diff --git a/.gitignore b/.gitignore index c6df47a..c78f88d 100644 --- a/.gitignore +++ b/.gitignore @@ -100,9 +100,17 @@ ENV/ # eclipse .project .pydevproject +# vscode + +.vscode + +schaingui/node_modules/ +schainpy/scripts/ .svn/ *.png *.pyc -schainpy/scripts .vscode -schaingui/node_modules \ No newline at end of file +trash +*.log +schainpy/scripts/testDigitalRF.py +schainpy/scripts/testDigitalRFWriter.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7c27fc1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM python:2.7-slim + +RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends \ + git \ + gcc \ + libpng-dev \ + libfreetype6-dev \ + libopenblas-dev \ + liblapack-dev \ + libatlas-base-dev \ + libssl-dev \ + libhdf5-dev \ + && git clone --branch v2.3 --depth 1 \ + http://jro-dev.igp.gob.pe/rhodecode/schain \ + && pip install numpy \ + && cd schain \ + && pip install . \ + && rm -rf * \ + && apt-get purge -y --auto-remove git gcc \ + && rm -rf /var/lib/apt/lists/* + +ENV BACKEND="Agg" + +VOLUME /data + +ENTRYPOINT ["schain"] diff --git a/README.md b/README.md index 5704c9f..a04a8a8 100644 --- a/README.md +++ b/README.md @@ -6,24 +6,47 @@ Signal Chain (SCh) is a radar data processing library developed using [Python](w ## Installation -Install system dependencies, clone the latest version from [git](http://jro-dev.igp.gob.pe/rhodecode/schain/) and install it as a normal python package. +Install system dependencies, clone the latest version from [here](http://jro-dev.igp.gob.pe/rhodecode/schain/) and install it as a normal python package. +### Linux based system ``` $ sudo apt-get install python-pip python-dev gfortran libpng-dev freetype* libblas-dev liblapack-dev libatlas-base-dev python-qt4 python-tk libssl-dev libhdf5-dev -$ sudo pip install numpy $ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/ $ cd schain $ sudo pip install ./ + ``` -**Its recommended to install schain in a virtual environment** +### MAC Os +``` +$ brew install python +$ brew install cartr/qt4/pyqt +$ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/ +$ cd schain +$ pip install ./ +``` +**It is recommended to install schain in a virtual environment** ``` -$ sudo pip install virtualenv -$ virtualenv /path/to/virtual --system-site-packages +$ virtualenv /path/to/virtual $ source /path/to/virtual/bin/activate (virtual) $ cd schain (virtual) $ pip install ./ +(virtual) $ bash link_PyQt4.sh +``` + +### Docker + +Download Dockerfile from the repository, and create a docker image + +``` +$ docker build -t schain . +``` + +You can run a container using an xml file or a schain script also you need to mount a volume for the data input and for the output files/plots +``` +$ docker run -it --rm --volume /path/to/host/data:/data schain xml /data/test.xml +$ docker run -it --rm --volume /path/to/host/data:/data --entrypoint=/bin/python schain /data/test.py ``` ## First Script diff --git a/link_PyQt4.sh b/link_PyQt4.sh new file mode 100755 index 0000000..bc9f852 --- /dev/null +++ b/link_PyQt4.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# This hook is run after a new virtualenv is activated. + +python_version=python$(python -c "import sys; print (str(sys.version_info[0])+'.'+str(sys.version_info[1]))") +var=( $(which -a $python_version) ) + +get_python_lib_cmd="from distutils.sysconfig import get_python_lib; print (get_python_lib())" +lib_virtualenv_path=$(python -c "$get_python_lib_cmd") +lib_system_path=$(${var[-1]} -c "$get_python_lib_cmd") +sip_path=$(ls $lib_system_path/sip*.so) + +echo "Linking Qt4..." +ln -s $lib_system_path/PyQt4 $lib_virtualenv_path/PyQt4 +echo "Linking SIP..." +ln -s $sip_path $lib_virtualenv_path/sip.so diff --git a/schainpy/CHANGELOG.md b/schainpy/CHANGELOG.md new file mode 100644 index 0000000..4f4d159 --- /dev/null +++ b/schainpy/CHANGELOG.md @@ -0,0 +1,112 @@ +## CHANGELOG: + +### 2.3 +* Added support for Madrigal formats (reading/writing). +* Added support for reading BLTR parameters (*.sswma). +* Added support for reading Julia format (*.dat). +* Added high order function `MPProject` for multiprocessing scripts. +* Added two new Processing Units `PublishData` and `ReceiverData` for receiving and sending dataOut through multiple ways (tcp, ipc, inproc). +* Added a new graphics Processing Unit `PlotterReceiver`. It is decoupled from normal processing sequence with support for data generated by multiprocessing scripts. +* Added support for sending realtime graphic to web server. +* GUI command `schain` is now `schainGUI`. +* Added a CLI tool named `schain`. + * Scripts templates can be now generated with `schain generate`. + * Now it is possible to search Processing Units and Operations with `schain search [module]` to get the right name and its allowed parameters. + * `schain xml` to run xml scripts. +* Added suggestions when parameters are poorly written. +* `Controller.start()` now runs in a different process than the process calling it. +* Added `schainpy.utils.log` for log standarization. +* Running script on online mode no longer ignores date and hour. Issue #1109. +* Added support for receving voltage data directly from JARS (tcp, ipc). +* Updated README for MAC OS GUI installation. +* Setup now installs numpy. + +### 2.2.6 +* Graphics generated by the GUI are now the same as generated by scripts. Issue #1074. +* Added support for C extensions. +* Function `hildebrand_sehkon` optimized with a C wrapper. +* Numpy version updated. +* Migration to GIT. + +### 2.2.5: +* splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI. +* nProfiles of USRP data (hdf5) is the number of profiles thera are in one second. +* jroPlotter works directly with data objects instead of dictionaries +* script "schain" was added to Signal Chain installer + +### 2.2.4.1: +* jroIO_usrp.py is update to read Sandra's data +* decimation in Spectra and RTI plots is always enabled. +* time* window option added to GUI + +### 2.2.4: +* jroproc_spectra_lags.py added to schainpy +* Bug fixed in schainGUI: ProcUnit was created with the same id in some cases. +* Bug fixed in jroHeaderIO: Header size validation. + +### 2.2.3.1: +* Filtering block by time has been added. +* Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked +properly but the next days did not. + +### 2.2.3: +* Bug fixed in GUI: Error getting(reading) Code value +* Bug fixed in GUI: Flip option always needs channelList field +* Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value +was modified for every branch (because this was a reference). It was modified in data.copy() +* Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList. + +### 2.2.2: +* VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested +* Rawdata and testRawdata.py added to Signal Chain project + +### 2.2.1: +* Bugs fixed in GUI +* Views were improved in GUI +* Support to MST* ISR experiments +* Bug fixed getting noise using hyldebrant. (minimum number of points > 20%) +* handleError added to jroplotter.py + +### 2.2.0: +* GUI: use of external plotter +* Compatible with matplotlib 1.5.0 + +### 2.1.5: +* serializer module added to Signal Chain +* jroplotter.py added to Signal Chain + +### 2.1.4.2: +* A new Plotter Class was added +* Project.start() does not accept filename as a parameter anymore + +### 2.1.4.1: +* Send notifications when an error different to ValueError is detected + +### 2.1.4: +* Sending error notifications to signal chain administrator +* Login to email server added + +### 2.1.3.3: +* Colored Button Icons were added to GUI + +### 2.1.3.2: +* GUI: user interaction enhanced +* controller_api.py: Safe access to ControllerThead + +### 2.1.3.1: +* GUI: every icon were resized +* jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file + +### 2.1.3: +* jroplot_heispectra.py: SpectraHeisScope was not showing the right channels +* jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value), + Bug fixed selecting heights by block (selecting profiles instead heights) +* jroproc_voltage.py: New feature added: decoding data by block using FFT. +* jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits. +* jroIO_heispectra.py: Channel index list does not exist. + +### 2.1.2: +* jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread + Server thread opens and closes remote server each time file list is sent +* jroplot_spectra.py: Noise path was not being created when noise data is saved. +* jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00] \ No newline at end of file diff --git a/schainpy/ROADMAP.md b/schainpy/ROADMAP.md new file mode 100644 index 0000000..80b3de6 --- /dev/null +++ b/schainpy/ROADMAP.md @@ -0,0 +1,10 @@ +ROADMAP FOR SCHAIN BRANCHES +=============================== + +### BRANCH - SCHAIN_MP +* Revisar si funciona con varios publishers. +* Revisar xRange y reinicialización de gráfico. +* Grabar cada spectra independientemente. +* Agregar kwargs al init +* Agregar gráficos restantes +* Presentación diff --git a/schainpy/VERSION b/schainpy/VERSION deleted file mode 100644 index a19b1a9..0000000 --- a/schainpy/VERSION +++ /dev/null @@ -1,85 +0,0 @@ -VERSIONS: - -2.1.2: --jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread - Server thread opens and closes remote server each time file list is sent --jroplot_spectra.py: Noise path was not being created when noise data is saved. --jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 - 07:00] - -2.1.3: --jroplot_heispectra.py: SpectraHeisScope was not showing the right channels --jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value), - Bug fixed selecting heights by block (selecting profiles instead heights) --jroproc_voltage.py: New feature added: decoding data by block using FFT. --jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits. --jroIO_heispectra.py: Channel index list does not exist. - -2.1.3.1: --GUI: every icon were resized --jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file - -2.1.3.2: --GUI: user interaction enhanced --controller_api.py: Safe access to ControllerThead - -2.1.3.3: --Colored Button Icons were added to GUI - -2.1.4: --Sending error notifications to signal chain administrator --Login to email server added - -2.1.4.1: --Send notifications when an error different to ValueError is detected - -2.1.4.2: --A new Plotter Class was added --Project.start() does not accept filename as a parameter anymore - -2.1.5: --serializer module added to Signal Chain --jroplotter.py added to Signal Chain - -2.2.0: --GUI: use of external plotter --Compatible with matplotlib 1.5.0 - -2.2.1: --Bugs fixed in GUI --Views were improved in GUI --Support to MST-ISR experiments --Bug fixed getting noise using hyldebrant. (minimum number of points > 20%) --handleError added to jroplotter.py - -2.2.2: --VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested --Rawdata and testRawdata.py added to Signal Chain project - -2.2.3: --Bug fixed in GUI: Error getting(reading) Code value --Bug fixed in GUI: Flip option always needs channelList field --Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value -was modified for every branch (because this was a reference). It was modified in data.copy() --Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList. - - -2.2.3.1: --Filtering block by time has been added. --Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked -properly but the next days did not. - -2.2.4: --jroproc_spectra_lags.py added to schainpy --Bug fixed in schainGUI: ProcUnit was created with the same id in some cases. --Bug fixed in jroHeaderIO: Header size validation. - -2.2.4.1: --jroIO_usrp.py is update to read Sandra's data --decimation in Spectra and RTI plots is always enabled. --time-window option added to GUI - -2.2.5: --splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI. --nProfiles of USRP data (hdf5) is the number of profiles thera are in one second. --jroPlotter works directly with data objects instead of dictionaries --script "schain" was added to Signal Chain installer \ No newline at end of file diff --git a/schainpy/__init__.py b/schainpy/__init__.py index fd40874..4654380 100644 --- a/schainpy/__init__.py +++ b/schainpy/__init__.py @@ -4,4 +4,4 @@ Created on Feb 7, 2012 @author $Author$ @version $Id$ ''' -__version__ = "2.2.6" \ No newline at end of file +__version__ = '2.3' diff --git a/schainpy/admin.py b/schainpy/admin.py index c22cf9e..ef2ed57 100644 --- a/schainpy/admin.py +++ b/schainpy/admin.py @@ -1,23 +1,123 @@ -"""The admin module contains all administrative classes relating to the schain python api. +""" +The admin module contains all administrative classes relating to the schain python api. The main role of this module is to send some reports. It contains a notification class and a standard error handing class. $Id: admin.py 3966 2015-12-01 14:32:29Z miguel.urco $ """ -import os, sys +import os +import sys +import time import traceback import smtplib import ConfigParser import StringIO - +from threading import Thread +from multiprocessing import Process from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart +import schainpy +from schainpy.utils import log +from schainpy.model.graphics.jroplot_data import popup + +def get_path(): + ''' + Return schainpy path + ''' + + try: + root = __file__ + if os.path.islink(root): + root = os.path.realpath(root) + + return os.path.dirname(os.path.abspath(root)) + except: + log.error('I am sorry, but something is wrong... __file__ not found') + +class Alarm(Process): + ''' + modes: + 0 - All + 1 - Send email + 2 - Popup message + 3 - Sound alarm + 4 - Send to alarm system TODO + ''' + + def __init__(self, modes=[], **kwargs): + Process.__init__(self) + self.modes = modes + self.kwargs = kwargs + + @staticmethod + def play_sound(): + sound = os.path.join(get_path(), 'alarm1.oga') + if os.path.exists(sound): + for __ in range(2): + os.system('paplay {}'.format(sound)) + time.sleep(0.5) + else: + log.warning('Unable to play alarm, sound file not found', 'ADMIN') + + @staticmethod + def send_email(**kwargs): + notifier = SchainNotify() + print kwargs + notifier.notify(**kwargs) + + @staticmethod + def show_popup(message): + if isinstance(message, list): + message = message[-1] + popup(message) + + @staticmethod + def send_alarm(): + pass + + @staticmethod + def get_kwargs(kwargs, keys): + ret = {} + for key in keys: + ret[key] = kwargs[key] + return ret + + def run(self): + tasks = { + 1 : self.send_email, + 2 : self.show_popup, + 3 : self.play_sound, + 4 : self.send_alarm, + } + + tasks_args = { + 1: ['email', 'message', 'subject', 'subtitle', 'filename'], + 2: ['message'], + 3: [], + 4: [], + } + procs = [] + for mode in self.modes: + if 0 in self.modes: + for x in tasks: + t = Thread(target=tasks[x], kwargs=self.get_kwargs(self.kwargs, tasks_args[x])) + t.start() + procs.append(t) + break + else: + t = Thread(target=tasks[mode], kwargs=self.get_kwargs(self.kwargs, tasks_args[mode])) + t.start() + procs.append(t) + for t in procs: + t.join() + + class SchainConfigure(): - __DEFAULT_ADMINISTRATOR_EMAIL = "" + __DEFAULT_ADMINISTRATOR_EMAIL = "juan.espinoza@jro.igp.gob.pe" __DEFAULT_EMAIL_SERVER = "jro-zimbra.igp.gob.pe" __DEFAULT_SENDER_EMAIL = "notifier-schain@jro.igp.gob.pe" __DEFAULT_SENDER_PASS = "" @@ -176,13 +276,15 @@ class SchainNotify: self.__emailServer = confObj.getEmailServer() def sendEmail(self, email_from, email_to, subject='Error running ...', message="", subtitle="", filename="", html_format=True): - + if not email_to: return 0 if not self.__emailServer: return 0 + log.success('Sending email to {}...'.format(email_to), 'System') + msg = MIMEMultipart() msg['Subject'] = subject msg['From'] = "(Python SChain API): " + email_from @@ -204,7 +306,7 @@ class SchainNotify: msg.attach(part) - if os.path.isfile(filename): + if filename and os.path.isfile(filename): # This is the binary part(The Attachment): part = MIMEApplication(open(filename,"rb").read()) part.add_header('Content-Disposition', @@ -216,11 +318,11 @@ class SchainNotify: try: smtp = smtplib.SMTP(self.__emailServer) except: - print "***** Could not connect to server %s *****" %self.__emailServer + log.error('Could not connect to server {}'.format(self.__emailServer), 'System') return 0 # Start the server: -# smtp.ehlo() + # smtp.ehlo() if self.__emailPass: smtp.login(self.__emailFromAddress, self.__emailPass) @@ -228,11 +330,13 @@ class SchainNotify: try: smtp.sendmail(msg['From'], msg['To'], msg.as_string()) except: - print "***** Could not send the email to %s *****" %msg['To'] + log.error('Could not send the email to {}'.format(msg['To']), 'System') smtp.quit() return 0 smtp.quit() + + log.success('Email sent ', 'System') return 1 @@ -264,8 +368,6 @@ class SchainNotify: if not sent: return 0 - print "***** Your system administrator has been notified *****" - return 1 def notify(self, email, message, subject = "", subtitle="", filename=""): @@ -280,16 +382,18 @@ class SchainNotify: Exceptions: None. """ - print "Notifying to %s ..." %email + if email is None: + email = self.__emailToAddress - self.sendEmail(email_from=self.__emailFromAddress, - email_to=email, - subject=subject, - message=message, - subtitle=subtitle, - filename=filename) - - print "***** Your system administrator has been notified *****" + self.sendEmail( + email_from=self.__emailFromAddress, + email_to=email, + subject=subject, + message=message, + subtitle=subtitle, + filename=filename + ) + class SchainError(Exception): """SchainError is an exception class that is thrown for all known errors using Schain Py lib. @@ -386,6 +490,10 @@ class SchainError(Exception): return excStr +class SchainWarning(Exception): + pass + + if __name__ == '__main__': test = SchainNotify() diff --git a/schainpy/alarm1.oga b/schainpy/alarm1.oga new file mode 100644 index 0000000000000000000000000000000000000000..a253702a5f65c375457b5d7fb08a4ec06476b9d0 GIT binary patch literal 73696 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 literal 0 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 1: + log.error('There is more than one file to run') + elif numberfiles == 1: + subprocess.call(['python ' + currentfiles[0]], shell=True) + else: + log.error('There is no file to run') + else: + try: + subprocess.call(['python ' + nextcommand], shell=True) + except Exception as e: + log.error("I cannot run the file. Does it exists?") + + +def basicInputs(): + inputs = {} + inputs['desc'] = click.prompt( + 'Enter a description', default="A schain project", type=str) + inputs['name'] = click.prompt( + 'Name of the project', default="project", type=str) + inputs['path'] = click.prompt('Data path', default=os.getcwd( + ), type=click.Path(exists=True, resolve_path=True)) + inputs['startDate'] = click.prompt( + 'Start date', default='1970/01/01', type=str) + inputs['endDate'] = click.prompt( + 'End date', default='2017/12/31', type=str) + inputs['startHour'] = click.prompt( + 'Start hour', default='00:00:00', type=str) + inputs['endHour'] = click.prompt('End hour', default='23:59:59', type=str) + inputs['figpath'] = inputs['path'] + '/figs' + return inputs + + +def generate(): + inputs = basicInputs() + inputs['multiprocess'] = click.confirm('Is this a multiprocess script?') + if inputs['multiprocess']: + inputs['nProcess'] = click.prompt( + 'How many process?', default=cpu_count(), type=int) + current = templates.multiprocess.format(**inputs) + else: + current = templates.basic.format(**inputs) + scriptname = '{}_{}.py'.format(PREFIX, inputs['name']) + script = open(scriptname, 'w') + try: + script.write(current) + log.success('Script {} generated'.format(scriptname)) + except Exception as e: + log.error('I cannot create the file. Do you have writing permissions?') + + +def test(): + log.warning('testing') + + +def runFromXML(filename): + controller = Project() + if not controller.readXml(filename): + return + controller.start() + return diff --git a/schainpy/cli/templates.py b/schainpy/cli/templates.py new file mode 100644 index 0000000..29ad580 --- /dev/null +++ b/schainpy/cli/templates.py @@ -0,0 +1,90 @@ +basic = '''from schainpy.controller import Project + +desc = "{desc}" +project = Project() +project.setup(id='200', name="{name}", description=desc) + +voltage_reader = project.addReadUnit(datatype='VoltageReader', + path="{path}", + startDate="{startDate}", + endDate="{endDate}", + startTime="{startHour}", + endTime="{endHour}", + online=0, + verbose=1, + walk=1, + ) + +voltage_proc = project.addProcUnit(datatype='VoltageProc', inputId=voltage_reader.getId()) + +profile = voltage_proc.addOperation(name='ProfileSelector', optype='other') +profile.addParameter(name='profileRangeList', value='120,183', format='intlist') + +rti = voltage_proc.addOperation(name='RTIPlot', optype='other') +rti.addParameter(name='wintitle', value='Jicamarca Radio Observatory', format='str') +rti.addParameter(name='showprofile', value='0', format='int') +rti.addParameter(name='xmin', value='0', format='int') +rti.addParameter(name='xmax', value='24', format='int') +rti.addParameter(name='figpath', value="{figpath}", format='str') +rti.addParameter(name='wr_period', value='5', format='int') +rti.addParameter(name='exp_code', value='22', format='int') + + +project.start() +''' + +multiprocess = '''from schainpy.controller import Project, MPProject +from time import sleep +desc = "{desc}" + +#################### +# PLOTTER RECEIVER # +#################### +plotter = Project() +plotter.setup(id='100', name='receiver', description=desc) + +receiver_plot = plotter.addProcUnit(name='PlotterReceiver') +receiver_plot.addParameter(name='throttle', value=20, format='int') +receiver_plot.addParameter(name='plottypes', value='rti', format='str') + +rti = receiver_plot.addOperation(name='PlotRTIData', optype='other') +rti.addParameter(name='zmin', value='-40.0', format='float') +rti.addParameter(name='zmax', value='100.0', format='float') +rti.addParameter(name='decimation', value='200', format='int') +rti.addParameter(name='xmin', value='0.0', format='int') +rti.addParameter(name='colormap', value='jet', format='str') + +plotter.start() + +sleep(2) + +################ +# DATA EMITTER # +################ +project = Project() +project.setup(id='200', name="{name}", description=desc) + +spectra_reader = project.addReadUnit(datatype='SpectraReader', + path="{path}", + startDate={startDate}, + endDate={endDate}, + startTime="{startHour}", + endTime="{endHour}", + online=0, + verbose=1, + walk=1, + ) + +spectra_proc = project.addProcUnit(datatype='Spectra', inputId=spectra_reader.getId()) + +parameters_proc = project.addProcUnit(datatype='ParametersProc', inputId=spectra_proc.getId()) +moments = parameters_proc.addOperation(name='SpectralMoments', optype='other') + +publish = parameters_proc.addOperation(name='PublishData', optype='other') +publish.addParameter(name='zeromq', value=1, format='int') +publish.addParameter(name='verbose', value=0, format='bool') + +MPProject(project, 16) + + +''' diff --git a/schainpy/cli/tests/__init__.py b/schainpy/cli/tests/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/schainpy/cli/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/schainpy/cli/tests/test_cli.py b/schainpy/cli/tests/test_cli.py new file mode 100644 index 0000000..7af3a6f --- /dev/null +++ b/schainpy/cli/tests/test_cli.py @@ -0,0 +1,29 @@ +import pytest +from click.testing import CliRunner +from schainpy.cli import cli + + +@pytest.fixture +def runner(): + return CliRunner() + + +def test_cli(runner): + result = runner.invoke(cli.main) + assert result.exit_code == 0 + assert not result.exception + assert result.output.strip() == 'Hello, world.' + + +def test_cli_with_option(runner): + result = runner.invoke(cli.main, ['--as-cowboy']) + assert not result.exception + assert result.exit_code == 0 + assert result.output.strip() == 'Howdy, world.' + + +def test_cli_with_arg(runner): + result = runner.invoke(cli.main, ['Jicamarca']) + assert result.exit_code == 0 + assert not result.exception + assert result.output.strip() == 'Hello, Jicamarca.' diff --git a/schainpy/controller.py b/schainpy/controller.py index e400096..ce97a95 100644 --- a/schainpy/controller.py +++ b/schainpy/controller.py @@ -1,1294 +1,1342 @@ ''' Created on September , 2012 -@author: +@author: ''' - + import sys import ast import datetime import traceback -import schainpy -import schainpy.admin +import math +import time +from multiprocessing import Process, cpu_count from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring from xml.dom import minidom +import schainpy +from schainpy.admin import Alarm, SchainWarning from schainpy.model import * -from time import sleep +from schainpy.utils import log + +DTYPES = { + 'Voltage': '.r', + 'Spectra': '.pdata' +} + + +def MPProject(project, n=cpu_count()): + ''' + Project wrapper to run schain in n processes + ''' + + rconf = project.getReadUnitObj() + op = rconf.getOperationObj('run') + dt1 = op.getParameterValue('startDate') + dt2 = op.getParameterValue('endDate') + tm1 = op.getParameterValue('startTime') + tm2 = op.getParameterValue('endTime') + days = (dt2 - dt1).days + + for day in range(days + 1): + skip = 0 + cursor = 0 + processes = [] + dt = dt1 + datetime.timedelta(day) + dt_str = dt.strftime('%Y/%m/%d') + reader = JRODataReader() + paths, files = reader.searchFilesOffLine(path=rconf.path, + startDate=dt, + endDate=dt, + startTime=tm1, + endTime=tm2, + ext=DTYPES[rconf.datatype]) + nFiles = len(files) + if nFiles == 0: + continue + skip = int(math.ceil(nFiles / n)) + while nFiles > cursor * skip: + rconf.update(startDate=dt_str, endDate=dt_str, cursor=cursor, + skip=skip) + p = project.clone() + p.start() + processes.append(p) + cursor += 1 + + def beforeExit(exctype, value, trace): + for process in processes: + process.terminate() + process.join() + print traceback.print_tb(trace) + + sys.excepthook = beforeExit + + for process in processes: + process.join() + process.terminate() + + time.sleep(3) -def prettify(elem): - """Return a pretty-printed XML string for the Element. - """ - rough_string = tostring(elem, 'utf-8') - reparsed = minidom.parseString(rough_string) - return reparsed.toprettyxml(indent=" ") class ParameterConf(): - + id = None name = None value = None format = None - + __formated_value = None - + ELEMENTNAME = 'Parameter' - + def __init__(self): - + self.format = 'str' - + def getElementName(self): - + return self.ELEMENTNAME - + def getValue(self): value = self.value format = self.format - + if self.__formated_value != None: - + return self.__formated_value - + + if format == 'obj': + return value + if format == 'str': self.__formated_value = str(value) return self.__formated_value - + if value == '': - raise ValueError, "%s: This parameter value is empty" %self.name - + raise ValueError, '%s: This parameter value is empty' % self.name + if format == 'list': strList = value.split(',') - + self.__formated_value = strList - + return self.__formated_value - + if format == 'intlist': - """ + ''' Example: value = (0,1,2) - """ - + ''' + new_value = ast.literal_eval(value) - + if type(new_value) not in (tuple, list): new_value = [int(new_value)] - + self.__formated_value = new_value - + return self.__formated_value - + if format == 'floatlist': - """ + ''' Example: value = (0.5, 1.4, 2.7) - """ - + ''' + new_value = ast.literal_eval(value) - + if type(new_value) not in (tuple, list): new_value = [float(new_value)] - + self.__formated_value = new_value - + return self.__formated_value - + if format == 'date': strList = value.split('/') intList = [int(x) for x in strList] date = datetime.date(intList[0], intList[1], intList[2]) - + self.__formated_value = date - + return self.__formated_value - + if format == 'time': strList = value.split(':') intList = [int(x) for x in strList] time = datetime.time(intList[0], intList[1], intList[2]) - + self.__formated_value = time - + return self.__formated_value - + if format == 'pairslist': - """ + ''' Example: value = (0,1),(1,2) - """ + ''' new_value = ast.literal_eval(value) - + if type(new_value) not in (tuple, list): - raise ValueError, "%s has to be a tuple or list of pairs" %value - + raise ValueError, '%s has to be a tuple or list of pairs' % value + if type(new_value[0]) not in (tuple, list): if len(new_value) != 2: - raise ValueError, "%s has to be a tuple or list of pairs" %value + raise ValueError, '%s has to be a tuple or list of pairs' % value new_value = [new_value] - + for thisPair in new_value: if len(thisPair) != 2: - raise ValueError, "%s has to be a tuple or list of pairs" %value - + raise ValueError, '%s has to be a tuple or list of pairs' % value + self.__formated_value = new_value - + return self.__formated_value - + if format == 'multilist': - """ + ''' Example: value = (0,1,2),(3,4,5) - """ + ''' multiList = ast.literal_eval(value) - + if type(multiList[0]) == int: - multiList = ast.literal_eval("(" + value + ")") - + multiList = ast.literal_eval('(' + value + ')') + self.__formated_value = multiList - + return self.__formated_value - + if format == 'bool': value = int(value) - + if format == 'int': value = float(value) - + format_func = eval(format) - + self.__formated_value = format_func(value) - + return self.__formated_value def updateId(self, new_id): - + self.id = str(new_id) - + def setup(self, id, name, value, format='str'): - self.id = str(id) self.name = name - self.value = str(value) + if format == 'obj': + self.value = value + else: + self.value = str(value) self.format = str.lower(format) - + self.getValue() - + return 1 - + def update(self, name, value, format='str'): - + self.name = name self.value = str(value) self.format = format - + def makeXml(self, opElement): - - parmElement = SubElement(opElement, self.ELEMENTNAME) - parmElement.set('id', str(self.id)) - parmElement.set('name', self.name) - parmElement.set('value', self.value) - parmElement.set('format', self.format) - + if self.name not in ('queue',): + parmElement = SubElement(opElement, self.ELEMENTNAME) + parmElement.set('id', str(self.id)) + parmElement.set('name', self.name) + parmElement.set('value', self.value) + parmElement.set('format', self.format) + def readXml(self, parmElement): - + self.id = parmElement.get('id') self.name = parmElement.get('name') self.value = parmElement.get('value') self.format = str.lower(parmElement.get('format')) - - #Compatible with old signal chain version + + # Compatible with old signal chain version if self.format == 'int' and self.name == 'idfigure': self.name = 'id' - + def printattr(self): - - print "Parameter[%s]: name = %s, value = %s, format = %s" %(self.id, self.name, self.value, self.format) + + print 'Parameter[%s]: name = %s, value = %s, format = %s' % (self.id, self.name, self.value, self.format) + class OperationConf(): - + id = None name = None priority = None type = None - + parmConfObjList = [] - + ELEMENTNAME = 'Operation' - + def __init__(self): - + self.id = '0' self.name = None self.priority = None self.type = 'self' - - + def __getNewId(self): - - return int(self.id)*10 + len(self.parmConfObjList) + 1 + + return int(self.id) * 10 + len(self.parmConfObjList) + 1 def updateId(self, new_id): - + self.id = str(new_id) - + n = 1 for parmObj in self.parmConfObjList: - - idParm = str(int(new_id)*10 + n) + + idParm = str(int(new_id) * 10 + n) parmObj.updateId(idParm) - + n += 1 - + def getElementName(self): - + return self.ELEMENTNAME - + def getParameterObjList(self): - + return self.parmConfObjList - + def getParameterObj(self, parameterName): - + for parmConfObj in self.parmConfObjList: - + if parmConfObj.name != parameterName: continue - + return parmConfObj - + return None def getParameterObjfromValue(self, parameterValue): - + for parmConfObj in self.parmConfObjList: - + if parmConfObj.getValue() != parameterValue: continue - + return parmConfObj.getValue() - + return None - + def getParameterValue(self, parameterName): - + parameterObj = self.getParameterObj(parameterName) - + # if not parameterObj: # return None - + value = parameterObj.getValue() - + return value - + + def getKwargs(self): + + kwargs = {} + + for parmConfObj in self.parmConfObjList: + if self.name == 'run' and parmConfObj.name == 'datatype': + continue + + kwargs[parmConfObj.name] = parmConfObj.getValue() + + return kwargs + def setup(self, id, name, priority, type): - + self.id = str(id) self.name = name self.type = type self.priority = priority - + self.parmConfObjList = [] - + def removeParameters(self): - + for obj in self.parmConfObjList: del obj - + self.parmConfObjList = [] - + def addParameter(self, name, value, format='str'): - + + if value is None: + return None id = self.__getNewId() - + parmConfObj = ParameterConf() if not parmConfObj.setup(id, name, value, format): return None - + self.parmConfObjList.append(parmConfObj) - + return parmConfObj - + def changeParameter(self, name, value, format='str'): - + parmConfObj = self.getParameterObj(name) parmConfObj.update(name, value, format) - + return parmConfObj - + def makeXml(self, procUnitElement): - + opElement = SubElement(procUnitElement, self.ELEMENTNAME) opElement.set('id', str(self.id)) opElement.set('name', self.name) opElement.set('type', self.type) opElement.set('priority', str(self.priority)) - + for parmConfObj in self.parmConfObjList: parmConfObj.makeXml(opElement) - + def readXml(self, opElement): - + self.id = opElement.get('id') self.name = opElement.get('name') self.type = opElement.get('type') self.priority = opElement.get('priority') - - #Compatible with old signal chain version - #Use of 'run' method instead 'init' + + # Compatible with old signal chain version + # Use of 'run' method instead 'init' if self.type == 'self' and self.name == 'init': self.name = 'run' - + self.parmConfObjList = [] - + parmElementList = opElement.iter(ParameterConf().getElementName()) - + for parmElement in parmElementList: parmConfObj = ParameterConf() parmConfObj.readXml(parmElement) - - #Compatible with old signal chain version - #If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER + + # Compatible with old signal chain version + # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER if self.type != 'self' and self.name == 'Plot': if parmConfObj.format == 'str' and parmConfObj.name == 'type': self.name = parmConfObj.value continue - + self.parmConfObjList.append(parmConfObj) - + def printattr(self): - - print "%s[%s]: name = %s, type = %s, priority = %s" %(self.ELEMENTNAME, - self.id, - self.name, - self.type, - self.priority) - + + print '%s[%s]: name = %s, type = %s, priority = %s' % (self.ELEMENTNAME, + self.id, + self.name, + self.type, + self.priority) + for parmConfObj in self.parmConfObjList: parmConfObj.printattr() - + def createObject(self, plotter_queue=None): - + if self.type == 'self': - raise ValueError, "This operation type cannot be created" - + raise ValueError, 'This operation type cannot be created' + if self.type == 'plotter': - #Plotter(plotter_name) if not plotter_queue: - raise ValueError, "plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)" - + raise ValueError, 'plotter_queue is not defined. Use:\nmyProject = Project()\nmyProject.setPlotterQueue(plotter_queue)' + opObj = Plotter(self.name, plotter_queue) - + if self.type == 'external' or self.type == 'other': + className = eval(self.name) - opObj = className() - + kwargs = self.getKwargs() + + opObj = className(**kwargs) + return opObj - + + class ProcUnitConf(): - + id = None name = None datatype = None inputId = None parentId = None - + opConfObjList = [] - + procUnitObj = None opObjList = [] - + ELEMENTNAME = 'ProcUnit' - + def __init__(self): - + self.id = None self.datatype = None self.name = None self.inputId = None - + self.opConfObjList = [] - + self.procUnitObj = None self.opObjDict = {} - + def __getPriority(self): - - return len(self.opConfObjList)+1 - + + return len(self.opConfObjList) + 1 + def __getNewId(self): - - return int(self.id)*10 + len(self.opConfObjList) + 1 - + + return int(self.id) * 10 + len(self.opConfObjList) + 1 + def getElementName(self): - + return self.ELEMENTNAME - + def getId(self): - + return self.id def updateId(self, new_id, parentId=parentId): - - - new_id = int(parentId)*10 + (int(self.id) % 10) - new_inputId = int(parentId)*10 + (int(self.inputId) % 10) - - #If this proc unit has not inputs + + new_id = int(parentId) * 10 + (int(self.id) % 10) + new_inputId = int(parentId) * 10 + (int(self.inputId) % 10) + + # If this proc unit has not inputs if self.inputId == '0': new_inputId = 0 - + n = 1 for opConfObj in self.opConfObjList: - - idOp = str(int(new_id)*10 + n) + + idOp = str(int(new_id) * 10 + n) opConfObj.updateId(idOp) - + n += 1 - + self.parentId = str(parentId) self.id = str(new_id) self.inputId = str(new_inputId) - - + def getInputId(self): - + return self.inputId - + def getOperationObjList(self): - + return self.opConfObjList - + def getOperationObj(self, name=None): - + for opConfObj in self.opConfObjList: - + if opConfObj.name != name: continue - + return opConfObj - + return None - + def getOpObjfromParamValue(self, value=None): - + for opConfObj in self.opConfObjList: if opConfObj.getParameterObjfromValue(parameterValue=value) != value: continue return opConfObj return None - + def getProcUnitObj(self): - + return self.procUnitObj - + def setup(self, id, name, datatype, inputId, parentId=None): - - #Compatible with old signal chain version - if datatype==None and name==None: - raise ValueError, "datatype or name should be defined" - - if name==None: + + # Compatible with old signal chain version + if datatype == None and name == None: + raise ValueError, 'datatype or name should be defined' + + if name == None: if 'Proc' in datatype: name = datatype else: - name = '%sProc' %(datatype) - - if datatype==None: - datatype = name.replace('Proc','') - + name = '%sProc' % (datatype) + + if datatype == None: + datatype = name.replace('Proc', '') + self.id = str(id) self.name = name self.datatype = datatype self.inputId = inputId self.parentId = parentId - + self.opConfObjList = [] - + self.addOperation(name='run', optype='self') - + def removeOperations(self): - + for obj in self.opConfObjList: del obj - + self.opConfObjList = [] self.addOperation(name='run') - + def addParameter(self, **kwargs): ''' - Add parameters to "run" operation + Add parameters to 'run' operation ''' opObj = self.opConfObjList[0] - + opObj.addParameter(**kwargs) - + return opObj - + def addOperation(self, name, optype='self'): - + id = self.__getNewId() - priority = self.__getPriority() - + priority = self.__getPriority() + opConfObj = OperationConf() opConfObj.setup(id, name=name, priority=priority, type=optype) - + self.opConfObjList.append(opConfObj) - + return opConfObj - + def makeXml(self, projectElement): - + procUnitElement = SubElement(projectElement, self.ELEMENTNAME) procUnitElement.set('id', str(self.id)) procUnitElement.set('name', self.name) procUnitElement.set('datatype', self.datatype) procUnitElement.set('inputId', str(self.inputId)) - + for opConfObj in self.opConfObjList: opConfObj.makeXml(procUnitElement) - + def readXml(self, upElement): - + self.id = upElement.get('id') self.name = upElement.get('name') self.datatype = upElement.get('datatype') self.inputId = upElement.get('inputId') - - if self.ELEMENTNAME == "ReadUnit": - self.datatype = self.datatype.replace("Reader", "") - - if self.ELEMENTNAME == "ProcUnit": - self.datatype = self.datatype.replace("Proc", "") - + + if self.ELEMENTNAME == 'ReadUnit': + self.datatype = self.datatype.replace('Reader', '') + + if self.ELEMENTNAME == 'ProcUnit': + self.datatype = self.datatype.replace('Proc', '') + if self.inputId == 'None': self.inputId = '0' - + self.opConfObjList = [] - + opElementList = upElement.iter(OperationConf().getElementName()) - + for opElement in opElementList: opConfObj = OperationConf() opConfObj.readXml(opElement) self.opConfObjList.append(opConfObj) - + def printattr(self): - - print "%s[%s]: name = %s, datatype = %s, inputId = %s" %(self.ELEMENTNAME, - self.id, - self.name, - self.datatype, - self.inputId) - + + print '%s[%s]: name = %s, datatype = %s, inputId = %s' % (self.ELEMENTNAME, + self.id, + self.name, + self.datatype, + self.inputId) + for opConfObj in self.opConfObjList: opConfObj.printattr() - + + def getKwargs(self): + + opObj = self.opConfObjList[0] + kwargs = opObj.getKwargs() + + return kwargs + def createObjects(self, plotter_queue=None): - + className = eval(self.name) - procUnitObj = className() - + kwargs = self.getKwargs() + procUnitObj = className(**kwargs) + for opConfObj in self.opConfObjList: - - if opConfObj.type == 'self': + + if opConfObj.type == 'self' and self.name == 'run': + continue + elif opConfObj.type == 'self': + procUnitObj.addOperationKwargs( + opConfObj.id, **opConfObj.getKwargs()) continue - + opObj = opConfObj.createObject(plotter_queue) - + self.opObjDict[opConfObj.id] = opObj + procUnitObj.addOperation(opObj, opConfObj.id) - + self.procUnitObj = procUnitObj - + return procUnitObj - + def run(self): - + is_ok = False - + for opConfObj in self.opConfObjList: - + kwargs = {} for parmConfObj in opConfObj.getParameterObjList(): if opConfObj.name == 'run' and parmConfObj.name == 'datatype': continue - + kwargs[parmConfObj.name] = parmConfObj.getValue() - - #ini = time.time() - - #print "\tRunning the '%s' operation with %s" %(opConfObj.name, opConfObj.id) - sts = self.procUnitObj.call(opType = opConfObj.type, - opName = opConfObj.name, - opId = opConfObj.id, - **kwargs) - - # total_time = time.time() - ini - # - # if total_time > 0.002: - # print "%s::%s took %f seconds" %(self.name, opConfObj.name, total_time) - + + sts = self.procUnitObj.call(opType=opConfObj.type, + opName=opConfObj.name, + opId=opConfObj.id) + is_ok = is_ok or sts - + return is_ok def close(self): - + for opConfObj in self.opConfObjList: if opConfObj.type == 'self': continue - + opObj = self.procUnitObj.getOperationObj(opConfObj.id) opObj.close() - + self.procUnitObj.close() - + return + class ReadUnitConf(ProcUnitConf): - + path = None startDate = None endDate = None startTime = None endTime = None - + ELEMENTNAME = 'ReadUnit' - + def __init__(self): - + self.id = None self.datatype = None self.name = None self.inputId = None - + self.parentId = None - + self.opConfObjList = [] self.opObjList = [] - + def getElementName(self): - + return self.ELEMENTNAME - - def setup(self, id, name, datatype, path, startDate="", endDate="", startTime="", endTime="", parentId=None, **kwargs): - #Compatible with old signal chain version - if datatype==None and name==None: - raise ValueError, "datatype or name should be defined" - - if name==None: + def setup(self, id, name, datatype, path='', startDate='', endDate='', + startTime='', endTime='', parentId=None, server=None, **kwargs): + + # Compatible with old signal chain version + if datatype == None and name == None: + raise ValueError, 'datatype or name should be defined' + if name == None: if 'Reader' in datatype: name = datatype + datatype = name.replace('Reader','') else: - name = '%sReader' %(datatype) - - if datatype==None: - datatype = name.replace('Reader','') - + name = '{}Reader'.format(datatype) + if datatype == None: + if 'Reader' in name: + datatype = name.replace('Reader','') + else: + datatype = name + name = '{}Reader'.format(name) + self.id = id self.name = name self.datatype = datatype - - self.path = os.path.abspath(path) + if path != '': + self.path = os.path.abspath(path) self.startDate = startDate self.endDate = endDate self.startTime = startTime self.endTime = endTime - self.inputId = '0' self.parentId = parentId - + self.server = server self.addRunOperation(**kwargs) - - def update(self, datatype, path, startDate, endDate, startTime, endTime, parentId=None, name=None, **kwargs): - #Compatible with old signal chain version - if datatype==None and name==None: - raise ValueError, "datatype or name should be defined" - - if name==None: + def update(self, **kwargs): + + if 'datatype' in kwargs: + datatype = kwargs.pop('datatype') if 'Reader' in datatype: - name = datatype + self.name = datatype else: - name = '%sReader' %(datatype) - - if datatype==None: - datatype = name.replace('Reader','') - - self.datatype = datatype - self.name = name - self.path = path - self.startDate = startDate - self.endDate = endDate - self.startTime = startTime - self.endTime = endTime - + self.name = '%sReader' % (datatype) + self.datatype = self.name.replace('Reader', '') + + attrs = ('path', 'startDate', 'endDate', + 'startTime', 'endTime', 'parentId') + + for attr in attrs: + if attr in kwargs: + setattr(self, attr, kwargs.pop(attr)) + self.inputId = '0' - self.parentId = parentId - self.updateRunOperation(**kwargs) - + def removeOperations(self): - + for obj in self.opConfObjList: del obj - + self.opConfObjList = [] - + def addRunOperation(self, **kwargs): - - opObj = self.addOperation(name = 'run', optype = 'self') - - opObj.addParameter(name='datatype' , value=self.datatype, format='str') - opObj.addParameter(name='path' , value=self.path, format='str') - opObj.addParameter(name='startDate' , value=self.startDate, format='date') - opObj.addParameter(name='endDate' , value=self.endDate, format='date') - opObj.addParameter(name='startTime' , value=self.startTime, format='time') - opObj.addParameter(name='endTime' , value=self.endTime, format='time') - - for key, value in kwargs.items(): - opObj.addParameter(name=key, value=value, format=type(value).__name__) - + + opObj = self.addOperation(name='run', optype='self') + + if self.server is None: + opObj.addParameter( + name='datatype', value=self.datatype, format='str') + opObj.addParameter(name='path', value=self.path, format='str') + opObj.addParameter( + name='startDate', value=self.startDate, format='date') + opObj.addParameter( + name='endDate', value=self.endDate, format='date') + opObj.addParameter( + name='startTime', value=self.startTime, format='time') + opObj.addParameter( + name='endTime', value=self.endTime, format='time') + + for key, value in kwargs.items(): + opObj.addParameter(name=key, value=value, + format=type(value).__name__) + else: + opObj.addParameter(name='server', value=self.server, format='str') + return opObj - + def updateRunOperation(self, **kwargs): - - opObj = self.getOperationObj(name = 'run') + + opObj = self.getOperationObj(name='run') opObj.removeParameters() - - opObj.addParameter(name='datatype' , value=self.datatype, format='str') - opObj.addParameter(name='path' , value=self.path, format='str') - opObj.addParameter(name='startDate' , value=self.startDate, format='date') - opObj.addParameter(name='endDate' , value=self.endDate, format='date') - opObj.addParameter(name='startTime' , value=self.startTime, format='time') - opObj.addParameter(name='endTime' , value=self.endTime, format='time') - + + opObj.addParameter(name='datatype', value=self.datatype, format='str') + opObj.addParameter(name='path', value=self.path, format='str') + opObj.addParameter( + name='startDate', value=self.startDate, format='date') + opObj.addParameter(name='endDate', value=self.endDate, format='date') + opObj.addParameter( + name='startTime', value=self.startTime, format='time') + opObj.addParameter(name='endTime', value=self.endTime, format='time') + for key, value in kwargs.items(): - opObj.addParameter(name=key, value=value, format=type(value).__name__) - + opObj.addParameter(name=key, value=value, + format=type(value).__name__) + return opObj - - # def makeXml(self, projectElement): - # - # procUnitElement = SubElement(projectElement, self.ELEMENTNAME) - # procUnitElement.set('id', str(self.id)) - # procUnitElement.set('name', self.name) - # procUnitElement.set('datatype', self.datatype) - # procUnitElement.set('inputId', str(self.inputId)) - # - # for opConfObj in self.opConfObjList: - # opConfObj.makeXml(procUnitElement) - + def readXml(self, upElement): - + self.id = upElement.get('id') self.name = upElement.get('name') self.datatype = upElement.get('datatype') self.inputId = upElement.get('inputId') - - if self.ELEMENTNAME == "ReadUnit": - self.datatype = self.datatype.replace("Reader", "") - + + if self.ELEMENTNAME == 'ReadUnit': + self.datatype = self.datatype.replace('Reader', '') + if self.inputId == 'None': self.inputId = '0' - + self.opConfObjList = [] - + opElementList = upElement.iter(OperationConf().getElementName()) - + for opElement in opElementList: opConfObj = OperationConf() opConfObj.readXml(opElement) self.opConfObjList.append(opConfObj) - + if opConfObj.name == 'run': self.path = opConfObj.getParameterValue('path') self.startDate = opConfObj.getParameterValue('startDate') self.endDate = opConfObj.getParameterValue('endDate') self.startTime = opConfObj.getParameterValue('startTime') self.endTime = opConfObj.getParameterValue('endTime') - -class Project(): - + + +class Project(Process): + id = None - name = None + # name = None description = None filename = None - + procUnitConfObjDict = None - + ELEMENTNAME = 'Project' - + plotterQueue = None - + def __init__(self, plotter_queue=None): - - self.id = None - self.name = None + + Process.__init__(self) + self.id = None self.description = None - + self.email = None + self.alarm = None self.plotterQueue = plotter_queue - self.procUnitConfObjDict = {} - + def __getNewId(self): - + idList = self.procUnitConfObjDict.keys() - - id = int(self.id)*10 - + + id = int(self.id) * 10 + while True: id += 1 - + if str(id) in idList: continue - + break - + return str(id) - + def getElementName(self): - + return self.ELEMENTNAME def getId(self): - + return self.id - + def updateId(self, new_id): - + self.id = str(new_id) - + keyList = self.procUnitConfObjDict.keys() keyList.sort() - + n = 1 newProcUnitConfObjDict = {} - + for procKey in keyList: - + procUnitConfObj = self.procUnitConfObjDict[procKey] - idProcUnit = str(int(self.id)*10 + n) - procUnitConfObj.updateId(idProcUnit, parentId = self.id) - + idProcUnit = str(int(self.id) * 10 + n) + procUnitConfObj.updateId(idProcUnit, parentId=self.id) newProcUnitConfObjDict[idProcUnit] = procUnitConfObj n += 1 - + self.procUnitConfObjDict = newProcUnitConfObjDict - - def setup(self, id, name, description): - + + def setup(self, id, name='', description='', email=None, alarm=[]): + + print + print '*' * 60 + print ' Starting SIGNAL CHAIN PROCESSING v%s ' % schainpy.__version__ + print '*' * 60 + print self.id = str(id) - self.name = name self.description = description + self.email = email + self.alarm = alarm + + def update(self, **kwargs): + + for key, value in kwargs.items(): + setattr(self, key, value) + + def clone(self): + + p = Project() + p.procUnitConfObjDict = self.procUnitConfObjDict + return p - def update(self, name, description): - - self.name = name - self.description = description - def addReadUnit(self, id=None, datatype=None, name=None, **kwargs): - + if id is None: idReadUnit = self.__getNewId() else: idReadUnit = str(id) - + readUnitConfObj = ReadUnitConf() - readUnitConfObj.setup(idReadUnit, name, datatype, parentId=self.id, **kwargs) - + readUnitConfObj.setup(idReadUnit, name, datatype, + parentId=self.id, **kwargs) + self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj - + return readUnitConfObj - + def addProcUnit(self, inputId='0', datatype=None, name=None): - + idProcUnit = self.__getNewId() - + procUnitConfObj = ProcUnitConf() - procUnitConfObj.setup(idProcUnit, name, datatype, inputId, parentId=self.id) - + procUnitConfObj.setup(idProcUnit, name, datatype, + inputId, parentId=self.id) + self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj - + return procUnitConfObj - + def removeProcUnit(self, id): - + if id in self.procUnitConfObjDict.keys(): self.procUnitConfObjDict.pop(id) - + def getReadUnitId(self): - + readUnitConfObj = self.getReadUnitObj() - + return readUnitConfObj.id - + def getReadUnitObj(self): - + for obj in self.procUnitConfObjDict.values(): - if obj.getElementName() == "ReadUnit": + if obj.getElementName() == 'ReadUnit': return obj - + return None - + def getProcUnitObj(self, id=None, name=None): - + if id != None: return self.procUnitConfObjDict[id] - + if name != None: return self.getProcUnitObjByName(name) - + return None - + def getProcUnitObjByName(self, name): - + for obj in self.procUnitConfObjDict.values(): if obj.name == name: return obj - + return None - + def procUnitItems(self): - + return self.procUnitConfObjDict.items() - - def makeXml(self): - + + def makeXml(self): + projectElement = Element('Project') projectElement.set('id', str(self.id)) projectElement.set('name', self.name) projectElement.set('description', self.description) - + for procUnitConfObj in self.procUnitConfObjDict.values(): procUnitConfObj.makeXml(projectElement) - + self.projectElement = projectElement - + def writeXml(self, filename=None): - + if filename == None: if self.filename: filename = self.filename else: - filename = "schain.xml" - + filename = 'schain.xml' + if not filename: - print "filename has not been defined. Use setFilename(filename) for do it." + print 'filename has not been defined. Use setFilename(filename) for do it.' return 0 - + abs_file = os.path.abspath(filename) - + if not os.access(os.path.dirname(abs_file), os.W_OK): - print "No write permission on %s" %os.path.dirname(abs_file) + print 'No write permission on %s' % os.path.dirname(abs_file) return 0 - + if os.path.isfile(abs_file) and not(os.access(abs_file, os.W_OK)): - print "File %s already exists and it could not be overwriten" %abs_file + print 'File %s already exists and it could not be overwriten' % abs_file return 0 - + self.makeXml() - + ElementTree(self.projectElement).write(abs_file, method='xml') - + self.filename = abs_file - + return 1 - def readXml(self, filename = None): - + def readXml(self, filename=None): + if not filename: - print "filename is not defined" + print 'filename is not defined' return 0 - + abs_file = os.path.abspath(filename) - + if not os.path.isfile(abs_file): - print "%s file does not exist" %abs_file + print '%s file does not exist' % abs_file return 0 - + self.projectElement = None self.procUnitConfObjDict = {} - + try: self.projectElement = ElementTree().parse(abs_file) except: - print "Error reading %s, verify file format" %filename + print 'Error reading %s, verify file format' % filename return 0 - + self.project = self.projectElement.tag - + self.id = self.projectElement.get('id') self.name = self.projectElement.get('name') - self.description = self.projectElement.get('description') - - readUnitElementList = self.projectElement.iter(ReadUnitConf().getElementName()) - + self.description = self.projectElement.get('description') + + readUnitElementList = self.projectElement.iter( + ReadUnitConf().getElementName()) + for readUnitElement in readUnitElementList: readUnitConfObj = ReadUnitConf() readUnitConfObj.readXml(readUnitElement) - + if readUnitConfObj.parentId == None: readUnitConfObj.parentId = self.id - + self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj - - procUnitElementList = self.projectElement.iter(ProcUnitConf().getElementName()) - + + procUnitElementList = self.projectElement.iter( + ProcUnitConf().getElementName()) + for procUnitElement in procUnitElementList: procUnitConfObj = ProcUnitConf() procUnitConfObj.readXml(procUnitElement) - + if procUnitConfObj.parentId == None: procUnitConfObj.parentId = self.id - + self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj - + self.filename = abs_file - + return 1 - + def printattr(self): - - print "Project[%s]: name = %s, description = %s" %(self.id, - self.name, - self.description) - + + print 'Project[%s]: name = %s, description = %s' % (self.id, + self.name, + self.description) + for procUnitConfObj in self.procUnitConfObjDict.values(): procUnitConfObj.printattr() - + def createObjects(self): - + for procUnitConfObj in self.procUnitConfObjDict.values(): procUnitConfObj.createObjects(self.plotterQueue) - + def __connect(self, objIN, thisObj): - + thisObj.setInput(objIN.getOutputObj()) - + def connectObjects(self): - + for thisPUConfObj in self.procUnitConfObjDict.values(): - + inputId = thisPUConfObj.getInputId() - + if int(inputId) == 0: continue - - #Get input object + + # Get input object puConfINObj = self.procUnitConfObjDict[inputId] puObjIN = puConfINObj.getProcUnitObj() - - #Get current object + + # Get current object thisPUObj = thisPUConfObj.getProcUnitObj() - + self.__connect(puObjIN, thisPUObj) - - def __handleError(self, procUnitConfObj, send_email=True): - + + def __handleError(self, procUnitConfObj, modes=None, stdout=True): + import socket + + if modes is None: + modes = self.alarm + if not self.alarm: + modes = [] + err = traceback.format_exception(sys.exc_info()[0], - sys.exc_info()[1], - sys.exc_info()[2]) + sys.exc_info()[1], + sys.exc_info()[2]) - print "***** Error occurred in %s *****" %(procUnitConfObj.name) - print "***** %s" %err[-1] + log.error('{}'.format(err[-1]), procUnitConfObj.name) + + message = ''.join(err) + + if stdout: + sys.stderr.write(message) + + subject = 'SChain v%s: Error running %s\n' % ( + schainpy.__version__, procUnitConfObj.name) + + subtitle = '%s: %s\n' % ( + procUnitConfObj.getElementName(), procUnitConfObj.name) + subtitle += 'Hostname: %s\n' % socket.gethostbyname( + socket.gethostname()) + subtitle += 'Working directory: %s\n' % os.path.abspath('./') + subtitle += 'Configuration file: %s\n' % self.filename + subtitle += 'Time: %s\n' % str(datetime.datetime.now()) - message = "".join(err) - - sys.stderr.write(message) - - if not send_email: - return - - subject = "SChain v%s: Error running %s\n" %(schainpy.__version__, procUnitConfObj.name) - - subtitle = "%s: %s\n" %(procUnitConfObj.getElementName() ,procUnitConfObj.name) - subtitle += "Hostname: %s\n" %socket.gethostbyname(socket.gethostname()) - subtitle += "Working directory: %s\n" %os.path.abspath("./") - subtitle += "Configuration file: %s\n" %self.filename - subtitle += "Time: %s\n" %str(datetime.datetime.now()) - readUnitConfObj = self.getReadUnitObj() if readUnitConfObj: - subtitle += "\nInput parameters:\n" - subtitle += "[Data path = %s]\n" %readUnitConfObj.path - subtitle += "[Data type = %s]\n" %readUnitConfObj.datatype - subtitle += "[Start date = %s]\n" %readUnitConfObj.startDate - subtitle += "[End date = %s]\n" %readUnitConfObj.endDate - subtitle += "[Start time = %s]\n" %readUnitConfObj.startTime - subtitle += "[End time = %s]\n" %readUnitConfObj.endTime - - adminObj = schainpy.admin.SchainNotify() - adminObj.sendAlert(message=message, - subject=subject, - subtitle=subtitle, - filename=self.filename) - + subtitle += '\nInput parameters:\n' + subtitle += '[Data path = %s]\n' % readUnitConfObj.path + subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype + subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate + subtitle += '[End date = %s]\n' % readUnitConfObj.endDate + subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime + subtitle += '[End time = %s]\n' % readUnitConfObj.endTime + + a = Alarm( + modes=modes, + email=self.email, + message=message, + subject=subject, + subtitle=subtitle, + filename=self.filename + ) + + return a + def isPaused(self): return 0 - + def isStopped(self): return 0 - + def runController(self): - """ + ''' returns 0 when this process has been stopped, 1 otherwise - """ - + ''' + if self.isPaused(): - print "Process suspended" - + print 'Process suspended' + while True: - sleep(0.1) - + time.sleep(0.1) + if not self.isPaused(): break - + if self.isStopped(): break - - print "Process reinitialized" - + + print 'Process reinitialized' + if self.isStopped(): - print "Process stopped" + print 'Process stopped' return 0 - + return 1 def setFilename(self, filename): - + self.filename = filename - + def setPlotterQueue(self, plotter_queue): - - raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class" + + raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class' def getPlotterQueue(self): - - raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class" + + raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class' def useExternalPlotter(self): - - raise NotImplementedError, "Use schainpy.controller_api.ControllerThread instead Project class" - + + raise NotImplementedError, 'Use schainpy.controller_api.ControllerThread instead Project class' + def run(self): - - print - print "*"*60 - print " Starting SIGNAL CHAIN PROCESSING v%s " %schainpy.__version__ - print "*"*60 - print - + + log.success('Starting {}'.format(self.name), tag='') + self.start_time = time.time() + self.createObjects() + self.connectObjects() + keyList = self.procUnitConfObjDict.keys() keyList.sort() - + + err = None + while(True): - + is_ok = False - + for procKey in keyList: -# print "Running the '%s' process with %s" %(procUnitConfObj.name, procUnitConfObj.id) - + procUnitConfObj = self.procUnitConfObjDict[procKey] - + try: sts = procUnitConfObj.run() is_ok = is_ok or sts + except SchainWarning: + err = self.__handleError(procUnitConfObj, modes=[2, 3], stdout=False) + is_ok = False + break except KeyboardInterrupt: is_ok = False break except ValueError, e: - sleep(0.5) - self.__handleError(procUnitConfObj, send_email=True) + time.sleep(0.5) + err = self.__handleError(procUnitConfObj) is_ok = False break except: - sleep(0.5) - self.__handleError(procUnitConfObj) + time.sleep(0.5) + err = self.__handleError(procUnitConfObj) is_ok = False break - - #If every process unit finished so end process + + # If every process unit finished so end process if not(is_ok): -# print "Every process unit have finished" break if not self.runController(): break - - #Closing every process + + # Closing every process for procKey in keyList: procUnitConfObj = self.procUnitConfObjDict[procKey] procUnitConfObj.close() - - print "Process finished" - - def start(self): - - self.writeXml() - - self.createObjects() - self.connectObjects() - self.run() - -if __name__ == '__main__': - - desc = "Segundo Test" - filename = "schain.xml" - - controllerObj = Project() - - controllerObj.setup(id = '191', name='test01', description=desc) - - readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path='data/rawdata/', - startDate='2011/01/01', - endDate='2012/12/31', - startTime='00:00:00', - endTime='23:59:59', - online=1, - walk=1) - - procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - - opObj10 = procUnitConfObj0.addOperation(name='selectChannels') - opObj10.addParameter(name='channelList', value='3,4,5', format='intlist') - - opObj10 = procUnitConfObj0.addOperation(name='selectHeights') - opObj10.addParameter(name='minHei', value='90', format='float') - opObj10.addParameter(name='maxHei', value='180', format='float') - - opObj12 = procUnitConfObj0.addOperation(name='CohInt', optype='external') - opObj12.addParameter(name='n', value='10', format='int') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj0.getId()) - procUnitConfObj1.addParameter(name='nFFTPoints', value='32', format='int') -# procUnitConfObj1.addParameter(name='pairList', value='(0,1),(0,2),(1,2)', format='') - - - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external') - opObj11.addParameter(name='idfigure', value='1', format='int') - opObj11.addParameter(name='wintitle', value='SpectraPlot0', format='str') - opObj11.addParameter(name='zmin', value='40', format='int') - opObj11.addParameter(name='zmax', value='90', format='int') - opObj11.addParameter(name='showprofile', value='1', format='int') - - print "Escribiendo el archivo XML" - - controllerObj.writeXml(filename) - - print "Leyendo el archivo XML" - controllerObj.readXml(filename) - #controllerObj.printattr() - - controllerObj.createObjects() - controllerObj.connectObjects() - controllerObj.run() - - \ No newline at end of file + + if err is not None: + err.start() + # err.join() + + log.success('{} finished (time: {}s)'.format( + self.name, + time.time()-self.start_time)) diff --git a/schainpy/controller_api.py b/schainpy/controller_api.py index 6df488f..2d1775e 100644 --- a/schainpy/controller_api.py +++ b/schainpy/controller_api.py @@ -5,175 +5,175 @@ from schainpy.controller import Project from schainpy.model.graphics.jroplotter import PlotManager class ControllerThread(threading.Thread, Project): - + def __init__(self, plotter_queue=None): - + threading.Thread.__init__(self) Project.__init__(self, plotter_queue) - + self.setDaemon(True) - + self.lock = threading.Lock() self.control = { 'stop':False, 'pause':False } def __del__(self): - + self.control['stop'] = True - + def stop(self): - + self.lock.acquire() - + self.control['stop'] = True - + self.lock.release() - + def pause(self): - + self.lock.acquire() - + self.control['pause'] = not(self.control['pause']) paused = self.control['pause'] - + self.lock.release() - + return paused - + def isPaused(self): - + self.lock.acquire() paused = self.control['pause'] self.lock.release() - + return paused - + def isStopped(self): - + self.lock.acquire() stopped = self.control['stop'] self.lock.release() - + return stopped - + def run(self): self.control['stop'] = False self.control['pause'] = False - + self.writeXml() - + self.createObjects() self.connectObjects() Project.run(self) - + def isRunning(self): - + return self.is_alive() - + def isFinished(self): - + return not self.is_alive() def setPlotters(self): - + plotterList = PlotManager.plotterList - + for thisPUConfObj in self.procUnitConfObjDict.values(): - + inputId = thisPUConfObj.getInputId() - + if int(inputId) == 0: continue - + for thisOpObj in thisPUConfObj.getOperationObjList(): - + if thisOpObj.type == "self": continue - + if thisOpObj.name in plotterList: thisOpObj.type = "other" def setPlotterQueue(self, plotter_queue): - + self.plotterQueue = plotter_queue - + def getPlotterQueue(self): - + return self.plotterQueue def useExternalPlotter(self): - + self.plotterQueue = Queue(10) self.setPlotters() - + plotManagerObj = PlotManager(self.plotterQueue) plotManagerObj.setController(self) - + return plotManagerObj - + # from PyQt4 import QtCore # from PyQt4.QtCore import SIGNAL -# +# # class ControllerQThread(QtCore.QThread, Project): -# +# # def __init__(self, filename): -# +# # QtCore.QThread.__init__(self) # Project.__init__(self) -# +# # self.filename = filename -# +# # self.lock = threading.Lock() # self.control = {'stop':False, 'pause':False} -# +# # def __del__(self): -# +# # self.control['stop'] = True # self.wait() -# +# # def stop(self): -# +# # self.lock.acquire() -# +# # self.control['stop'] = True -# +# # self.lock.release() -# +# # def pause(self): -# +# # self.lock.acquire() -# +# # self.control['pause'] = not(self.control['pause']) # paused = self.control['pause'] -# +# # self.lock.release() -# +# # return paused -# +# # def isPaused(self): -# +# # self.lock.acquire() # paused = self.control['pause'] # self.lock.release() -# +# # return paused -# +# # def isStopped(self): -# +# # self.lock.acquire() # stopped = self.control['stop'] # self.lock.release() -# +# # return stopped -# +# # def run(self): -# +# # self.control['stop'] = False # self.control['pause'] = False -# +# # self.readXml(self.filename) # self.createObjects() # self.connectObjects() # self.emit( SIGNAL( "jobStarted( PyQt_PyObject )" ), 1) # Project.run(self) # self.emit( SIGNAL( "jobFinished( PyQt_PyObject )" ), 1) -# \ No newline at end of file +# diff --git a/schainpy/gui/schainGUI b/schainpy/gui/schainGUI index 610d685..6532eee 100644 --- a/schainpy/gui/schainGUI +++ b/schainpy/gui/schainGUI @@ -1,29 +1,39 @@ #!/usr/bin/env python -import os, sys -from PyQt4 import QtCore, QtGui -from PyQt4.QtGui import QApplication +import os +import sys +from schainpy.utils import log + +try: + from PyQt4 import QtCore, QtGui + from PyQt4.QtGui import QApplication +except: + log.error( + 'You should install PyQt4 module in order to run the GUI. See the README.') + sys.exit() from schainpy.gui.viewcontroller.initwindow import InitWindow from schainpy.gui.viewcontroller.basicwindow import BasicWindow from schainpy.gui.viewcontroller.workspace import Workspace + def main(): - + app = QtGui.QApplication(sys.argv) - - Welcome=InitWindow() - - if not Welcome.exec_(): - sys.exit(-1) - - WorkPathspace=Workspace() - if not WorkPathspace.exec_(): + + Welcome = InitWindow() + + if not Welcome.exec_(): sys.exit(-1) - - MainGUI=BasicWindow() - MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText()) + + WorkPathspace = Workspace() + if not WorkPathspace.exec_(): + sys.exit(-1) + + MainGUI = BasicWindow() + MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText()) MainGUI.show() sys.exit(app.exec_()) - + + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/schainpy/gui/viewcontroller/basicwindow.py b/schainpy/gui/viewcontroller/basicwindow.py index caf1333..c2d8e75 100644 --- a/schainpy/gui/viewcontroller/basicwindow.py +++ b/schainpy/gui/viewcontroller/basicwindow.py @@ -6218,3 +6218,6 @@ class ShowMeConsole(QtCore.QObject): text = text[:-1] self.textWritten.emit(str(text)) + + def flush(self): + pass diff --git a/schainpy/gui/viewcontroller/parametersModel.py b/schainpy/gui/viewcontroller/parametersModel.py index a3f1c17..665c01f 100644 --- a/schainpy/gui/viewcontroller/parametersModel.py +++ b/schainpy/gui/viewcontroller/parametersModel.py @@ -50,7 +50,6 @@ class ProjectParms(): indexDatatype = 2 if 'usrp' in self.datatype.lower(): indexDatatype = 3 - return indexDatatype def getExt(self): @@ -65,7 +64,6 @@ class ProjectParms(): ext = '.fits' if self.datatype.lower() == 'usrp': ext = '.hdf5' - return ext def set(self, project_name, datatype, ext, dpath, online, diff --git a/schainpy/model/__init__.py b/schainpy/model/__init__.py index 6dea354..ae3ce46 100644 --- a/schainpy/model/__init__.py +++ b/schainpy/model/__init__.py @@ -5,8 +5,8 @@ # from schainpy.model.utils.jroutils import * # from schainpy.serializer import * +from graphics import * from data import * from io import * from proc import * -from graphics import * from utils import * diff --git a/schainpy/model/data/BLTRheaderIO.py b/schainpy/model/data/BLTRheaderIO.py new file mode 100644 index 0000000..69e0d25 --- /dev/null +++ b/schainpy/model/data/BLTRheaderIO.py @@ -0,0 +1,404 @@ +''' + +$Author: murco $ +$Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $ +''' +import sys +import numpy +import copy +import datetime +from __builtin__ import None + +SPEED_OF_LIGHT = 299792458 +SPEED_OF_LIGHT = 3e8 + +FILE_STRUCTURE = numpy.dtype([ #HEADER 48bytes + ('FileMgcNumber',' vertical) + ('AntennaCoord',' endFp: + sys.stderr.write("Warning %s: Size value read from System Header is lower than it has to be\n" %fp.name) + return 0 + + if fp.tell() < endFp: + sys.stderr.write("Warning %s: Size value read from System Header size is greater than it has to be\n" %fp.name) + return 0 + + return 1 + + def write(self, fp): + + headerTuple = (self.RecMgcNumber, + self.RecCounter, + self.Off2StartNxtRec, + self.EpTimeStamp, + self.msCompTimeStamp, + self.ExpTagName, + self.ExpComment, + self.SiteLatDegrees, + self.SiteLongDegrees, + self.RTCgpsStatus, + self.TransmitFrec, + self.ReceiveFrec, + self.FirstOsciFrec, + self.Polarisation, + self.ReceiverFiltSett, + self.nModesInUse, + self.DualModeIndex, + self.DualModeRange, + self.nDigChannels, + self.SampResolution, + self.nRangeGatesSamp, + self.StartRangeSamp, + self.PRFhz, + self.Integrations, + self.nDataPointsTrsf, + self.nReceiveBeams, + self.nSpectAverages, + self.FFTwindowingInd, + self.BeamAngleAzim, + self.BeamAngleZen, + self.AntennaCoord, + self.RecPhaseCalibr, + self.RecAmpCalibr, + self.ReceiverGaindB) + +# self.size,self.nSamples, +# self.nProfiles, +# self.nChannels, +# self.adcResolution, +# self.pciDioBusWidth + + header = numpy.array(headerTuple,RECORD_STRUCTURE) + header.tofile(fp) + + return 1 + + +def get_dtype_index(numpy_dtype): + + index = None + + for i in range(len(NUMPY_DTYPE_LIST)): + if numpy_dtype == NUMPY_DTYPE_LIST[i]: + index = i + break + + return index + +def get_numpy_dtype(index): + + #dtype4 = numpy.dtype([('real',' nums_min: # rtest = float(j)/(j-1) + 1.0/navg # if ((sumq*j) > (rtest*sump**2)): @@ -93,290 +95,283 @@ def hildebrand_sekhon(data, navg): # sump = sump - sortdata[j] # sumq = sumq - sortdata[j]**2 # cont = 0 -# +# # j += 1 -# +# # lnoise = sump /j -# +# # return lnoise return cSchain.hildebrand_sekhon(sortdata, navg) class Beam: - + def __init__(self): self.codeList = [] self.azimuthList = [] - self.zenithList = [] + self.zenithList = [] + class GenericData(object): - + flagNoData = True - - def __init__(self): - - raise NotImplementedError - + def copy(self, inputObj=None): - + if inputObj == None: return copy.deepcopy(self) for key in inputObj.__dict__.keys(): - + attribute = inputObj.__dict__[key] - - #If this attribute is a tuple or list + + # If this attribute is a tuple or list if type(inputObj.__dict__[key]) in (tuple, list): self.__dict__[key] = attribute[:] continue - - #If this attribute is another object or instance + + # If this attribute is another object or instance if hasattr(attribute, '__dict__'): self.__dict__[key] = attribute.copy() continue - + self.__dict__[key] = inputObj.__dict__[key] def deepcopy(self): - + return copy.deepcopy(self) - + def isEmpty(self): - + return self.flagNoData - + + class JROData(GenericData): - -# m_BasicHeader = BasicHeader() -# m_ProcessingHeader = ProcessingHeader() + + # m_BasicHeader = BasicHeader() + # m_ProcessingHeader = ProcessingHeader() systemHeaderObj = SystemHeader() - + radarControllerHeaderObj = RadarControllerHeader() # data = None - + type = None - - datatype = None #dtype but in string - + + datatype = None # dtype but in string + # dtype = None - + # nChannels = None - + # nHeights = None - + nProfiles = None - + heightList = None - + channelList = None - + flagDiscontinuousBlock = False - + useLocalTime = False - + utctime = None - + timeZone = None - + dstFlag = None - + errorCount = None - + blocksize = None - + # nCode = None -# +# # nBaud = None -# +# # code = None - - flagDecodeData = False #asumo q la data no esta decodificada - - flagDeflipData = False #asumo q la data no esta sin flip - + + flagDecodeData = False # asumo q la data no esta decodificada + + flagDeflipData = False # asumo q la data no esta sin flip + flagShiftFFT = False - + # ippSeconds = None - + # timeInterval = None - + nCohInt = None - + # noise = None - + windowOfFilter = 1 - - #Speed of ligth + + # Speed of ligth C = 3e8 - + frequency = 49.92e6 - + realtime = False - + beacon_heiIndexList = None - + last_block = None - + blocknow = None azimuth = None - + zenith = None - + beam = Beam() - + profileIndex = None - - def __init__(self): - - raise NotImplementedError - + def getNoise(self): - + raise NotImplementedError - + def getNChannels(self): - + return len(self.channelList) - + def getChannelIndexList(self): - + return range(self.nChannels) - + def getNHeights(self): - + return len(self.heightList) - + def getHeiRange(self, extrapoints=0): - + heis = self.heightList # deltah = self.heightList[1] - self.heightList[0] -# +# # heis.append(self.heightList[-1]) - + return heis - + def getDeltaH(self): - + delta = self.heightList[1] - self.heightList[0] - + return delta - + def getltctime(self): - + if self.useLocalTime: - return self.utctime - self.timeZone*60 - + return self.utctime - self.timeZone * 60 + return self.utctime - + def getDatatime(self): - + datatimeValue = datetime.datetime.utcfromtimestamp(self.ltctime) return datatimeValue - + def getTimeRange(self): - + datatime = [] - + datatime.append(self.ltctime) - datatime.append(self.ltctime + self.timeInterval+1) - + datatime.append(self.ltctime + self.timeInterval + 1) + datatime = numpy.array(datatime) - + return datatime - + def getFmaxTimeResponse(self): - - period = (10**-6)*self.getDeltaH()/(0.15) - - PRF = 1./(period * self.nCohInt) - + + period = (10**-6) * self.getDeltaH() / (0.15) + + PRF = 1. / (period * self.nCohInt) + fmax = PRF - + return fmax - + def getFmax(self): - - PRF = 1./(self.ippSeconds * self.nCohInt) - + PRF = 1. / (self.ippSeconds * self.nCohInt) + fmax = PRF - return fmax - + def getVmax(self): - - _lambda = self.C/self.frequency - - vmax = self.getFmax() * _lambda/2 - + + _lambda = self.C / self.frequency + + vmax = self.getFmax() * _lambda / 2 + return vmax - + def get_ippSeconds(self): ''' ''' return self.radarControllerHeaderObj.ippSeconds - + def set_ippSeconds(self, ippSeconds): ''' ''' - + self.radarControllerHeaderObj.ippSeconds = ippSeconds - + return - + def get_dtype(self): ''' ''' return getNumpyDtype(self.datatype) - + def set_dtype(self, numpyDtype): ''' ''' - + self.datatype = getDataTypeCode(numpyDtype) def get_code(self): ''' ''' return self.radarControllerHeaderObj.code - + def set_code(self, code): ''' ''' self.radarControllerHeaderObj.code = code - + return def get_ncode(self): ''' ''' return self.radarControllerHeaderObj.nCode - + def set_ncode(self, nCode): ''' ''' self.radarControllerHeaderObj.nCode = nCode - + return def get_nbaud(self): ''' ''' return self.radarControllerHeaderObj.nBaud - + def set_nbaud(self, nBaud): ''' ''' self.radarControllerHeaderObj.nBaud = nBaud - + return - + nChannels = property(getNChannels, "I'm the 'nChannel' property.") - channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.") + channelIndexList = property( + getChannelIndexList, "I'm the 'channelIndexList' property.") nHeights = property(getNHeights, "I'm the 'nHeights' property.") #noise = property(getNoise, "I'm the 'nHeights' property.") datatime = property(getDatatime, "I'm the 'datatime' property") @@ -387,71 +382,72 @@ class JROData(GenericData): code = property(get_code, set_code) nCode = property(get_ncode, set_ncode) nBaud = property(get_nbaud, set_nbaud) - + + class Voltage(JROData): - - #data es un numpy array de 2 dmensiones (canales, alturas) + + # data es un numpy array de 2 dmensiones (canales, alturas) data = None - + def __init__(self): ''' Constructor ''' - + self.useLocalTime = True - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.systemHeaderObj = SystemHeader() - + self.type = "Voltage" - + self.data = None - + # self.dtype = None - + # self.nChannels = 0 - + # self.nHeights = 0 - + self.nProfiles = None - + self.heightList = None - + self.channelList = None - + # self.channelIndexList = None - + self.flagNoData = True - + self.flagDiscontinuousBlock = False - + self.utctime = None - + self.timeZone = None - + self.dstFlag = None - + self.errorCount = None - + self.nCohInt = None - + self.blocksize = None - - self.flagDecodeData = False #asumo q la data no esta decodificada - - self.flagDeflipData = False #asumo q la data no esta sin flip - + + self.flagDecodeData = False # asumo q la data no esta decodificada + + self.flagDeflipData = False # asumo q la data no esta sin flip + self.flagShiftFFT = False - - self.flagDataAsBlock = False #Asumo que la data es leida perfil a perfil - + + self.flagDataAsBlock = False # Asumo que la data es leida perfil a perfil + self.profileIndex = 0 - - def getNoisebyHildebrand(self, channel = None): + + def getNoisebyHildebrand(self, channel=None): """ Determino el nivel de ruido usando el metodo Hildebrand-Sekhon - + Return: noiselevel """ @@ -462,390 +458,434 @@ class Voltage(JROData): else: data = self.data nChannels = self.nChannels - + noise = numpy.zeros(nChannels) power = data * numpy.conjugate(data) - + for thisChannel in range(nChannels): if nChannels == 1: daux = power[:].real else: - daux = power[thisChannel,:].real + daux = power[thisChannel, :].real noise[thisChannel] = hildebrand_sekhon(daux, self.nCohInt) - + return noise - - def getNoise(self, type = 1, channel = None): - + + def getNoise(self, type=1, channel=None): + if type == 1: noise = self.getNoisebyHildebrand(channel) - + return noise - - def getPower(self, channel = None): - + + def getPower(self, channel=None): + if channel != None: data = self.data[channel] else: data = self.data - + power = data * numpy.conjugate(data) - powerdB = 10*numpy.log10(power.real) + powerdB = 10 * numpy.log10(power.real) powerdB = numpy.squeeze(powerdB) - + return powerdB - + def getTimeInterval(self): - + timeInterval = self.ippSeconds * self.nCohInt - + return timeInterval - + noise = property(getNoise, "I'm the 'nHeights' property.") timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property") - + + class Spectra(JROData): - - #data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas) + + # data spc es un numpy array de 2 dmensiones (canales, perfiles, alturas) data_spc = None - - #data cspc es un numpy array de 2 dmensiones (canales, pares, alturas) + + # data cspc es un numpy array de 2 dmensiones (canales, pares, alturas) data_cspc = None - - #data dc es un numpy array de 2 dmensiones (canales, alturas) + + # data dc es un numpy array de 2 dmensiones (canales, alturas) data_dc = None - - #data power + + # data power data_pwr = None - + nFFTPoints = None - + # nPairs = None - + pairsList = None - + nIncohInt = None - - wavelength = None #Necesario para cacular el rango de velocidad desde la frecuencia - - nCohInt = None #se requiere para determinar el valor de timeInterval - + + wavelength = None # Necesario para cacular el rango de velocidad desde la frecuencia + + nCohInt = None # se requiere para determinar el valor de timeInterval + ippFactor = None - + profileIndex = 0 - + plotting = "spectra" - + def __init__(self): ''' Constructor ''' - + self.useLocalTime = True - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.systemHeaderObj = SystemHeader() - + self.type = "Spectra" - + # self.data = None - + # self.dtype = None - + # self.nChannels = 0 - + # self.nHeights = 0 - + self.nProfiles = None - + self.heightList = None - + self.channelList = None - + # self.channelIndexList = None self.pairsList = None - + self.flagNoData = True - + self.flagDiscontinuousBlock = False - + self.utctime = None - + self.nCohInt = None - + self.nIncohInt = None - + self.blocksize = None - + self.nFFTPoints = None - + self.wavelength = None - - self.flagDecodeData = False #asumo q la data no esta decodificada - - self.flagDeflipData = False #asumo q la data no esta sin flip - + + self.flagDecodeData = False # asumo q la data no esta decodificada + + self.flagDeflipData = False # asumo q la data no esta sin flip + self.flagShiftFFT = False - + self.ippFactor = 1 - + #self.noise = None - + self.beacon_heiIndexList = [] - + self.noise_estimation = None - - + def getNoisebyHildebrand(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None): """ Determino el nivel de ruido usando el metodo Hildebrand-Sekhon - + Return: noiselevel """ - + noise = numpy.zeros(self.nChannels) - + for channel in range(self.nChannels): - daux = self.data_spc[channel,xmin_index:xmax_index,ymin_index:ymax_index] + daux = self.data_spc[channel, + xmin_index:xmax_index, ymin_index:ymax_index] noise[channel] = hildebrand_sekhon(daux, self.nIncohInt) - - return noise - + + return noise + def getNoise(self, xmin_index=None, xmax_index=None, ymin_index=None, ymax_index=None): - + if self.noise_estimation is not None: - return self.noise_estimation #this was estimated by getNoise Operation defined in jroproc_spectra.py + # this was estimated by getNoise Operation defined in jroproc_spectra.py + return self.noise_estimation else: - noise = self.getNoisebyHildebrand(xmin_index, xmax_index, ymin_index, ymax_index) + noise = self.getNoisebyHildebrand( + xmin_index, xmax_index, ymin_index, ymax_index) return noise - + def getFreqRangeTimeResponse(self, extrapoints=0): - - deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints*self.ippFactor) - freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2 - + + deltafreq = self.getFmaxTimeResponse() / (self.nFFTPoints * self.ippFactor) + freqrange = deltafreq * \ + (numpy.arange(self.nFFTPoints + extrapoints) - + self.nFFTPoints / 2.) - deltafreq / 2 + return freqrange - + def getAcfRange(self, extrapoints=0): - - deltafreq = 10./(self.getFmax() / (self.nFFTPoints*self.ippFactor)) - freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2 - + + deltafreq = 10. / (self.getFmax() / (self.nFFTPoints * self.ippFactor)) + freqrange = deltafreq * \ + (numpy.arange(self.nFFTPoints + extrapoints) - + self.nFFTPoints / 2.) - deltafreq / 2 + return freqrange - + def getFreqRange(self, extrapoints=0): - - deltafreq = self.getFmax() / (self.nFFTPoints*self.ippFactor) - freqrange = deltafreq*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) - deltafreq/2 - + + deltafreq = self.getFmax() / (self.nFFTPoints * self.ippFactor) + freqrange = deltafreq * \ + (numpy.arange(self.nFFTPoints + extrapoints) - + self.nFFTPoints / 2.) - deltafreq / 2 + return freqrange def getVelRange(self, extrapoints=0): - - deltav = self.getVmax() / (self.nFFTPoints*self.ippFactor) - velrange = deltav*(numpy.arange(self.nFFTPoints+extrapoints)-self.nFFTPoints/2.) #- deltav/2 - + + deltav = self.getVmax() / (self.nFFTPoints * self.ippFactor) + velrange = deltav * (numpy.arange(self.nFFTPoints + + extrapoints) - self.nFFTPoints / 2.) # - deltav/2 + return velrange - + def getNPairs(self): - + return len(self.pairsList) - + def getPairsIndexList(self): - + return range(self.nPairs) - + def getNormFactor(self): - + pwcode = 1 - + if self.flagDecodeData: pwcode = numpy.sum(self.code[0]**2) #normFactor = min(self.nFFTPoints,self.nProfiles)*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter - normFactor = self.nProfiles*self.nIncohInt*self.nCohInt*pwcode*self.windowOfFilter - + normFactor = self.nProfiles * self.nIncohInt * \ + self.nCohInt * pwcode * self.windowOfFilter + return normFactor - + def getFlagCspc(self): - + if self.data_cspc is None: return True - + return False - + def getFlagDc(self): - + if self.data_dc is None: return True - + return False - + def getTimeInterval(self): - - timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles - + + timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt * self.nProfiles * self.ippFactor + return timeInterval - + def getPower(self): - + factor = self.normFactor - z = self.data_spc/factor - z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + z = self.data_spc / factor + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) avg = numpy.average(z, axis=1) - - return 10*numpy.log10(avg) - + + return 10 * numpy.log10(avg) + + def getCoherence(self, pairsList=None, phase=False): + + z = [] + if pairsList is None: + pairsIndexList = self.pairsIndexList + else: + pairsIndexList = [] + for pair in pairsList: + if pair not in self.pairsList: + raise ValueError, "Pair %s is not in dataOut.pairsList" % ( + pair) + pairsIndexList.append(self.pairsList.index(pair)) + for i in range(len(pairsIndexList)): + pair = self.pairsList[pairsIndexList[i]] + ccf = numpy.average( + self.data_cspc[pairsIndexList[i], :, :], axis=0) + powa = numpy.average(self.data_spc[pair[0], :, :], axis=0) + powb = numpy.average(self.data_spc[pair[1], :, :], axis=0) + avgcoherenceComplex = ccf / numpy.sqrt(powa * powb) + if phase: + data = numpy.arctan2(avgcoherenceComplex.imag, + avgcoherenceComplex.real) * 180 / numpy.pi + else: + data = numpy.abs(avgcoherenceComplex) + + z.append(data) + + return numpy.array(z) + def setValue(self, value): - + print "This property should not be initialized" - + return - + nPairs = property(getNPairs, setValue, "I'm the 'nPairs' property.") - pairsIndexList = property(getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.") - normFactor = property(getNormFactor, setValue, "I'm the 'getNormFactor' property.") + pairsIndexList = property( + getPairsIndexList, setValue, "I'm the 'pairsIndexList' property.") + normFactor = property(getNormFactor, setValue, + "I'm the 'getNormFactor' property.") flag_cspc = property(getFlagCspc, setValue) flag_dc = property(getFlagDc, setValue) noise = property(getNoise, setValue, "I'm the 'nHeights' property.") - timeInterval = property(getTimeInterval, setValue, "I'm the 'timeInterval' property") - + timeInterval = property(getTimeInterval, setValue, + "I'm the 'timeInterval' property") + + class SpectraHeis(Spectra): - + data_spc = None - + data_cspc = None - + data_dc = None - + nFFTPoints = None - + # nPairs = None - + pairsList = None - + nCohInt = None - + nIncohInt = None - + def __init__(self): - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.systemHeaderObj = SystemHeader() - + self.type = "SpectraHeis" - + # self.dtype = None - + # self.nChannels = 0 - + # self.nHeights = 0 - + self.nProfiles = None - + self.heightList = None - + self.channelList = None - + # self.channelIndexList = None - + self.flagNoData = True - + self.flagDiscontinuousBlock = False - + # self.nPairs = 0 - + self.utctime = None - + self.blocksize = None - + self.profileIndex = 0 - + self.nCohInt = 1 - + self.nIncohInt = 1 - + def getNormFactor(self): pwcode = 1 if self.flagDecodeData: pwcode = numpy.sum(self.code[0]**2) - - normFactor = self.nIncohInt*self.nCohInt*pwcode - + + normFactor = self.nIncohInt * self.nCohInt * pwcode + return normFactor - + def getTimeInterval(self): - + timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt - + return timeInterval - + normFactor = property(getNormFactor, "I'm the 'getNormFactor' property.") timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property") + class Fits(JROData): - + heightList = None - + channelList = None - + flagNoData = True - + flagDiscontinuousBlock = False - + useLocalTime = False - + utctime = None - + timeZone = None - + # ippSeconds = None - + # timeInterval = None - + nCohInt = None - + nIncohInt = None - + noise = None - + windowOfFilter = 1 - - #Speed of ligth + + # Speed of ligth C = 3e8 - + frequency = 49.92e6 - + realtime = False - def __init__(self): - + self.type = "Fits" - + self.nProfiles = None - + self.heightList = None - + self.channelList = None - + # self.channelIndexList = None - + self.flagNoData = True - + self.utctime = None - + self.nCohInt = 1 - + self.nIncohInt = 1 - + self.useLocalTime = True - + self.profileIndex = 0 - + # self.utctime = None # self.timeZone = None # self.ltctime = None @@ -860,230 +900,231 @@ class Fits(JROData): # self.nSamples = None # self.dataBlocksPerFile = None # self.comments = '' -# +# - def getltctime(self): - + if self.useLocalTime: - return self.utctime - self.timeZone*60 - + return self.utctime - self.timeZone * 60 + return self.utctime - + def getDatatime(self): - + datatime = datetime.datetime.utcfromtimestamp(self.ltctime) return datatime - + def getTimeRange(self): - + datatime = [] - + datatime.append(self.ltctime) datatime.append(self.ltctime + self.timeInterval) - + datatime = numpy.array(datatime) - + return datatime - + def getHeiRange(self): - + heis = self.heightList - + return heis - + def getNHeights(self): - + return len(self.heightList) - + def getNChannels(self): - + return len(self.channelList) - + def getChannelIndexList(self): - + return range(self.nChannels) - - def getNoise(self, type = 1): - + + def getNoise(self, type=1): + #noise = numpy.zeros(self.nChannels) - + if type == 1: noise = self.getNoisebyHildebrand() - + if type == 2: noise = self.getNoisebySort() - + if type == 3: noise = self.getNoisebyWindow() - + return noise - + def getTimeInterval(self): - + timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt - + return timeInterval - + datatime = property(getDatatime, "I'm the 'datatime' property") nHeights = property(getNHeights, "I'm the 'nHeights' property.") nChannels = property(getNChannels, "I'm the 'nChannel' property.") - channelIndexList = property(getChannelIndexList, "I'm the 'channelIndexList' property.") + channelIndexList = property( + getChannelIndexList, "I'm the 'channelIndexList' property.") noise = property(getNoise, "I'm the 'nHeights' property.") - + ltctime = property(getltctime, "I'm the 'ltctime' property") timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property") - - + + class Correlation(JROData): - + noise = None - + SNR = None - + #-------------------------------------------------- - + mode = None - + split = False data_cf = None - + lags = None - + lagRange = None - + pairsList = None - + normFactor = None - + #-------------------------------------------------- - + # calculateVelocity = None - + nLags = None - + nPairs = None - + nAvg = None - def __init__(self): ''' Constructor ''' self.radarControllerHeaderObj = RadarControllerHeader() - + self.systemHeaderObj = SystemHeader() - + self.type = "Correlation" - + self.data = None - + self.dtype = None - + self.nProfiles = None - + self.heightList = None - + self.channelList = None - + self.flagNoData = True - + self.flagDiscontinuousBlock = False - + self.utctime = None - + self.timeZone = None - + self.dstFlag = None - + self.errorCount = None - + self.blocksize = None - - self.flagDecodeData = False #asumo q la data no esta decodificada - - self.flagDeflipData = False #asumo q la data no esta sin flip - + + self.flagDecodeData = False # asumo q la data no esta decodificada + + self.flagDeflipData = False # asumo q la data no esta sin flip + self.pairsList = None - + self.nPoints = None def getPairsList(self): - + return self.pairsList - - def getNoise(self, mode = 2): - + + def getNoise(self, mode=2): + indR = numpy.where(self.lagR == 0)[0][0] indT = numpy.where(self.lagT == 0)[0][0] - - jspectra0 = self.data_corr[:,:,indR,:] + + jspectra0 = self.data_corr[:, :, indR, :] jspectra = copy.copy(jspectra0) - + num_chan = jspectra.shape[0] num_hei = jspectra.shape[2] - - freq_dc = jspectra.shape[1]/2 - ind_vel = numpy.array([-2,-1,1,2]) + freq_dc - - if ind_vel[0]<0: - ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof - - if mode == 1: - jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION - + + freq_dc = jspectra.shape[1] / 2 + ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc + + if ind_vel[0] < 0: + ind_vel[range(0, 1)] = ind_vel[range(0, 1)] + self.num_prof + + if mode == 1: + jspectra[:, freq_dc, :] = ( + jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION + if mode == 2: - - vel = numpy.array([-2,-1,1,2]) - xx = numpy.zeros([4,4]) - + + vel = numpy.array([-2, -1, 1, 2]) + xx = numpy.zeros([4, 4]) + for fil in range(4): - xx[fil,:] = vel[fil]**numpy.asarray(range(4)) - + xx[fil, :] = vel[fil]**numpy.asarray(range(4)) + xx_inv = numpy.linalg.inv(xx) - xx_aux = xx_inv[0,:] - + xx_aux = xx_inv[0, :] + for ich in range(num_chan): - yy = jspectra[ich,ind_vel,:] - jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy) + yy = jspectra[ich, ind_vel, :] + jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy) - junkid = jspectra[ich,freq_dc,:]<=0 + junkid = jspectra[ich, freq_dc, :] <= 0 cjunkid = sum(junkid) - + if cjunkid.any(): - jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2 - - noise = jspectra0[:,freq_dc,:] - jspectra[:,freq_dc,:] - + jspectra[ich, freq_dc, junkid.nonzero()] = ( + jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2 + + noise = jspectra0[:, freq_dc, :] - jspectra[:, freq_dc, :] + return noise def getTimeInterval(self): - + timeInterval = self.ippSeconds * self.nCohInt * self.nProfiles - + return timeInterval - + def splitFunctions(self): - + pairsList = self.pairsList ccf_pairs = [] acf_pairs = [] ccf_ind = [] acf_ind = [] - for l in range(len(pairsList)): + for l in range(len(pairsList)): chan0 = pairsList[l][0] chan1 = pairsList[l][1] - - #Obteniendo pares de Autocorrelacion + + # Obteniendo pares de Autocorrelacion if chan0 == chan1: acf_pairs.append(chan0) acf_ind.append(l) else: ccf_pairs.append(pairsList[l]) ccf_ind.append(l) - + data_acf = self.data_cf[acf_ind] data_ccf = self.data_cf[ccf_ind] @@ -1092,98 +1133,119 @@ class Correlation(JROData): def getNormFactor(self): acf_ind, ccf_ind, acf_pairs, ccf_pairs, data_acf, data_ccf = self.splitFunctions() acf_pairs = numpy.array(acf_pairs) - normFactor = numpy.zeros((self.nPairs,self.nHeights)) - + normFactor = numpy.zeros((self.nPairs, self.nHeights)) + for p in range(self.nPairs): pair = self.pairsList[p] - + ch0 = pair[0] ch1 = pair[1] - - ch0_max = numpy.max(data_acf[acf_pairs==ch0,:,:], axis=1) - ch1_max = numpy.max(data_acf[acf_pairs==ch1,:,:], axis=1) - normFactor[p,:] = numpy.sqrt(ch0_max*ch1_max) - + + ch0_max = numpy.max(data_acf[acf_pairs == ch0, :, :], axis=1) + ch1_max = numpy.max(data_acf[acf_pairs == ch1, :, :], axis=1) + normFactor[p, :] = numpy.sqrt(ch0_max * ch1_max) + return normFactor - + timeInterval = property(getTimeInterval, "I'm the 'timeInterval' property") normFactor = property(getNormFactor, "I'm the 'normFactor property'") - -class Parameters(JROData): - - experimentInfo = None #Information about the experiment - - #Information from previous data - - inputUnit = None #Type of data to be processed - - operation = None #Type of operation to parametrize - - normFactor = None #Normalization Factor - - groupList = None #List of Pairs, Groups, etc - - #Parameters - - data_param = None #Parameters obtained - - data_pre = None #Data Pre Parametrization - - data_SNR = None #Signal to Noise Ratio - + + +class Parameters(Spectra): + + experimentInfo = None # Information about the experiment + + # Information from previous data + + inputUnit = None # Type of data to be processed + + operation = None # Type of operation to parametrize + + # normFactor = None #Normalization Factor + + groupList = None # List of Pairs, Groups, etc + + # Parameters + + data_param = None # Parameters obtained + + data_pre = None # Data Pre Parametrization + + data_SNR = None # Signal to Noise Ratio + # heightRange = None #Heights - - abscissaList = None #Abscissa, can be velocities, lags or time - - noise = None #Noise Potency - - utctimeInit = None #Initial UTC time - - paramInterval = None #Time interval to calculate Parameters in seconds - + + abscissaList = None # Abscissa, can be velocities, lags or time + +# noise = None #Noise Potency + + utctimeInit = None # Initial UTC time + + paramInterval = None # Time interval to calculate Parameters in seconds + useLocalTime = True - - #Fitting - - data_error = None #Error of the estimation - - constants = None - + + # Fitting + + data_error = None # Error of the estimation + + constants = None + library = None - - #Output signal - - outputInterval = None #Time interval to calculate output signal in seconds - - data_output = None #Out signal - + + # Output signal + + outputInterval = None # Time interval to calculate output signal in seconds + + data_output = None # Out signal + nAvg = None - - + + noise_estimation = None + + GauSPC = None # Fit gaussian SPC + def __init__(self): ''' Constructor ''' self.radarControllerHeaderObj = RadarControllerHeader() - + self.systemHeaderObj = SystemHeader() - + self.type = "Parameters" - + def getTimeRange1(self, interval): - + datatime = [] - + if self.useLocalTime: - time1 = self.utctimeInit - self.timeZone*60 + time1 = self.utctimeInit - self.timeZone * 60 else: time1 = self.utctimeInit - -# datatime.append(self.utctimeInit) -# datatime.append(self.utctimeInit + self.outputInterval) + datatime.append(time1) datatime.append(time1 + interval) - datatime = numpy.array(datatime) - - return datatime + + return datatime + + def getTimeInterval(self): + + if hasattr(self, 'timeInterval1'): + return self.timeInterval1 + else: + return self.paramInterval + + def setValue(self, value): + + print "This property should not be initialized" + + return + + def getNoise(self): + + return self.spc_noise + + timeInterval = property(getTimeInterval) + noise = property(getNoise, setValue, "I'm the 'Noise' property.") diff --git a/schainpy/model/data/jroheaderIO.py b/schainpy/model/data/jroheaderIO.py index c03853d..2f0b4f9 100644 --- a/schainpy/model/data/jroheaderIO.py +++ b/schainpy/model/data/jroheaderIO.py @@ -7,104 +7,126 @@ import sys import numpy import copy import datetime +import inspect SPEED_OF_LIGHT = 299792458 SPEED_OF_LIGHT = 3e8 BASIC_STRUCTURE = numpy.dtype([ - ('nSize',' endFp: - sys.stderr.write("Warning %s: Size value read from System Header is lower than it has to be\n" %fp.name) - return 0 - - if fp.tell() < endFp: - sys.stderr.write("Warning %s: Size value read from System Header size is greater than it has to be\n" %fp.name) - return 0 - + + if startFp is not None: + endFp = self.size + startFp + + if fp.tell() > endFp: + sys.stderr.write( + "Warning %s: Size value read from System Header is lower than it has to be\n" % fp.name) + return 0 + + if fp.tell() < endFp: + sys.stderr.write( + "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp.name) + return 0 + + self.length = header.nbytes return 1 - + def write(self, fp): - - headerTuple = (self.size,self.nSamples,self.nProfiles,self.nChannels,self.adcResolution,self.pciDioBusWidth) - header = numpy.array(headerTuple,SYSTEM_STRUCTURE) + + headerTuple = (self.size, self.nSamples, self.nProfiles, + self.nChannels, self.adcResolution, self.pciDioBusWidth) + header = numpy.array(headerTuple, SYSTEM_STRUCTURE) header.tofile(fp) - + return 1 + class RadarControllerHeader(Header): - + expType = None nTx = None ipp = None @@ -247,31 +289,31 @@ class RadarControllerHeader(Header): line5Function = None fClock = None prePulseBefore = None - prePulserAfter = None + prePulseAfter = None rangeIpp = None rangeTxA = None rangeTxB = None - + structure = RADAR_STRUCTURE __size = None - + def __init__(self, expType=2, nTx=1, - ippKm=None, txA=0, txB=0, + ipp=None, txA=0, txB=0, nWindows=None, nHeights=None, firstHeight=None, deltaHeight=None, numTaus=0, line6Function=0, line5Function=0, fClock=None, prePulseBefore=0, prePulseAfter=0, codeType=0, nCode=0, nBaud=0, code=None, flip1=0, flip2=0): - -# self.size = 116 + + # self.size = 116 self.expType = expType self.nTx = nTx - self.ipp = ippKm + self.ipp = ipp self.txA = txA self.txB = txB - self.rangeIpp = ippKm + self.rangeIpp = ipp self.rangeTxA = txA self.rangeTxB = txB - + self.nWindows = nWindows self.numTaus = numTaus self.codeType = codeType @@ -279,35 +321,43 @@ class RadarControllerHeader(Header): self.line5Function = line5Function self.fClock = fClock self.prePulseBefore = prePulseBefore - self.prePulserAfter = prePulseAfter - + self.prePulseAfter = prePulseAfter + self.nHeights = nHeights self.firstHeight = firstHeight self.deltaHeight = deltaHeight self.samplesWin = nHeights - + self.nCode = nCode self.nBaud = nBaud self.code = code self.flip1 = flip1 self.flip2 = flip2 - - self.code_size = int(numpy.ceil(self.nBaud/32.))*self.nCode*4 + + self.code_size = int(numpy.ceil(self.nBaud / 32.)) * self.nCode * 4 # self.dynamic = numpy.array([],numpy.dtype('byte')) - + if self.fClock is None and self.deltaHeight is not None: - self.fClock = 0.15/(deltaHeight*1e-6) #0.15Km / (height * 1u) + self.fClock = 0.15 / (deltaHeight * 1e-6) # 0.15Km / (height * 1u) def read(self, fp): - - - startFp = fp.tell() + self.length = 0 + try: + startFp = fp.tell() + except Exception, e: + startFp = None + pass + try: - header = numpy.fromfile(fp,RADAR_STRUCTURE,1) + if hasattr(fp, 'read'): + header = numpy.fromfile(fp, RADAR_STRUCTURE, 1) + else: + header = numpy.fromstring(fp, RADAR_STRUCTURE, 1) + self.length += header.nbytes except Exception, e: - print "RadarControllerHeader: " + e + print "RadarControllerHeader: " + str(e) return 0 - + size = int(header['nSize'][0]) self.expType = int(header['nExpType'][0]) self.nTx = int(header['nNTx'][0]) @@ -321,60 +371,105 @@ class RadarControllerHeader(Header): self.line5Function = int(header['nLine5Function'][0]) self.fClock = float(header['fClock'][0]) self.prePulseBefore = int(header['nPrePulseBefore'][0]) - self.prePulserAfter = int(header['nPrePulseAfter'][0]) + self.prePulseAfter = int(header['nPrePulseAfter'][0]) self.rangeIpp = header['sRangeIPP'][0] self.rangeTxA = header['sRangeTxA'][0] self.rangeTxB = header['sRangeTxB'][0] - - samplingWindow = numpy.fromfile(fp,SAMPLING_STRUCTURE,self.nWindows) - + + try: + if hasattr(fp, 'read'): + samplingWindow = numpy.fromfile( + fp, SAMPLING_STRUCTURE, self.nWindows) + else: + samplingWindow = numpy.fromstring( + fp[self.length:], SAMPLING_STRUCTURE, self.nWindows) + self.length += samplingWindow.nbytes + except Exception, e: + print "RadarControllerHeader: " + str(e) + return 0 self.nHeights = int(numpy.sum(samplingWindow['nsa'])) self.firstHeight = samplingWindow['h0'] self.deltaHeight = samplingWindow['dh'] self.samplesWin = samplingWindow['nsa'] - - self.Taus = numpy.fromfile(fp,' endFp: - sys.stderr.write("Warning %s: Size value read from Radar Controller header is lower than it has to be\n" %fp.name) -# return 0 - - if fp.tell() < endFp: - sys.stderr.write("Warning %s: Size value read from Radar Controller header is greater than it has to be\n" %fp.name) - - + if startFp is not None: + endFp = size + startFp + + if fp.tell() != endFp: + # fp.seek(endFp) + print "%s: Radar Controller Header size is not consistent: from data [%d] != from header field [%d]" % (fp.name, fp.tell() - startFp, size) + # return 0 + + if fp.tell() > endFp: + sys.stderr.write( + "Warning %s: Size value read from Radar Controller header is lower than it has to be\n" % fp.name) + # return 0 + + if fp.tell() < endFp: + sys.stderr.write( + "Warning %s: Size value read from Radar Controller header is greater than it has to be\n" % fp.name) + return 1 - + def write(self, fp): - + headerTuple = (self.size, self.expType, self.nTx, @@ -388,87 +483,91 @@ class RadarControllerHeader(Header): self.line5Function, self.fClock, self.prePulseBefore, - self.prePulserAfter, + self.prePulseAfter, self.rangeIpp, self.rangeTxA, self.rangeTxB) - - header = numpy.array(headerTuple,RADAR_STRUCTURE) + + header = numpy.array(headerTuple, RADAR_STRUCTURE) header.tofile(fp) - - sampleWindowTuple = (self.firstHeight,self.deltaHeight,self.samplesWin) - samplingWindow = numpy.array(sampleWindowTuple,SAMPLING_STRUCTURE) + + sampleWindowTuple = ( + self.firstHeight, self.deltaHeight, self.samplesWin) + samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE) samplingWindow.tofile(fp) - + if self.numTaus > 0: self.Taus.tofile(fp) - - if self.codeType !=0: + + if self.codeType != 0: nCode = numpy.array(self.nCode, ' 0: self.flag_cspc = True - - endFp = size + startFp - - if fp.tell() > endFp: - sys.stderr.write("Warning: Processing header size is lower than it has to be") - return 0 - - if fp.tell() < endFp: - sys.stderr.write("Warning: Processing header size is greater than it is considered") - + + if startFp is not None: + endFp = size + startFp + if fp.tell() > endFp: + sys.stderr.write( + "Warning: Processing header size is lower than it has to be") + return 0 + + if fp.tell() < endFp: + sys.stderr.write( + "Warning: Processing header size is greater than it is considered") + return 1 - + def write(self, fp): - #Clear DEFINE_PROCESS_CODE + # Clear DEFINE_PROCESS_CODE self.processFlags = self.processFlags & (~PROCFLAG.DEFINE_PROCESS_CODE) - + headerTuple = (self.size, self.dtype, self.blockSize, @@ -609,154 +743,163 @@ class ProcessingHeader(Header): self.nCohInt, self.nIncohInt, self.totalSpectra) - - header = numpy.array(headerTuple,PROCESSING_STRUCTURE) + + header = numpy.array(headerTuple, PROCESSING_STRUCTURE) header.tofile(fp) - + if self.nWindows != 0: - sampleWindowTuple = (self.firstHeight,self.deltaHeight,self.samplesWin) - samplingWindow = numpy.array(sampleWindowTuple,SAMPLING_STRUCTURE) + sampleWindowTuple = ( + self.firstHeight, self.deltaHeight, self.samplesWin) + samplingWindow = numpy.array(sampleWindowTuple, SAMPLING_STRUCTURE) samplingWindow.tofile(fp) - + if self.totalSpectra != 0: -# spectraComb = numpy.array([],numpy.dtype('u1')) + # spectraComb = numpy.array([],numpy.dtype('u1')) spectraComb = self.spectraComb spectraComb.tofile(fp) - + # if self.processFlags & PROCFLAG.DEFINE_PROCESS_CODE == PROCFLAG.DEFINE_PROCESS_CODE: # nCode = numpy.array([self.nCode], numpy.dtype('u4')) #Probar con un dato que almacene codigo, hasta el momento no se hizo la prueba # nCode.tofile(fp) -# +# # nBaud = numpy.array([self.nBaud], numpy.dtype('u4')) # nBaud.tofile(fp) -# +# # code = self.code.reshape(self.nCode*self.nBaud) # code = code.astype(numpy.dtype('= xmin and hour <= xmax: return 1 else: return 0 - + else: - + if hour >= xmin or hour <= (xmax % 24): return 1 else: return 0 - + return 0 def isRealtime(utcdatatime): - + utcnow = time.mktime(time.localtime()) delta = abs(utcnow - utcdatatime) # abs if delta >= 30.: @@ -36,130 +36,130 @@ def isRealtime(utcdatatime): return True class Figure(Operation): - + __driver = mpldriver fig = None - + id = None wintitle = None width = None height = None nplots = None timerange = None - + axesObjList = [] - + WIDTH = 300 HEIGHT = 200 PREFIX = 'fig' - + xmin = None xmax = None - + counter_imagwr = 0 - + figfile = None - + created = False - - def __init__(self): - - raise NotImplementedError - + parameters = {} + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + def __del__(self): - + self.__driver.closeFigure() - + def getFilename(self, name, ext='.png'): - + path = '%s%03d' %(self.PREFIX, self.id) filename = '%s_%s%s' %(self.PREFIX, name, ext) return os.path.join(path, filename) - + def getAxesObjList(self): - + return self.axesObjList - + def getSubplots(self): - + raise NotImplementedError - + def getScreenDim(self, widthplot, heightplot): - + nrow, ncol = self.getSubplots() - + widthscreen = widthplot*ncol heightscreen = heightplot*nrow - + return widthscreen, heightscreen - + def getTimeLim(self, x, xmin=None, xmax=None, timerange=None): - + # if self.xmin != None and self.xmax != None: # if timerange == None: # timerange = self.xmax - self.xmin # xmin = self.xmin + timerange # xmax = self.xmax + timerange -# +# # return xmin, xmax - + if timerange == None and (xmin==None or xmax==None): timerange = 14400 #seconds - + if timerange != None: txmin = x[0] #- x[0] % min(timerange/10, 10*60) else: txmin = x[0] #- x[0] % 10*60 - + thisdatetime = datetime.datetime.utcfromtimestamp(txmin) thisdate = datetime.datetime.combine(thisdatetime.date(), datetime.time(0,0,0)) - + if timerange != None: xmin = (thisdatetime - thisdate).seconds/(60*60.) xmax = xmin + timerange/(60*60.) - + d1970 = datetime.datetime(1970,1,1) - + mindt = thisdate + datetime.timedelta(hours=xmin) #- datetime.timedelta(seconds=time.timezone) xmin_sec = (mindt - d1970).total_seconds() #time.mktime(mindt.timetuple()) - time.timezone - + maxdt = thisdate + datetime.timedelta(hours=xmax) #- datetime.timedelta(seconds=time.timezone) xmax_sec = (maxdt - d1970).total_seconds() #time.mktime(maxdt.timetuple()) - time.timezone return xmin_sec, xmax_sec - + def init(self, id, nplots, wintitle): - + raise NotImplementedError, "This method has been replaced by createFigure" - + def createFigure(self, id, wintitle, widthplot=None, heightplot=None, show=True): - + """ Crea la figura de acuerdo al driver y parametros seleccionados seleccionados. Las dimensiones de la pantalla es calculada a partir de los atributos self.WIDTH y self.HEIGHT y el numero de subplots (nrow, ncol) - + Input: - id : Los parametros necesarios son - wintitle : - + id : Los parametros necesarios son + wintitle : + """ - + if widthplot == None: widthplot = self.WIDTH - + if heightplot == None: heightplot = self.HEIGHT - + self.id = id - + self.wintitle = wintitle - + self.widthscreen, self.heightscreen = self.getScreenDim(widthplot, heightplot) - + # if self.created: # self.__driver.closeFigure(self.fig) - + if not self.created: self.fig = self.__driver.createFigure(id=self.id, wintitle=self.wintitle, @@ -168,101 +168,101 @@ class Figure(Operation): show=show) else: self.__driver.clearFigure(self.fig) - + self.axesObjList = [] self.counter_imagwr = 0 self.created = True - + def setDriver(self, driver=mpldriver): - + self.__driver = driver - + def setTitle(self, title): - + self.__driver.setTitle(self.fig, title) - + def setWinTitle(self, title): - + self.__driver.setWinTitle(self.fig, title=title) - + def setTextFromAxes(self, text): - + raise NotImplementedError, "This method has been replaced with Axes.setText" - + def makeAxes(self, nrow, ncol, xpos, ypos, colspan, rowspan): - + raise NotImplementedError, "This method has been replaced with Axes.addAxes" - + def addAxes(self, *args): """ - + Input: *args : Los parametros necesarios son nrow, ncol, xpos, ypos, colspan, rowspan """ - + axesObj = Axes(self.fig, *args) self.axesObjList.append(axesObj) - + def saveFigure(self, figpath, figfile, *args): - + filename = os.path.join(figpath, figfile) - + fullpath = os.path.split(filename)[0] - + if not os.path.exists(fullpath): subpath = os.path.split(fullpath)[0] - + if not os.path.exists(subpath): os.mkdir(subpath) - + os.mkdir(fullpath) - + self.__driver.saveFigure(self.fig, filename, *args) - + def save(self, figpath, figfile=None, save=True, ftp=False, wr_period=1, thisDatetime=None, update_figfile=True): - + self.counter_imagwr += 1 if self.counter_imagwr < wr_period: return - + self.counter_imagwr = 0 - + if save: - + if not figfile: - + if not thisDatetime: raise ValueError, "Saving figure: figfile or thisDatetime should be defined" return - + str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") figfile = self.getFilename(name = str_datetime) - + if self.figfile == None: self.figfile = figfile - + if update_figfile: self.figfile = figfile - - # store png plot to local folder + + # store png plot to local folder self.saveFigure(figpath, self.figfile) - - + + if not ftp: return - + if not thisDatetime: return - - # store png plot to FTP server according to RT-Web format + + # store png plot to FTP server according to RT-Web format ftp_filename = self.getNameToFtp(thisDatetime, self.FTP_WEI, self.EXP_CODE, self.SUB_EXP_CODE, self.PLOT_CODE, self.PLOT_POS) # ftp_filename = os.path.join(figpath, name) - self.saveFigure(figpath, ftp_filename) - + self.saveFigure(figpath, ftp_filename) + def getNameToFtp(self, thisDatetime, FTP_WEI, EXP_CODE, SUB_EXP_CODE, PLOT_CODE, PLOT_POS): - YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year + YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year DOY_STR = '%3.3d'%thisDatetime.timetuple().tm_yday FTP_WEI = '%2.2d'%FTP_WEI EXP_CODE = '%3.3d'%EXP_CODE @@ -271,110 +271,110 @@ class Figure(Operation): PLOT_POS = '%2.2d'%PLOT_POS name = YEAR_STR + DOY_STR + FTP_WEI + EXP_CODE + SUB_EXP_CODE + PLOT_CODE + PLOT_POS return name - + def draw(self): - + self.__driver.draw(self.fig) - + def run(self): - + raise NotImplementedError - + def close(self, show=False): - + self.__driver.closeFigure(show=show, fig=self.fig) - + axesList = property(getAxesObjList) - + class Axes: - + __driver = mpldriver fig = None ax = None plot = None __missing = 1E30 __firsttime = None - + __showprofile = False - + xmin = None xmax = None ymin = None ymax = None zmin = None zmax = None - + x_buffer = None z_buffer = None - + decimationx = None decimationy = None - + __MAXNUMX = 200 __MAXNUMY = 400 - + __MAXNUMTIME = 500 - + def __init__(self, *args): - + """ - + Input: *args : Los parametros necesarios son fig, nrow, ncol, xpos, ypos, colspan, rowspan """ - + ax = self.__driver.createAxes(*args) self.fig = args[0] self.ax = ax self.plot = None - + self.__firsttime = True self.idlineList = [] - + self.x_buffer = numpy.array([]) self.z_buffer = numpy.array([]) - + def setText(self, text): - + self.__driver.setAxesText(self.ax, text) - + def setXAxisAsTime(self): pass - + def pline(self, x, y, xmin=None, xmax=None, ymin=None, ymax=None, xlabel='', ylabel='', title='', **kwargs): - + """ - + Input: - x : - y : + x : + y : xmin : xmax : ymin : - ymax : + ymax : xlabel : ylabel : title : **kwargs : Los parametros aceptados son - + ticksize ytick_visible """ - + if self.__firsttime: - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + self.plot = self.__driver.createPline(self.ax, x, y, xmin, xmax, ymin, ymax, @@ -386,39 +386,39 @@ class Axes: self.idlineList.append(0) self.__firsttime = False return - + self.__driver.pline(self.plot, x, y, xlabel=xlabel, ylabel=ylabel, title=title) # self.__driver.pause() - + def addpline(self, x, y, idline, **kwargs): lines = self.ax.lines - + if idline in self.idlineList: self.__driver.set_linedata(self.ax, x, y, idline) - + if idline not in(self.idlineList): self.__driver.addpline(self.ax, x, y, **kwargs) self.idlineList.append(idline) return - + def pmultiline(self, x, y, xmin=None, xmax=None, ymin=None, ymax=None, xlabel='', ylabel='', title='', **kwargs): - + if self.__firsttime: - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + self.plot = self.__driver.createPmultiline(self.ax, x, y, xmin, xmax, ymin, ymax, @@ -428,27 +428,27 @@ class Axes: **kwargs) self.__firsttime = False return - + self.__driver.pmultiline(self.plot, x, y, xlabel=xlabel, ylabel=ylabel, title=title) - + # self.__driver.pause() - + def pmultilineyaxis(self, x, y, xmin=None, xmax=None, ymin=None, ymax=None, xlabel='', ylabel='', title='', **kwargs): - + if self.__firsttime: - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + self.plot = self.__driver.createPmultilineYAxis(self.ax, x, y, xmin, xmax, ymin, ymax, @@ -460,16 +460,16 @@ class Axes: if self.xmax == None: self.xmax = xmax if self.ymin == None: self.ymin = ymin if self.ymax == None: self.ymax = ymax - + self.__firsttime = False return - + self.__driver.pmultilineyaxis(self.plot, x, y, xlabel=xlabel, ylabel=ylabel, title=title) - + # self.__driver.pause() - + def pcolor(self, x, y, z, xmin=None, xmax=None, ymin=None, ymax=None, @@ -477,11 +477,11 @@ class Axes: xlabel='', ylabel='', title='', colormap='jet', **kwargs): - + """ Input: - x : - y : + x : + y : x : xmin : xmax : @@ -496,30 +496,30 @@ class Axes: ticksize=9, cblabel='' """ - + #Decimating data xlen = len(x) ylen = len(y) - - decimationx = int(xlen/self.__MAXNUMX) + 1 + + decimationx = int(xlen/self.__MAXNUMX) + 1 decimationy = int(ylen/self.__MAXNUMY) + 1 - - + + x_buffer = x#[::decimationx] - y_buffer = y#[::decimationy] + y_buffer = y#[::decimationy] z_buffer = z#[::decimationx, ::decimationy] #=================================================== - + if self.__firsttime: - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) if zmin == None: zmin = numpy.nanmin(z) if zmax == None: zmax = numpy.nanmax(z) - - + + self.plot = self.__driver.createPcolor(self.ax, x_buffer, y_buffer, z_buffer, @@ -531,25 +531,25 @@ class Axes: title=title, colormap=colormap, **kwargs) - + if self.xmin == None: self.xmin = xmin if self.xmax == None: self.xmax = xmax if self.ymin == None: self.ymin = ymin if self.ymax == None: self.ymax = ymax if self.zmin == None: self.zmin = zmin if self.zmax == None: self.zmax = zmax - + self.__firsttime = False return - + self.__driver.pcolor(self.plot, z_buffer, xlabel=xlabel, ylabel=ylabel, title=title) - + # self.__driver.pause() - + def pcolorbuffer(self, x, y, z, xmin=None, xmax=None, ymin=None, ymax=None, @@ -558,24 +558,24 @@ class Axes: title='', rti = True, colormap='jet', maxNumX = None, maxNumY = None, **kwargs): - + if maxNumX == None: maxNumX = self.__MAXNUMTIME - + if maxNumY == None: - maxNumY = self.__MAXNUMY - - if self.__firsttime: + maxNumY = self.__MAXNUMY + + if self.__firsttime: self.z_buffer = z self.x_buffer = numpy.hstack((self.x_buffer, x)) - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) if zmin == None: zmin = numpy.nanmin(z) if zmax == None: zmax = numpy.nanmax(z) - + self.plot = self.__driver.createPcolor(self.ax, self.x_buffer, y, z, xmin, xmax, ymin, ymax, @@ -585,77 +585,73 @@ class Axes: title=title, colormap=colormap, **kwargs) - + if self.xmin == None: self.xmin = xmin if self.xmax == None: self.xmax = xmax if self.ymin == None: self.ymin = ymin if self.ymax == None: self.ymax = ymax if self.zmin == None: self.zmin = zmin if self.zmax == None: self.zmax = zmax - + self.__firsttime = False return - + self.x_buffer = numpy.hstack((self.x_buffer[:-1], x[0], x[-1])) self.z_buffer = numpy.hstack((self.z_buffer, z)) z_buffer = self.z_buffer.reshape(-1,len(y)) - + #Decimating data xlen = len(self.x_buffer) ylen = len(y) - + decimationx = int(xlen/maxNumX) + 1 decimationy = int(ylen/maxNumY) + 1 - + x_buffer = self.x_buffer#[::decimationx] - y_buffer = y#[::decimationy] + y_buffer = y#[::decimationy] z_buffer = z_buffer#[::decimationx, ::decimationy] #=================================================== - + x_buffer, y_buffer, z_buffer = self.__fillGaps(x_buffer, y_buffer, z_buffer) - + self.__driver.addpcolorbuffer(self.ax, x_buffer, y_buffer, z_buffer, self.zmin, self.zmax, xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap) - + # self.__driver.pause() - + def polar(self, x, y, title='', xlabel='',ylabel='',**kwargs): - + if self.__firsttime: self.plot = self.__driver.createPolar(self.ax, x, y, title = title, xlabel = xlabel, ylabel = ylabel) self.__firsttime = False self.x_buffer = x self.y_buffer = y return - + self.x_buffer = numpy.hstack((self.x_buffer,x)) self.y_buffer = numpy.hstack((self.y_buffer,y)) self.__driver.polar(self.plot, self.x_buffer, self.y_buffer, xlabel=xlabel, ylabel=ylabel, title=title) - + # self.__driver.pause() - + def __fillGaps(self, x_buffer, y_buffer, z_buffer): - + if x_buffer.shape[0] < 2: return x_buffer, y_buffer, z_buffer - + deltas = x_buffer[1:] - x_buffer[0:-1] x_median = numpy.median(deltas) - + index = numpy.where(deltas > 5*x_median) - + if len(index[0]) != 0: z_buffer[index[0],::] = self.__missing z_buffer = numpy.ma.masked_inside(z_buffer,0.99*self.__missing,1.01*self.__missing) return x_buffer, y_buffer, z_buffer - - - - \ No newline at end of file diff --git a/schainpy/model/graphics/jroplot_correlation.py b/schainpy/model/graphics/jroplot_correlation.py index 9f12d54..759f8c6 100644 --- a/schainpy/model/graphics/jroplot_correlation.py +++ b/schainpy/model/graphics/jroplot_correlation.py @@ -2,85 +2,84 @@ import os import datetime import numpy import copy - +from schainpy.model import * from figure import Figure, isRealtime class CorrelationPlot(Figure): - isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'corr' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 280 self.HEIGHT = 250 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = 1 self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - + def getSubplots(self): - + ncol = int(numpy.sqrt(self.nplots)+0.9) nrow = int(self.nplots*1./ncol + 0.9) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=False, show=True): - - showprofile = False + + showprofile = False self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 if showprofile: ncolspan = 3 colspan = 2 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + if showprofile: self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False): - + """ - + Input: dataOut : id : @@ -94,15 +93,15 @@ class CorrelationPlot(Figure): zmin : None, zmax : None """ - + if dataOut.flagNoData: return None - + if realtime: if not(isRealtime(utcdatatime = dataOut.utctime)): print 'Skipping this plot function' return - + if channelList == None: channelIndexList = dataOut.channelIndexList else: @@ -111,53 +110,53 @@ class CorrelationPlot(Figure): if channel not in dataOut.channelList: raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - + factor = dataOut.normFactor lenfactor = factor.shape[1] x = dataOut.getLagTRange(1) y = dataOut.getHeiRange() - + z = copy.copy(dataOut.data_corr[:,:,0,:]) for i in range(dataOut.data_corr.shape[0]): - z[i,:,:] = z[i,:,:]/factor[i,:] + z[i,:,:] = z[i,:,:]/factor[i,:] zdB = numpy.abs(z) - + avg = numpy.average(z, axis=1) # avg = numpy.nanmean(z, axis=1) # noise = dataOut.noise/factor - + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) - title = wintitle + " Correlation" + title = wintitle + " Correlation" xlabel = "Lag T (s)" ylabel = "Range (Km)" - + if not self.isConfig: - - nplots = dataOut.data_corr.shape[0] - + + nplots = dataOut.data_corr.shape[0] + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) if zmin == None: zmin = 0 if zmax == None: zmax = 1 - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.isConfig = True - + self.setWinTitle(title) - + for i in range(self.nplots): str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) title = "Channel %d and %d: : %s" %(dataOut.pairsList[i][0],dataOut.pairsList[i][1] , str_datetime) @@ -166,7 +165,7 @@ class CorrelationPlot(Figure): xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax, xlabel=xlabel, ylabel=ylabel, title=title, ticksize=9, cblabel='') - + # if self.__showprofile: # axes = self.axesList[i*self.__nsubplots +1] # axes.pline(avgdB[i], y, @@ -174,15 +173,15 @@ class CorrelationPlot(Figure): # xlabel='dB', ylabel='', title='', # ytick_visible=False, # grid='x') -# +# # noiseline = numpy.repeat(noisedB[i], len(y)) # axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2) - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, ftp=ftp, wr_period=wr_period, - thisDatetime=thisDatetime) + thisDatetime=thisDatetime) diff --git a/schainpy/model/graphics/jroplot_data.py b/schainpy/model/graphics/jroplot_data.py index 3191d1d..6253a0a 100644 --- a/schainpy/model/graphics/jroplot_data.py +++ b/schainpy/model/graphics/jroplot_data.py @@ -1,259 +1,1148 @@ import os import time -import numpy +import glob import datetime -import numpy as np +from multiprocessing import Process + +import zmq +import numpy +import matplotlib import matplotlib.pyplot as plt +from matplotlib.patches import Polygon from mpl_toolkits.axes_grid1 import make_axes_locatable -from matplotlib.ticker import FuncFormatter, LinearLocator +from matplotlib.ticker import FuncFormatter, LinearLocator, MultipleLocator from schainpy.model.proc.jroproc_base import Operation +from schainpy.utils import log -func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime('%H:%M')) +jet_values = matplotlib.pyplot.get_cmap('jet', 100)(numpy.arange(100))[10:90] +blu_values = matplotlib.pyplot.get_cmap( + 'seismic_r', 20)(numpy.arange(20))[10:15] +ncmap = matplotlib.colors.LinearSegmentedColormap.from_list( + 'jro', numpy.vstack((blu_values, jet_values))) +matplotlib.pyplot.register_cmap(cmap=ncmap) -d1970 = datetime.datetime(1970,1,1) +CMAPS = [plt.get_cmap(s) for s in ('jro', 'jet', 'viridis', 'plasma', 'inferno', 'Greys', 'seismic', 'bwr', 'coolwarm')] +EARTH_RADIUS = 6.3710e3 -class PlotData(Operation): +def ll2xy(lat1, lon1, lat2, lon2): - __code = 'Figure' - __MAXNUMX = 80 - __MAXNUMY = 80 - __missing = 1E30 + p = 0.017453292519943295 + a = 0.5 - numpy.cos((lat2 - lat1) * p)/2 + numpy.cos(lat1 * p) * numpy.cos(lat2 * p) * (1 - numpy.cos((lon2 - lon1) * p)) / 2 + r = 12742 * numpy.arcsin(numpy.sqrt(a)) + theta = numpy.arctan2(numpy.sin((lon2-lon1)*p)*numpy.cos(lat2*p), numpy.cos(lat1*p)*numpy.sin(lat2*p)-numpy.sin(lat1*p)*numpy.cos(lat2*p)*numpy.cos((lon2-lon1)*p)) + theta = -theta + numpy.pi/2 + return r*numpy.cos(theta), r*numpy.sin(theta) - def __init__(self): +def km2deg(km): + ''' + Convert distance in km to degrees + ''' - Operation.__init__(self) - self.xmin = None - self.xmax = None - self.newdataOut = None - self.dataOut = None - self.isConfig = False - self.figure = None - self.width = 6 - self.height = 4 + return numpy.rad2deg(km/EARTH_RADIUS) + +def figpause(interval): + backend = plt.rcParams['backend'] + if backend in matplotlib.rcsetup.interactive_bk: + figManager = matplotlib._pylab_helpers.Gcf.get_active() + if figManager is not None: + canvas = figManager.canvas + if canvas.figure.stale: + canvas.draw() + try: + canvas.start_event_loop(interval) + except: + pass + return + +def popup(message): + ''' + ''' + + fig = plt.figure(figsize=(12, 8), facecolor='r') + text = '\n'.join([s.strip() for s in message.split(':')]) + fig.text(0.01, 0.5, text, ha='left', va='center', size='20', weight='heavy', color='w') + fig.show() + figpause(1000) + + +class PlotData(Operation, Process): + ''' + Base class for Schain plotting operations + ''' + + CODE = 'Figure' + colormap = 'jro' + bgcolor = 'white' + CONFLATE = False + __missing = 1E30 + + __attrs__ = ['show', 'save', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax', + 'zlimits', 'xlabel', 'ylabel', 'xaxis','cb_label', 'title', + 'colorbar', 'bgcolor', 'width', 'height', 'localtime', 'oneFigure', + 'showprofile', 'decimation', 'ftp'] - def setup(self, dataOut, **kwargs): + def __init__(self, **kwargs): - self.first = True + Operation.__init__(self, plot=True, **kwargs) + Process.__init__(self) + + self.kwargs['code'] = self.CODE + self.mp = False + self.data = None + self.isConfig = False + self.figures = [] + self.axes = [] + self.cb_axes = [] self.localtime = kwargs.pop('localtime', True) - self.show = kwargs.pop('show', True) - self.save = kwargs.pop('save', False) - self.pause = kwargs.pop('pause', False) - self.time = [] - self.nblock = 0 - self.z = [] - self.data = [{} for __ in dataOut.channelList] - self.axes = [] - self.colormap = kwargs.get('colormap', 'jet') - self.title = kwargs.get('wintitle', '') - self.xaxis = kwargs.get('xaxis', None) + self.show = kwargs.get('show', True) + self.save = kwargs.get('save', False) + self.ftp = kwargs.get('ftp', False) + self.colormap = kwargs.get('colormap', self.colormap) + self.colormap_coh = kwargs.get('colormap_coh', 'jet') + self.colormap_phase = kwargs.get('colormap_phase', 'RdBu_r') + self.colormaps = kwargs.get('colormaps', None) + self.bgcolor = kwargs.get('bgcolor', self.bgcolor) + self.showprofile = kwargs.get('showprofile', False) + self.title = kwargs.get('wintitle', self.CODE.upper()) + self.cb_label = kwargs.get('cb_label', None) + self.cb_labels = kwargs.get('cb_labels', None) + self.labels = kwargs.get('labels', None) + self.xaxis = kwargs.get('xaxis', 'frequency') self.zmin = kwargs.get('zmin', None) self.zmax = kwargs.get('zmax', None) + self.zlimits = kwargs.get('zlimits', None) + self.xmin = kwargs.get('xmin', None) + self.xmax = kwargs.get('xmax', None) + self.xrange = kwargs.get('xrange', 24) + self.xscale = kwargs.get('xscale', None) + self.ymin = kwargs.get('ymin', None) + self.ymax = kwargs.get('ymax', None) + self.yscale = kwargs.get('yscale', None) + self.xlabel = kwargs.get('xlabel', None) + self.decimation = kwargs.get('decimation', None) + self.showSNR = kwargs.get('showSNR', False) + self.oneFigure = kwargs.get('oneFigure', True) + self.width = kwargs.get('width', None) + self.height = kwargs.get('height', None) + self.colorbar = kwargs.get('colorbar', True) + self.factors = kwargs.get('factors', [1, 1, 1, 1, 1, 1, 1, 1]) + self.channels = kwargs.get('channels', None) + self.titles = kwargs.get('titles', []) + self.polar = False + self.grid = kwargs.get('grid', False) - xmin = kwargs.get('xmin', 0) - xmax = kwargs.get('xmax', xmin+4) + def __fmtTime(self, x, pos): + ''' + ''' - dt = dataOut.datatime.date() - dtmin = datetime.datetime.combine(dt, datetime.time(xmin, 0, 0)) - dtmax = datetime.datetime.combine(dt, datetime.time(xmax, 59, 59)) + return '{}'.format(self.getDateTime(x).strftime('%H:%M')) - self.xmin = (dtmin-d1970).total_seconds() - self.xmax = (dtmax-d1970).total_seconds() + def __setup(self): + ''' + Common setup for all figures, here figures and axes are created + ''' - self.ymin = kwargs.get('ymin', None) - self.ymax = kwargs.get('ymax', None) + if self.CODE not in self.data: + raise ValueError(log.error('Missing data for {}'.format(self.CODE), + self.name)) + + self.setup() - if self.figure is None: - self.figure = plt.figure() + self.time_label = 'LT' if self.localtime else 'UTC' + if self.data.localtime: + self.getDateTime = datetime.datetime.fromtimestamp else: - self.figure.clf() + self.getDateTime = datetime.datetime.utcfromtimestamp - self.setup_fig() - - for n in range(dataOut.nChannels): - ax = self.figure.add_subplot(self.nrows, self.ncols, n+1) - ax.firsttime = True - self.axes.append(ax) + if self.width is None: + self.width = 8 - self.setup_fig() + self.figures = [] + self.axes = [] + self.cb_axes = [] + self.pf_axes = [] + self.cmaps = [] - self.figure.set_size_inches (self.width, self.height) + size = '15%' if self.ncols == 1 else '30%' + pad = '4%' if self.ncols == 1 else '8%' - def fill_gaps(self, x_buffer, y_buffer, z_buffer): + if self.oneFigure: + if self.height is None: + self.height = 1.4 * self.nrows + 1 + fig = plt.figure(figsize=(self.width, self.height), + edgecolor='k', + facecolor='w') + self.figures.append(fig) + for n in range(self.nplots): + ax = fig.add_subplot(self.nrows, self.ncols, + n + 1, polar=self.polar) + ax.tick_params(labelsize=8) + ax.firsttime = True + ax.index = 0 + ax.press = None + self.axes.append(ax) + if self.showprofile: + cax = self.__add_axes(ax, size=size, pad=pad) + cax.tick_params(labelsize=8) + self.pf_axes.append(cax) + else: + if self.height is None: + self.height = 3 + for n in range(self.nplots): + fig = plt.figure(figsize=(self.width, self.height), + edgecolor='k', + facecolor='w') + ax = fig.add_subplot(1, 1, 1, polar=self.polar) + ax.tick_params(labelsize=8) + ax.firsttime = True + ax.index = 0 + ax.press = None + self.figures.append(fig) + self.axes.append(ax) + if self.showprofile: + cax = self.__add_axes(ax, size=size, pad=pad) + cax.tick_params(labelsize=8) + self.pf_axes.append(cax) + + for n in range(self.nrows): + if self.colormaps is not None: + cmap = plt.get_cmap(self.colormaps[n]) + else: + cmap = plt.get_cmap(self.colormap) + cmap.set_bad(self.bgcolor, 1.) + self.cmaps.append(cmap) + + for fig in self.figures: + fig.canvas.mpl_connect('key_press_event', self.OnKeyPress) + fig.canvas.mpl_connect('scroll_event', self.OnBtnScroll) + fig.canvas.mpl_connect('button_press_event', self.onBtnPress) + fig.canvas.mpl_connect('motion_notify_event', self.onMotion) + fig.canvas.mpl_connect('button_release_event', self.onBtnRelease) + if self.show: + fig.show() + + def OnKeyPress(self, event): + ''' + Event for pressing keys (up, down) change colormap + ''' + ax = event.inaxes + if ax in self.axes: + if event.key == 'down': + ax.index += 1 + elif event.key == 'up': + ax.index -= 1 + if ax.index < 0: + ax.index = len(CMAPS) - 1 + elif ax.index == len(CMAPS): + ax.index = 0 + cmap = CMAPS[ax.index] + ax.cbar.set_cmap(cmap) + ax.cbar.draw_all() + ax.plt.set_cmap(cmap) + ax.cbar.patch.figure.canvas.draw() + self.colormap = cmap.name + def OnBtnScroll(self, event): + ''' + Event for scrolling, scale figure + ''' + cb_ax = event.inaxes + if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]: + ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0] + pt = ax.cbar.ax.bbox.get_points()[:, 1] + nrm = ax.cbar.norm + vmin, vmax, p0, p1, pS = ( + nrm.vmin, nrm.vmax, pt[0], pt[1], event.y) + scale = 2 if event.step == 1 else 0.5 + point = vmin + (vmax - vmin) / (p1 - p0) * (pS - p0) + ax.cbar.norm.vmin = point - scale * (point - vmin) + ax.cbar.norm.vmax = point - scale * (point - vmax) + ax.plt.set_norm(ax.cbar.norm) + ax.cbar.draw_all() + ax.cbar.patch.figure.canvas.draw() + + def onBtnPress(self, event): + ''' + Event for mouse button press + ''' + cb_ax = event.inaxes + if cb_ax is None: + return + + if cb_ax in [ax.cbar.ax for ax in self.axes if ax.cbar]: + cb_ax.press = event.x, event.y + else: + cb_ax.press = None + + def onMotion(self, event): + ''' + Event for move inside colorbar + ''' + cb_ax = event.inaxes + if cb_ax is None: + return + if cb_ax not in [ax.cbar.ax for ax in self.axes if ax.cbar]: + return + if cb_ax.press is None: + return + + ax = [ax for ax in self.axes if cb_ax == ax.cbar.ax][0] + xprev, yprev = cb_ax.press + dx = event.x - xprev + dy = event.y - yprev + cb_ax.press = event.x, event.y + scale = ax.cbar.norm.vmax - ax.cbar.norm.vmin + perc = 0.03 + + if event.button == 1: + ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy) + ax.cbar.norm.vmax -= (perc * scale) * numpy.sign(dy) + elif event.button == 3: + ax.cbar.norm.vmin -= (perc * scale) * numpy.sign(dy) + ax.cbar.norm.vmax += (perc * scale) * numpy.sign(dy) + + ax.cbar.draw_all() + ax.plt.set_norm(ax.cbar.norm) + ax.cbar.patch.figure.canvas.draw() + + def onBtnRelease(self, event): + ''' + Event for mouse button release + ''' + cb_ax = event.inaxes + if cb_ax is not None: + cb_ax.press = None + + def __add_axes(self, ax, size='30%', pad='8%'): + ''' + Add new axes to the given figure + ''' + divider = make_axes_locatable(ax) + nax = divider.new_horizontal(size=size, pad=pad) + ax.figure.add_axes(nax) + return nax + + self.setup() + + def setup(self): + ''' + This method should be implemented in the child class, the following + attributes should be set: + + self.nrows: number of rows + self.ncols: number of cols + self.nplots: number of plots (channels or pairs) + self.ylabel: label for Y axes + self.titles: list of axes title + + ''' + raise(NotImplementedError, 'Implement this method in child class') + + def fill_gaps(self, x_buffer, y_buffer, z_buffer): + ''' + Create a masked array for missing data + ''' if x_buffer.shape[0] < 2: return x_buffer, y_buffer, z_buffer deltas = x_buffer[1:] - x_buffer[0:-1] - x_median = np.median(deltas) + x_median = numpy.median(deltas) - index = np.where(deltas > 5*x_median) + index = numpy.where(deltas > 5 * x_median) if len(index[0]) != 0: - z_buffer[::,index[0],::] = self.__missing - z_buffer = np.ma.masked_inside(z_buffer, - 0.99*self.__missing, - 1.01*self.__missing) + z_buffer[::, index[0], ::] = self.__missing + z_buffer = numpy.ma.masked_inside(z_buffer, + 0.99 * self.__missing, + 1.01 * self.__missing) return x_buffer, y_buffer, z_buffer def decimate(self): - - dx = int(len(self.x)/self.__MAXNUMX) + 1 - dy = int(len(self.y)/self.__MAXNUMY) + 1 - - x = self.x[::dx] - y = self.y[::dy] - z = self.z[::, ::dx, ::dy] - + + # dx = int(len(self.x)/self.__MAXNUMX) + 1 + dy = int(len(self.y) / self.decimation) + 1 + + # x = self.x[::dx] + x = self.x + y = self.y[::dy] + z = self.z[::, ::, ::dy] + return x, y, z - def _plot(self): + def format(self): + ''' + Set min and max values, labels, ticks and titles + ''' - self.plot() - - self.figure.suptitle(self.title+self.__code) - - if self.save: - figname = os.path.join(self.save, '{}_{}.png'.format(self.__code, - self.plot_dt.strftime('%y%m%d_%H%M%S'))) - print 'Saving figure: {}'.format(figname) - self.figure.savefig(figname) - - self.figure.canvas.draw() - if self.show: - self.figure.show() - if self.pause: - raw_input('Press to continue') + if self.xmin is None: + xmin = self.min_time + else: + if self.xaxis is 'time': + dt = self.getDateTime(self.min_time) + xmin = (dt.replace(hour=int(self.xmin), minute=0, second=0) - + datetime.datetime(1970, 1, 1)).total_seconds() + if self.data.localtime: + xmin += time.timezone + else: + xmin = self.xmin - - def update(self): + if self.xmax is None: + xmax = xmin + self.xrange * 60 * 60 + else: + if self.xaxis is 'time': + dt = self.getDateTime(self.max_time) + xmax = (dt.replace(hour=int(self.xmax), minute=59, second=59) - + datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=1)).total_seconds() + if self.data.localtime: + xmax += time.timezone + else: + xmax = self.xmax - pass + ymin = self.ymin if self.ymin else numpy.nanmin(self.y) + ymax = self.ymax if self.ymax else numpy.nanmax(self.y) - def run(self, dataOut, **kwargs): + Y = numpy.array([1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]) + i = 1 if numpy.where(abs(ymax-ymin) <= Y)[0][0] < 0 else numpy.where(abs(ymax-ymin) <= Y)[0][0] + ystep = Y[i] / 10. - self.dataOut = dataOut + for n, ax in enumerate(self.axes): + if ax.firsttime: + ax.set_facecolor(self.bgcolor) + ax.yaxis.set_major_locator(MultipleLocator(ystep)) + ax.xaxis.set_major_locator(MultipleLocator(ystep)) + if self.xscale: + ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{0:g}'.format(x*self.xscale))) + if self.xscale: + ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{0:g}'.format(x*self.yscale))) + if self.xaxis is 'time': + ax.xaxis.set_major_formatter(FuncFormatter(self.__fmtTime)) + ax.xaxis.set_major_locator(LinearLocator(9)) + if self.xlabel is not None: + ax.set_xlabel(self.xlabel) + ax.set_ylabel(self.ylabel) + ax.firsttime = False + if self.showprofile: + self.pf_axes[n].set_ylim(ymin, ymax) + self.pf_axes[n].set_xlim(self.zmin, self.zmax) + self.pf_axes[n].set_xlabel('dB') + self.pf_axes[n].grid(b=True, axis='x') + [tick.set_visible(False) + for tick in self.pf_axes[n].get_yticklabels()] + if self.colorbar: + ax.cbar = plt.colorbar( + ax.plt, ax=ax, fraction=0.05, pad=0.02, aspect=10) + ax.cbar.ax.tick_params(labelsize=8) + ax.cbar.ax.press = None + if self.cb_label: + ax.cbar.set_label(self.cb_label, size=8) + elif self.cb_labels: + ax.cbar.set_label(self.cb_labels[n], size=8) + else: + ax.cbar = None + if self.grid: + ax.grid(True) - if not self.isConfig: - self.setup(dataOut, **kwargs) - self.isConfig = True + if not self.polar: + ax.set_xlim(xmin, xmax) + ax.set_ylim(ymin, ymax) + ax.set_title('{} {} {}'.format( + self.titles[n], + self.getDateTime(self.max_time).strftime('%Y-%m-%dT%H:%M:%S'), + self.time_label), + size=8) + else: + ax.set_title('{}'.format(self.titles[n]), size=8) + ax.set_ylim(0, 90) + ax.set_yticks(numpy.arange(0, 90, 20)) + ax.yaxis.labelpad = 40 - self.nblock += 1 - self.update() - - if dataOut.ltctime>=self.xmax: - self._plot() - self.isConfig = False + def __plot(self): + ''' + ''' + log.log('Plotting', self.name) + + try: + self.plot() + self.format() + except Exception as e: + log.warning('{} Plot could not be updated... check data'.format(self.CODE), self.name) + log.error(str(e), '') + return + + for n, fig in enumerate(self.figures): + if self.nrows == 0 or self.nplots == 0: + log.warning('No data', self.name) + fig.text(0.5, 0.5, 'No Data', fontsize='large', ha='center') + fig.canvas.manager.set_window_title(self.CODE) + continue + + fig.tight_layout() + fig.canvas.manager.set_window_title('{} - {}'.format(self.title, + self.getDateTime(self.max_time).strftime('%Y/%m/%d'))) + fig.canvas.draw() + + if self.save and (self.data.ended or not self.data.buffering): + + if self.save_labels: + labels = self.save_labels + else: + labels = range(self.nrows) + + if self.oneFigure: + label = '' + else: + label = '-{}'.format(labels[n]) + figname = os.path.join( + self.save, + self.CODE, + '{}{}_{}.png'.format( + self.CODE, + label, + self.getDateTime(self.saveTime).strftime( + '%Y%m%d_%H%M%S'), + ) + ) + log.log('Saving figure: {}'.format(figname), self.name) + if not os.path.isdir(os.path.dirname(figname)): + os.makedirs(os.path.dirname(figname)) + fig.savefig(figname) + + def plot(self): + ''' + ''' + raise(NotImplementedError, 'Implement this method in child class') + + def run(self): + + log.log('Starting', self.name) + + context = zmq.Context() + receiver = context.socket(zmq.SUB) + receiver.setsockopt(zmq.SUBSCRIBE, '') + receiver.setsockopt(zmq.CONFLATE, self.CONFLATE) + + if 'server' in self.kwargs['parent']: + receiver.connect( + 'ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server'])) + else: + receiver.connect("ipc:///tmp/zmq.plots") + + while True: + try: + self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK) + if self.data.localtime and self.localtime: + self.times = self.data.times + elif self.data.localtime and not self.localtime: + self.times = self.data.times + time.timezone + elif not self.data.localtime and self.localtime: + self.times = self.data.times - time.timezone + else: + self.times = self.data.times + + self.min_time = self.times[0] + self.max_time = self.times[-1] + + if self.isConfig is False: + self.__setup() + self.isConfig = True + + self.__plot() + + except zmq.Again as e: + if self.data and self.data.ended: + break + log.log('Waiting for data...') + if self.data: + figpause(self.data.throttle) + else: + time.sleep(2) def close(self): - if self.dataOut: - self._plot() - + if self.data: + self.__plot() + class PlotSpectraData(PlotData): - - __code = 'Spectra' + ''' + Plot for Spectra data + ''' - def setup_fig(self): - pass + CODE = 'spc' + colormap = 'jro' + + def setup(self): + self.nplots = len(self.data.channels) + self.ncols = int(numpy.sqrt(self.nplots) + 0.9) + self.nrows = int((1.0 * self.nplots / self.ncols) + 0.9) + self.width = 3.4 * self.ncols + self.height = 3 * self.nrows + self.cb_label = 'dB' + if self.showprofile: + self.width += 0.8 * self.ncols + + self.ylabel = 'Range [km]' - def update(self): - - for ch in self.dataOut.channelList: - self.data[ch] = self.dataOut.data_spc[ch] - def plot(self): - pass + if self.xaxis == "frequency": + x = self.data.xrange[0] + self.xlabel = "Frequency (kHz)" + elif self.xaxis == "time": + x = self.data.xrange[1] + self.xlabel = "Time (ms)" + else: + x = self.data.xrange[2] + self.xlabel = "Velocity (m/s)" + + if self.CODE == 'spc_mean': + x = self.data.xrange[2] + self.xlabel = "Velocity (m/s)" + + self.titles = [] + + y = self.data.heights + self.y = y + z = self.data['spc'] + + for n, ax in enumerate(self.axes): + noise = self.data['noise'][n][-1] + if self.CODE == 'spc_mean': + mean = self.data['mean'][n][-1] + if ax.firsttime: + self.xmax = self.xmax if self.xmax else numpy.nanmax(x) + self.xmin = self.xmin if self.xmin else -self.xmax + self.zmin = self.zmin if self.zmin else numpy.nanmin(z) + self.zmax = self.zmax if self.zmax else numpy.nanmax(z) + ax.plt = ax.pcolormesh(x, y, z[n].T, + vmin=self.zmin, + vmax=self.zmax, + cmap=plt.get_cmap(self.colormap) + ) + + if self.showprofile: + ax.plt_profile = self.pf_axes[n].plot( + self.data['rti'][n][-1], y)[0] + ax.plt_noise = self.pf_axes[n].plot(numpy.repeat(noise, len(y)), y, + color="k", linestyle="dashed", lw=1)[0] + if self.CODE == 'spc_mean': + ax.plt_mean = ax.plot(mean, y, color='k')[0] + else: + ax.plt.set_array(z[n].T.ravel()) + if self.showprofile: + ax.plt_profile.set_data(self.data['rti'][n][-1], y) + ax.plt_noise.set_data(numpy.repeat(noise, len(y)), y) + if self.CODE == 'spc_mean': + ax.plt_mean.set_data(mean, y) + + self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) + self.saveTime = self.max_time + + +class PlotCrossSpectraData(PlotData): + + CODE = 'cspc' + zmin_coh = None + zmax_coh = None + zmin_phase = None + zmax_phase = None + + def setup(self): + + self.ncols = 4 + self.nrows = len(self.data.pairs) + self.nplots = self.nrows * 4 + self.width = 3.4 * self.ncols + self.height = 3 * self.nrows + self.ylabel = 'Range [km]' + self.showprofile = False + + def plot(self): + + if self.xaxis == "frequency": + x = self.data.xrange[0] + self.xlabel = "Frequency (kHz)" + elif self.xaxis == "time": + x = self.data.xrange[1] + self.xlabel = "Time (ms)" + else: + x = self.data.xrange[2] + self.xlabel = "Velocity (m/s)" + + self.titles = [] + + y = self.data.heights + self.y = y + spc = self.data['spc'] + cspc = self.data['cspc'] + + for n in range(self.nrows): + noise = self.data['noise'][n][-1] + pair = self.data.pairs[n] + ax = self.axes[4 * n] + ax3 = self.axes[4 * n + 3] + if ax.firsttime: + self.xmax = self.xmax if self.xmax else numpy.nanmax(x) + self.xmin = self.xmin if self.xmin else -self.xmax + self.zmin = self.zmin if self.zmin else numpy.nanmin(spc) + self.zmax = self.zmax if self.zmax else numpy.nanmax(spc) + ax.plt = ax.pcolormesh(x, y, spc[pair[0]].T, + vmin=self.zmin, + vmax=self.zmax, + cmap=plt.get_cmap(self.colormap) + ) + else: + ax.plt.set_array(spc[pair[0]].T.ravel()) + self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) + + ax = self.axes[4 * n + 1] + if ax.firsttime: + ax.plt = ax.pcolormesh(x, y, spc[pair[1]].T, + vmin=self.zmin, + vmax=self.zmax, + cmap=plt.get_cmap(self.colormap) + ) + else: + ax.plt.set_array(spc[pair[1]].T.ravel()) + self.titles.append('CH {}: {:3.2f}dB'.format(n, noise)) + + out = cspc[n] / numpy.sqrt(spc[pair[0]] * spc[pair[1]]) + coh = numpy.abs(out) + phase = numpy.arctan2(out.imag, out.real) * 180 / numpy.pi + + ax = self.axes[4 * n + 2] + if ax.firsttime: + ax.plt = ax.pcolormesh(x, y, coh.T, + vmin=0, + vmax=1, + cmap=plt.get_cmap(self.colormap_coh) + ) + else: + ax.plt.set_array(coh.T.ravel()) + self.titles.append( + 'Coherence Ch{} * Ch{}'.format(pair[0], pair[1])) + + ax = self.axes[4 * n + 3] + if ax.firsttime: + ax.plt = ax.pcolormesh(x, y, phase.T, + vmin=-180, + vmax=180, + cmap=plt.get_cmap(self.colormap_phase) + ) + else: + ax.plt.set_array(phase.T.ravel()) + self.titles.append('Phase CH{} * CH{}'.format(pair[0], pair[1])) + + self.saveTime = self.max_time + + +class PlotSpectraMeanData(PlotSpectraData): + ''' + Plot for Spectra and Mean + ''' + CODE = 'spc_mean' + colormap = 'jro' class PlotRTIData(PlotData): - - __code = 'RTI' - - def setup_fig(self): - + ''' + Plot for RTI data + ''' + + CODE = 'rti' + colormap = 'jro' + + def setup(self): + self.xaxis = 'time' self.ncols = 1 - self.nrows = self.dataOut.nChannels - self.width = 8 - self.height = 2.2*self.nrows - self.ylabel = 'Range [Km]' - - def update(self): - - self.time.append(self.dataOut.ltctime) - - for ch in self.dataOut.channelList: - self.data[ch][self.dataOut.ltctime] = self.dataOut.getPower()[ch] - + self.nrows = len(self.data.channels) + self.nplots = len(self.data.channels) + self.ylabel = 'Range [km]' + self.cb_label = 'dB' + self.titles = ['{} Channel {}'.format( + self.CODE.upper(), x) for x in range(self.nrows)] + def plot(self): - - self.plot_dt = datetime.datetime.utcfromtimestamp(self.time[-2]) + self.x = self.times + self.y = self.data.heights + self.z = self.data[self.CODE] + self.z = numpy.ma.masked_invalid(self.z) - self.time.sort() - self.x = self.time - self.y = self.dataOut.getHeiRange() - self.z = [] - - for ch in self.dataOut.channelList: - self.z.append([self.data[ch][t] for t in self.time]) - - self.x = np.array(self.x) - self.z = np.array(self.z) + if self.decimation is None: + x, y, z = self.fill_gaps(self.x, self.y, self.z) + else: + x, y, z = self.fill_gaps(*self.decimate()) for n, ax in enumerate(self.axes): - - if self.xaxis=='time': - ax.xaxis.set_major_formatter(FuncFormatter(func)) - ax.xaxis.set_major_locator(LinearLocator(6)) + self.zmin = self.zmin if self.zmin else numpy.min(self.z) + self.zmax = self.zmax if self.zmax else numpy.max(self.z) + if ax.firsttime: + ax.plt = ax.pcolormesh(x, y, z[n].T, + vmin=self.zmin, + vmax=self.zmax, + cmap=plt.get_cmap(self.colormap) + ) + if self.showprofile: + ax.plot_profile = self.pf_axes[n].plot( + self.data['rti'][n][-1], self.y)[0] + ax.plot_noise = self.pf_axes[n].plot(numpy.repeat(self.data['noise'][n][-1], len(self.y)), self.y, + color="k", linestyle="dashed", lw=1)[0] + else: + ax.collections.remove(ax.collections[0]) + ax.plt = ax.pcolormesh(x, y, z[n].T, + vmin=self.zmin, + vmax=self.zmax, + cmap=plt.get_cmap(self.colormap) + ) + if self.showprofile: + ax.plot_profile.set_data(self.data['rti'][n][-1], self.y) + ax.plot_noise.set_data(numpy.repeat( + self.data['noise'][n][-1], len(self.y)), self.y) - ax.yaxis.set_major_locator(LinearLocator(4)) + self.saveTime = self.min_time - ax.set_ylabel(self.ylabel) - - ax.set_xlim(self.xmin, self.xmax) - - ax.set_title('Channel {} {}'.format(self.dataOut.channelList[n], - self.plot_dt.strftime('%y/%m/%d %H:%M:%S')), - size=8) - self.decimate() +class PlotCOHData(PlotRTIData): + ''' + Plot for Coherence data + ''' - for n, ax in enumerate(self.axes): - + CODE = 'coh' + + def setup(self): + self.xaxis = 'time' + self.ncols = 1 + self.nrows = len(self.data.pairs) + self.nplots = len(self.data.pairs) + self.ylabel = 'Range [km]' + if self.CODE == 'coh': + self.cb_label = '' + self.titles = [ + 'Coherence Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] + else: + self.cb_label = 'Degrees' + self.titles = [ + 'Phase Map Ch{} * Ch{}'.format(x[0], x[1]) for x in self.data.pairs] + + +class PlotPHASEData(PlotCOHData): + ''' + Plot for Phase map data + ''' + + CODE = 'phase' + colormap = 'seismic' + + +class PlotNoiseData(PlotData): + ''' + Plot for noise + ''' + + CODE = 'noise' + + def setup(self): + self.xaxis = 'time' + self.ncols = 1 + self.nrows = 1 + self.nplots = 1 + self.ylabel = 'Intensity [dB]' + self.titles = ['Noise'] + self.colorbar = False + + def plot(self): + + x = self.times + xmin = self.min_time + xmax = xmin + self.xrange * 60 * 60 + Y = self.data[self.CODE] + + if self.axes[0].firsttime: + for ch in self.data.channels: + y = Y[ch] + self.axes[0].plot(x, y, lw=1, label='Ch{}'.format(ch)) + plt.legend() + else: + for ch in self.data.channels: + y = Y[ch] + self.axes[0].lines[ch].set_data(x, y) + + self.ymin = numpy.nanmin(Y) - 5 + self.ymax = numpy.nanmax(Y) + 5 + self.saveTime = self.min_time + + +class PlotSNRData(PlotRTIData): + ''' + Plot for SNR Data + ''' + + CODE = 'snr' + colormap = 'jet' + + +class PlotDOPData(PlotRTIData): + ''' + Plot for DOPPLER Data + ''' + + CODE = 'dop' + colormap = 'jet' + + +class PlotSkyMapData(PlotData): + ''' + Plot for meteors detection data + ''' + + CODE = 'param' + + def setup(self): + + self.ncols = 1 + self.nrows = 1 + self.width = 7.2 + self.height = 7.2 + self.nplots = 1 + self.xlabel = 'Zonal Zenith Angle (deg)' + self.ylabel = 'Meridional Zenith Angle (deg)' + self.polar = True + self.ymin = -180 + self.ymax = 180 + self.colorbar = False + + def plot(self): + + arrayParameters = numpy.concatenate(self.data['param']) + error = arrayParameters[:, -1] + indValid = numpy.where(error == 0)[0] + finalMeteor = arrayParameters[indValid, :] + finalAzimuth = finalMeteor[:, 3] + finalZenith = finalMeteor[:, 4] + + x = finalAzimuth * numpy.pi / 180 + y = finalZenith + + ax = self.axes[0] + + if ax.firsttime: + ax.plot = ax.plot(x, y, 'bo', markersize=5)[0] + else: + ax.plot.set_data(x, y) + + dt1 = self.getDateTime(self.min_time).strftime('%y/%m/%d %H:%M:%S') + dt2 = self.getDateTime(self.max_time).strftime('%y/%m/%d %H:%M:%S') + title = 'Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n' % (dt1, + dt2, + len(x)) + self.titles[0] = title + self.saveTime = self.max_time + + +class PlotParamData(PlotRTIData): + ''' + Plot for data_param object + ''' + + CODE = 'param' + colormap = 'seismic' + + def setup(self): + self.xaxis = 'time' + self.ncols = 1 + self.nrows = self.data.shape(self.CODE)[0] + self.nplots = self.nrows + if self.showSNR: + self.nrows += 1 + self.nplots += 1 + + self.ylabel = 'Height [km]' + if not self.titles: + self.titles = self.data.parameters \ + if self.data.parameters else ['Param {}'.format(x) for x in xrange(self.nrows)] + if self.showSNR: + self.titles.append('SNR') + + def plot(self): + self.data.normalize_heights() + self.x = self.times + self.y = self.data.heights + if self.showSNR: + self.z = numpy.concatenate( + (self.data[self.CODE], self.data['snr']) + ) + else: + self.z = self.data[self.CODE] + + self.z = numpy.ma.masked_invalid(self.z) + + if self.decimation is None: + x, y, z = self.fill_gaps(self.x, self.y, self.z) + else: x, y, z = self.fill_gaps(*self.decimate()) + + for n, ax in enumerate(self.axes): + self.zmax = self.zmax if self.zmax is not None else numpy.max( + self.z[n]) + self.zmin = self.zmin if self.zmin is not None else numpy.min( + self.z[n]) + if ax.firsttime: - ymin = self.ymin if self.ymin else np.nanmin(self.y) - ymax = self.ymax if self.ymax else np.nanmax(self.y) - zmin = self.zmin if self.zmin else np.nanmin(self.z) - zmax = self.zmax if self.zmax else np.nanmax(self.z) - plot = ax.pcolormesh(x, y, z[n].T, - vmin=zmin, - vmax=zmax, - cmap=plt.get_cmap(self.colormap) - ) - divider = make_axes_locatable(ax) - cax = divider.new_horizontal(size='3%', pad=0.05) - self.figure.add_axes(cax) - plt.colorbar(plot, cax) - ax.set_ylim(self.ymin, self.ymax) - ax.firsttime = False - else: - plot = ax.pcolormesh(x, y, z[n].T) + if self.zlimits is not None: + self.zmin, self.zmax = self.zlimits[n] - self.figure.subplots_adjust(wspace=None, hspace=0.5) - + ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n], + vmin=self.zmin, + vmax=self.zmax, + cmap=self.cmaps[n] + ) + else: + if self.zlimits is not None: + self.zmin, self.zmax = self.zlimits[n] + ax.collections.remove(ax.collections[0]) + ax.plt = ax.pcolormesh(x, y, z[n].T * self.factors[n], + vmin=self.zmin, + vmax=self.zmax, + cmap=self.cmaps[n] + ) -class PlotSNRData(PlotRTIData): - - __code = 'SNR' + self.saveTime = self.min_time + + +class PlotOutputData(PlotParamData): + ''' + Plot data_output object + ''' + + CODE = 'output' + colormap = 'seismic' + + +class PlotPolarMapData(PlotData): + ''' + Plot for meteors detection data + ''' + + CODE = 'param' + colormap = 'seismic' + + def setup(self): + self.ncols = 1 + self.nrows = 1 + self.width = 9 + self.height = 8 + self.mode = self.data.meta['mode'] + if self.channels is not None: + self.nplots = len(self.channels) + self.nrows = len(self.channels) + else: + self.nplots = self.data.shape(self.CODE)[0] + self.nrows = self.nplots + self.channels = range(self.nplots) + if self.mode == 'E': + self.xlabel = 'Longitude' + self.ylabel = 'Latitude' + else: + self.xlabel = 'Range (km)' + self.ylabel = 'Height (km)' + self.bgcolor = 'white' + self.cb_labels = self.data.meta['units'] + self.lat = self.data.meta['latitude'] + self.lon = self.data.meta['longitude'] + self.xmin, self.xmax = float(km2deg(self.xmin) + self.lon), float(km2deg(self.xmax) + self.lon) + self.ymin, self.ymax = float(km2deg(self.ymin) + self.lat), float(km2deg(self.ymax) + self.lat) + # self.polar = True + + def plot(self): - def update(self): + for n, ax in enumerate(self.axes): + data = self.data['param'][self.channels[n]] + + zeniths = numpy.linspace(0, self.data.meta['max_range'], data.shape[1]) + if self.mode == 'E': + azimuths = -numpy.radians(self.data.heights)+numpy.pi/2 + r, theta = numpy.meshgrid(zeniths, azimuths) + x, y = r*numpy.cos(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])), r*numpy.sin(theta)*numpy.cos(numpy.radians(self.data.meta['elevation'])) + x = km2deg(x) + self.lon + y = km2deg(y) + self.lat + else: + azimuths = numpy.radians(self.data.heights) + r, theta = numpy.meshgrid(zeniths, azimuths) + x, y = r*numpy.cos(theta), r*numpy.sin(theta) + self.y = zeniths + + if ax.firsttime: + if self.zlimits is not None: + self.zmin, self.zmax = self.zlimits[n] + ax.plt = ax.pcolormesh(#r, theta, numpy.ma.array(data, mask=numpy.isnan(data)), + x, y, numpy.ma.array(data, mask=numpy.isnan(data)), + vmin=self.zmin, + vmax=self.zmax, + cmap=self.cmaps[n]) + else: + if self.zlimits is not None: + self.zmin, self.zmax = self.zlimits[n] + ax.collections.remove(ax.collections[0]) + ax.plt = ax.pcolormesh(# r, theta, numpy.ma.array(data, mask=numpy.isnan(data)), + x, y, numpy.ma.array(data, mask=numpy.isnan(data)), + vmin=self.zmin, + vmax=self.zmax, + cmap=self.cmaps[n]) + + if self.mode == 'A': + continue + + # plot district names + f = open('/data/workspace/schain_scripts/distrito.csv') + for line in f: + label, lon, lat = [s.strip() for s in line.split(',') if s] + lat = float(lat) + lon = float(lon) + # ax.plot(lon, lat, '.b', ms=2) + ax.text(lon, lat, label.decode('utf8'), ha='center', va='bottom', size='8', color='black') + + # plot limites + limites =[] + tmp = [] + for line in open('/data/workspace/schain_scripts/lima.csv'): + if '#' in line: + if tmp: + limites.append(tmp) + tmp = [] + continue + values = line.strip().split(',') + tmp.append((float(values[0]), float(values[1]))) + for points in limites: + ax.add_patch(Polygon(points, ec='k', fc='none', ls='--', lw=0.5)) + + # plot Cuencas + for cuenca in ('rimac', 'lurin', 'mala', 'chillon', 'chilca', 'chancay-huaral'): + f = open('/data/workspace/schain_scripts/{}.csv'.format(cuenca)) + values = [line.strip().split(',') for line in f] + points = [(float(s[0]), float(s[1])) for s in values] + ax.add_patch(Polygon(points, ec='b', fc='none')) + + # plot grid + for r in (15, 30, 45, 60): + ax.add_artist(plt.Circle((self.lon, self.lat), km2deg(r), color='0.6', fill=False, lw=0.2)) + ax.text( + self.lon + (km2deg(r))*numpy.cos(60*numpy.pi/180), + self.lat + (km2deg(r))*numpy.sin(60*numpy.pi/180), + '{}km'.format(r), + ha='center', va='bottom', size='8', color='0.6', weight='heavy') + + if self.mode == 'E': + title = 'El={}$^\circ$'.format(self.data.meta['elevation']) + label = 'E{:02d}'.format(int(self.data.meta['elevation'])) + else: + title = 'Az={}$^\circ$'.format(self.data.meta['azimuth']) + label = 'A{:02d}'.format(int(self.data.meta['azimuth'])) - self.time.append(self.dataOut.ltctime) + self.save_labels = ['{}-{}'.format(lbl, label) for lbl in self.labels] + self.titles = ['{} {}'.format(self.data.parameters[x], title) for x in self.channels] + self.saveTime = self.max_time + - for ch in self.dataOut.channelList: - self.data[ch][self.dataOut.ltctime] = 10*np.log10(self.dataOut.data_SNR[ch]) \ No newline at end of file diff --git a/schainpy/model/graphics/jroplot_heispectra.py b/schainpy/model/graphics/jroplot_heispectra.py index f8d4512..b0c9c5b 100644 --- a/schainpy/model/graphics/jroplot_heispectra.py +++ b/schainpy/model/graphics/jroplot_heispectra.py @@ -11,79 +11,80 @@ from figure import Figure, isRealtime from plotting_codes import * class SpectraHeisScope(Figure): - - + + isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'spc' - - def __init__(self): - + + def __init__(self, **kwargs): + + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 230 self.HEIGHT = 250 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = SPEC_CODE - + def getSubplots(self): - + ncol = int(numpy.sqrt(self.nplots)+0.9) nrow = int(self.nplots*1./ncol + 0.9) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, show): - + showprofile = False self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 if showprofile: ncolspan = 3 colspan = 2 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show = show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + if showprofile: self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None, save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): - + """ - + Input: dataOut : id : @@ -94,12 +95,12 @@ class SpectraHeisScope(Figure): ymin : None, ymax : None, """ - + if dataOut.realtime: if not(isRealtime(utcdatatime = dataOut.utctime)): print 'Skipping this plot function' return - + if channelList == None: channelIndexList = dataOut.channelIndexList else: @@ -108,9 +109,9 @@ class SpectraHeisScope(Figure): if channel not in dataOut.channelList: raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - + # x = dataOut.heightList - c = 3E8 + c = 3E8 deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] #deberia cambiar para el caso de 1Mhz y 100KHz x = numpy.arange(-1*dataOut.nHeights/2.,dataOut.nHeights/2.)*(c/(2*deltaHeight*dataOut.nHeights*1000)) @@ -122,7 +123,7 @@ class SpectraHeisScope(Figure): data = dataOut.data_spc / factor datadB = 10.*numpy.log10(data) y = datadB - + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) title = wintitle + " Scope: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S")) @@ -130,29 +131,29 @@ class SpectraHeisScope(Figure): #para 1Mhz descomentar la siguiente linea #xlabel = "Frequency x 10000" ylabel = "Intensity (dB)" - + if not self.isConfig: nplots = len(channelIndexList) - + self.setup(id=id, nplots=nplots, wintitle=wintitle, show=show) - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.isConfig = True - + self.setWinTitle(title) - + for i in range(len(self.axesList)): ychannel = y[i,:] str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) @@ -161,10 +162,10 @@ class SpectraHeisScope(Figure): axes.pline(x, ychannel, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, xlabel=xlabel, ylabel=ylabel, title=title, grid='both') - - + + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -173,18 +174,18 @@ class SpectraHeisScope(Figure): thisDatetime=thisDatetime) class RTIfromSpectraHeis(Figure): - + isConfig = None __nsubplots = None PREFIX = 'rtinoise' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 24*60*60 self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 820 self.HEIGHT = 200 self.WIDTHPROF = 120 @@ -193,43 +194,43 @@ class RTIfromSpectraHeis(Figure): self.xdata = None self.ydata = None self.figfile = None - + self.PLOT_CODE = RTI_CODE - + def getSubplots(self): - + ncol = 1 nrow = 1 - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 7 colspan = 6 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH+self.WIDTHPROF, heightplot = self.HEIGHT+self.HEIGHTPROF, show = show) - + nrow, ncol = self.getSubplots() - + self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1) - - + + def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True', xmin=None, xmax=None, ymin=None, ymax=None, timerange=None, save=False, figpath='./', figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): - + if channelList == None: channelIndexList = dataOut.channelIndexList channelList = dataOut.channelList @@ -239,86 +240,86 @@ class RTIfromSpectraHeis(Figure): if channel not in dataOut.channelList: raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - + if timerange != None: self.timerange = timerange - + x = dataOut.getTimeRange() y = dataOut.getHeiRange() - + factor = dataOut.normFactor data = dataOut.data_spc / factor data = numpy.average(data,axis=1) datadB = 10*numpy.log10(data) - + # factor = dataOut.normFactor # noise = dataOut.getNoise()/factor # noisedB = 10*numpy.log10(noise) - + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) title = wintitle + " RTI: %s" %(thisDatetime.strftime("%d-%b-%Y")) xlabel = "Local Time" ylabel = "Intensity (dB)" - + if not self.isConfig: - + nplots = 1 - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + self.tmin, self.tmax = self.getTimeLim(x, xmin, xmax) - + if ymin == None: ymin = numpy.nanmin(datadB) if ymax == None: ymax = numpy.nanmax(datadB) - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True self.figfile = figfile self.xdata = numpy.array([]) self.ydata = numpy.array([]) - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.setWinTitle(title) - - + + # title = "RTI %s" %(thisDatetime.strftime("%d-%b-%Y")) title = "RTI - %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S")) - + legendlabels = ["channel %d"%idchannel for idchannel in channelList] axes = self.axesList[0] - + self.xdata = numpy.hstack((self.xdata, x[0:1])) - + if len(self.ydata)==0: self.ydata = datadB[channelIndexList].reshape(-1,1) else: self.ydata = numpy.hstack((self.ydata, datadB[channelIndexList].reshape(-1,1))) - - + + axes.pmultilineyaxis(x=self.xdata, y=self.ydata, xmin=self.tmin, xmax=self.tmax, ymin=ymin, ymax=ymax, xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='.', markersize=8, linestyle="solid", grid='both', XAxisAsTime=True ) - + self.draw() - + update_figfile = False - + if dataOut.ltctime >= self.tmax: self.counter_imagwr = wr_period self.isConfig = False update_figfile = True - + self.save(figpath=figpath, figfile=figfile, save=save, diff --git a/schainpy/model/graphics/jroplot_parameters.py b/schainpy/model/graphics/jroplot_parameters.py index 1cda791..4e810c6 100644 --- a/schainpy/model/graphics/jroplot_parameters.py +++ b/schainpy/model/graphics/jroplot_parameters.py @@ -1,87 +1,297 @@ import os import datetime import numpy - +import inspect from figure import Figure, isRealtime, isTimeInHourRange from plotting_codes import * +class FitGauPlot(Figure): + + isConfig = None + __nsubplots = None + + WIDTHPROF = None + HEIGHTPROF = None + PREFIX = 'fitgau' + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) + self.isConfig = False + self.__nsubplots = 1 + + self.WIDTH = 250 + self.HEIGHT = 250 + self.WIDTHPROF = 120 + self.HEIGHTPROF = 0 + self.counter_imagwr = 0 + + self.PLOT_CODE = SPEC_CODE + + self.FTP_WEI = None + self.EXP_CODE = None + self.SUB_EXP_CODE = None + self.PLOT_POS = None + + self.__xfilter_ena = False + self.__yfilter_ena = False + + def getSubplots(self): + + ncol = int(numpy.sqrt(self.nplots)+0.9) + nrow = int(self.nplots*1./ncol + 0.9) + + return nrow, ncol + + def setup(self, id, nplots, wintitle, showprofile=True, show=True): + + self.__showprofile = showprofile + self.nplots = nplots + + ncolspan = 1 + colspan = 1 + if showprofile: + ncolspan = 3 + colspan = 2 + self.__nsubplots = 2 + + self.createFigure(id = id, + wintitle = wintitle, + widthplot = self.WIDTH + self.WIDTHPROF, + heightplot = self.HEIGHT + self.HEIGHTPROF, + show=show) + + nrow, ncol = self.getSubplots() + + counter = 0 + for y in range(nrow): + for x in range(ncol): + + if counter >= self.nplots: + break + + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) + + if showprofile: + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) + + counter += 1 + + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True, + xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, + save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, + server=None, folder=None, username=None, password=None, + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False, + xaxis="frequency", colormap='jet', normFactor=None , GauSelector = 1): + + """ + + Input: + dataOut : + id : + wintitle : + channelList : + showProfile : + xmin : None, + xmax : None, + ymin : None, + ymax : None, + zmin : None, + zmax : None + """ + if realtime: + if not(isRealtime(utcdatatime = dataOut.utctime)): + print 'Skipping this plot function' + return + + if channelList == None: + channelIndexList = dataOut.channelIndexList + else: + channelIndexList = [] + for channel in channelList: + if channel not in dataOut.channelList: + raise ValueError, "Channel %d is not in dataOut.channelList" %channel + channelIndexList.append(dataOut.channelList.index(channel)) + +# if normFactor is None: +# factor = dataOut.normFactor +# else: +# factor = normFactor + if xaxis == "frequency": + x = dataOut.spc_range[0] + xlabel = "Frequency (kHz)" + + elif xaxis == "time": + x = dataOut.spc_range[1] + xlabel = "Time (ms)" + + else: + x = dataOut.spc_range[2] + xlabel = "Velocity (m/s)" + + ylabel = "Range (Km)" + + y = dataOut.getHeiRange() + + z = dataOut.GauSPC[:,GauSelector,:,:] #GauSelector] #dataOut.data_spc/factor + print 'GausSPC', z[0,32,10:40] + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + zdB = 10*numpy.log10(z) + + avg = numpy.average(z, axis=1) + avgdB = 10*numpy.log10(avg) + + noise = dataOut.spc_noise + noisedB = 10*numpy.log10(noise) + + thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) + title = wintitle + " Spectra" + if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): + title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith) + + if not self.isConfig: + + nplots = len(channelIndexList) + + self.setup(id=id, + nplots=nplots, + wintitle=wintitle, + showprofile=showprofile, + show=show) + + if xmin == None: xmin = numpy.nanmin(x) + if xmax == None: xmax = numpy.nanmax(x) + if ymin == None: ymin = numpy.nanmin(y) + if ymax == None: ymax = numpy.nanmax(y) + if zmin == None: zmin = numpy.floor(numpy.nanmin(noisedB)) - 3 + if zmax == None: zmax = numpy.ceil(numpy.nanmax(avgdB)) + 3 + + self.FTP_WEI = ftp_wei + self.EXP_CODE = exp_code + self.SUB_EXP_CODE = sub_exp_code + self.PLOT_POS = plot_pos + + self.isConfig = True + + self.setWinTitle(title) + + for i in range(self.nplots): + index = channelIndexList[i] + str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) + title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[index], noisedB[index], str_datetime) + if len(dataOut.beam.codeList) != 0: + title = "Ch%d:%4.2fdB,%2.2f,%2.2f:%s" %(dataOut.channelList[index], noisedB[index], dataOut.beam.azimuthList[index], dataOut.beam.zenithList[index], str_datetime) + + axes = self.axesList[i*self.__nsubplots] + axes.pcolor(x, y, zdB[index,:,:], + xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax, + xlabel=xlabel, ylabel=ylabel, title=title, colormap=colormap, + ticksize=9, cblabel='') + + if self.__showprofile: + axes = self.axesList[i*self.__nsubplots +1] + axes.pline(avgdB[index,:], y, + xmin=zmin, xmax=zmax, ymin=ymin, ymax=ymax, + xlabel='dB', ylabel='', title='', + ytick_visible=False, + grid='x') + + noiseline = numpy.repeat(noisedB[index], len(y)) + axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2) + + self.draw() + + if figfile == None: + str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") + name = str_datetime + if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): + name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith) + figfile = self.getFilename(name) + + self.save(figpath=figpath, + figfile=figfile, + save=save, + ftp=ftp, + wr_period=wr_period, + thisDatetime=thisDatetime) + + + class MomentsPlot(Figure): - + isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'prm' - - def __init__(self): - + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 280 self.HEIGHT = 250 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = MOMENTS_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - + def getSubplots(self): - + ncol = int(numpy.sqrt(self.nplots)+0.9) nrow = int(self.nplots*1./ncol + 0.9) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 if showprofile: ncolspan = 3 colspan = 2 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + if showprofile: self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False): - + """ - + Input: dataOut : id : @@ -95,15 +305,15 @@ class MomentsPlot(Figure): zmin : None, zmax : None """ - + if dataOut.flagNoData: return None - + if realtime: if not(isRealtime(utcdatatime = dataOut.utctime)): print 'Skipping this plot function' return - + if channelList == None: channelIndexList = dataOut.channelIndexList else: @@ -112,55 +322,55 @@ class MomentsPlot(Figure): if channel not in dataOut.channelList: raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - + factor = dataOut.normFactor x = dataOut.abscissaList y = dataOut.heightList - + z = dataOut.data_pre[channelIndexList,:,:]/factor - z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) avg = numpy.average(z, axis=1) noise = dataOut.noise/factor - + zdB = 10*numpy.log10(z) avgdB = 10*numpy.log10(avg) noisedB = 10*numpy.log10(noise) - + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) - title = wintitle + " Parameters" + title = wintitle + " Parameters" xlabel = "Velocity (m/s)" ylabel = "Range (Km)" - + update_figfile = False - + if not self.isConfig: - + nplots = len(channelIndexList) - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) if zmin == None: zmin = numpy.nanmin(avgdB)*0.9 if zmax == None: zmax = numpy.nanmax(avgdB)*0.9 - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.isConfig = True update_figfile = True - + self.setWinTitle(title) - + for i in range(self.nplots): str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) title = "Channel %d: %4.2fdB: %s" %(dataOut.channelList[i], noisedB[i], str_datetime) @@ -172,7 +382,7 @@ class MomentsPlot(Figure): #Mean Line mean = dataOut.data_param[i, 1, :] axes.addpline(mean, y, idline=0, color="black", linestyle="solid", lw=1) - + if self.__showprofile: axes = self.axesList[i*self.__nsubplots +1] axes.pline(avgdB[i], y, @@ -180,35 +390,35 @@ class MomentsPlot(Figure): xlabel='dB', ylabel='', title='', ytick_visible=False, grid='x') - + noiseline = numpy.repeat(noisedB[i], len(y)) axes.addpline(noiseline, y, idline=1, color="black", linestyle="dashed", lw=2) - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, ftp=ftp, wr_period=wr_period, thisDatetime=thisDatetime) - - + + class SkyMapPlot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'mmap' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + # self.WIDTH = 280 # self.HEIGHT = 250 self.WIDTH = 600 @@ -216,36 +426,36 @@ class SkyMapPlot(Figure): self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = MSKYMAP_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - + def getSubplots(self): - + ncol = int(numpy.sqrt(self.nplots)+0.9) nrow = int(self.nplots*1./ncol + 0.9) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=False, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH, #+ self.WIDTHPROF, heightplot = self.HEIGHT,# + self.HEIGHTPROF, show=show) - - nrow, ncol = 1,1 + + nrow, ncol = 1,1 counter = 0 x = 0 y = 0 @@ -256,9 +466,9 @@ class SkyMapPlot(Figure): save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False): - + """ - + Input: dataOut : id : @@ -272,43 +482,43 @@ class SkyMapPlot(Figure): zmin : None, zmax : None """ - + arrayParameters = dataOut.data_param error = arrayParameters[:,-1] indValid = numpy.where(error == 0)[0] finalMeteor = arrayParameters[indValid,:] finalAzimuth = finalMeteor[:,3] finalZenith = finalMeteor[:,4] - + x = finalAzimuth*numpy.pi/180 y = finalZenith - x1 = [dataOut.ltctime, dataOut.ltctime] - + x1 = [dataOut.ltctime, dataOut.ltctime] + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) - title = wintitle + " Parameters" + title = wintitle + " Parameters" xlabel = "Zonal Zenith Angle (deg) " ylabel = "Meridional Zenith Angle (deg)" update_figfile = False - + if not self.isConfig: - + nplots = 1 - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if self.xmin is None and self.xmax is None: self.xmin, self.xmax = self.getTimeLim(x1, tmin, tmax, timerange) - + if timerange != None: self.timerange = timerange else: self.timerange = self.xmax - self.xmin - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code @@ -317,21 +527,21 @@ class SkyMapPlot(Figure): self.firstdate = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) self.isConfig = True update_figfile = True - + self.setWinTitle(title) - + i = 0 str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) axes = self.axesList[i*self.__nsubplots] nevents = axes.x_buffer.shape[0] + x.shape[0] title = "Meteor Detection Sky Map\n %s - %s \n Number of events: %5.0f\n" %(self.firstdate,str_datetime,nevents) - axes.polar(x, y, + axes.polar(x, y, title=title, xlabel=xlabel, ylabel=ylabel, ticksize=9, cblabel='') - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -339,7 +549,7 @@ class SkyMapPlot(Figure): wr_period=wr_period, thisDatetime=thisDatetime, update_figfile=update_figfile) - + if dataOut.ltctime >= self.xmax: self.isConfigmagwr = wr_period self.isConfig = False @@ -347,85 +557,85 @@ class SkyMapPlot(Figure): axes.__firsttime = True self.xmin += self.timerange self.xmax += self.timerange - - + + class WindProfilerPlot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'wind' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = None self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 800 self.HEIGHT = 300 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = WIND_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - self.tmin = None + self.tmin = None self.tmax = None - + self.xmin = None self.xmax = None - + self.figfile = None - + def getSubplots(self): - + ncol = 1 nrow = self.nplots - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): if counter >= self.nplots: break - - self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1) + + self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1) counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile='False', xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, zmax_ver = None, zmin_ver = None, SNRmin = None, SNRmax = None, timerange=None, SNRthresh = None, save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): """ - + Input: dataOut : id : @@ -439,33 +649,32 @@ class WindProfilerPlot(Figure): zmin : None, zmax : None """ - + # if timerange is not None: # self.timerange = timerange -# +# # tmin = None # tmax = None - - x = dataOut.getTimeRange1(dataOut.outputInterval) - y = dataOut.heightList - z = dataOut.data_output.copy() + x = dataOut.getTimeRange1(dataOut.paramInterval) + y = dataOut.heightList + z = dataOut.data_output.copy() nplots = z.shape[0] #Number of wind dimensions estimated nplotsw = nplots - - + + #If there is a SNR function defined if dataOut.data_SNR is not None: nplots += 1 SNR = dataOut.data_SNR SNRavg = numpy.average(SNR, axis=0) - + SNRdB = 10*numpy.log10(SNR) SNRavgdB = 10*numpy.log10(SNRavg) - + if SNRthresh == None: SNRthresh = -5.0 ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0] - + for i in range(nplotsw): z[i,ind] = numpy.nan @@ -474,73 +683,73 @@ class WindProfilerPlot(Figure): title = wintitle + "Wind" xlabel = "" ylabel = "Height (km)" - update_figfile = False - + update_figfile = False + if not self.isConfig: - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if timerange is not None: self.timerange = timerange - + self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - + if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + if zmax == None: zmax = numpy.nanmax(abs(z[range(2),:])) #if numpy.isnan(zmax): zmax = 50 if zmin == None: zmin = -zmax - + if nplotsw == 3: if zmax_ver == None: zmax_ver = numpy.nanmax(abs(z[2,:])) if zmin_ver == None: zmin_ver = -zmax_ver - + if dataOut.data_SNR is not None: if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB) - if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) - - + if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) + + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True self.figfile = figfile update_figfile = True - + self.setWinTitle(title) - + if ((self.xmax - x[1]) < (x[1]-x[0])): x[1] = self.xmax - + strWind = ['Zonal', 'Meridional', 'Vertical'] strCb = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)'] zmaxVector = [zmax, zmax, zmax_ver] zminVector = [zmin, zmin, zmin_ver] windFactor = [1,1,100] - + for i in range(nplotsw): - + title = "%s Wind: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.__nsubplots] - + z1 = z[i,:].reshape((1,-1))*windFactor[i] - #z1=numpy.ma.masked_where(z1==0.,z1) + #z1=numpy.ma.masked_where(z1==0.,z1) axes.pcolorbuffer(x, y, z1, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i], xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel=strCb[i], cbsize="1%", colormap="seismic" ) - + if dataOut.data_SNR is not None: - i += 1 + i += 1 title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.__nsubplots] SNRavgdB = SNRavgdB.reshape((1,-1)) @@ -548,9 +757,9 @@ class WindProfilerPlot(Figure): xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel='', cbsize="1%", colormap="jet") - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -558,93 +767,92 @@ class WindProfilerPlot(Figure): wr_period=wr_period, thisDatetime=thisDatetime, update_figfile=update_figfile) - - if dataOut.ltctime + dataOut.outputInterval >= self.xmax: + + if dataOut.ltctime + dataOut.paramInterval >= self.xmax: self.counter_imagwr = wr_period self.isConfig = False update_figfile = True - + class ParametersPlot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'param' nplots = None nchan = None - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = None self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 800 self.HEIGHT = 180 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = RTI_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - self.tmin = None + self.tmin = None self.tmax = None - + self.xmin = None self.xmax = None - + self.figfile = None - + def getSubplots(self): - + ncol = 1 nrow = self.nplots - + return nrow, ncol - + def setup(self, id, nplots, wintitle, show=True): self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + counter += 1 - - def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap=True, + + def run(self, dataOut, id, wintitle="", channelList=None, paramIndex = 0, colormap="jet", xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, timerange=None, showSNR=False, SNRthresh = -numpy.inf, SNRmin=None, SNRmax=None, save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): - + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, HEIGHT=None): """ - + Input: dataOut : id : @@ -659,14 +867,13 @@ class ParametersPlot(Figure): zmax : None """ - if colormap: - colormap="jet" - else: - colormap="RdBu_r" + if HEIGHT is not None: + self.HEIGHT = HEIGHT + if not isTimeInHourRange(dataOut.datatime, xmin, xmax): return - + if channelList == None: channelIndexList = range(dataOut.data_param.shape[0]) else: @@ -675,70 +882,70 @@ class ParametersPlot(Figure): if channel not in dataOut.channelList: raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - + x = dataOut.getTimeRange1(dataOut.paramInterval) y = dataOut.getHeiRange() - + if dataOut.data_param.ndim == 3: z = dataOut.data_param[channelIndexList,paramIndex,:] else: z = dataOut.data_param[channelIndexList,:] - + if showSNR: #SNR data SNRarray = dataOut.data_SNR[channelIndexList,:] SNRdB = 10*numpy.log10(SNRarray) ind = numpy.where(SNRdB < SNRthresh) z[ind] = numpy.nan - + thisDatetime = dataOut.datatime # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y")) xlabel = "" ylabel = "Range (Km)" - + update_figfile = False - + if not self.isConfig: - + nchan = len(channelIndexList) self.nchan = nchan self.plotFact = 1 nplots = nchan - + if showSNR: nplots = nchan*2 self.plotFact = 2 if SNRmin == None: SNRmin = numpy.nanmin(SNRdB) - if SNRmax == None: SNRmax = numpy.nanmax(SNRdB) - + if SNRmax == None: SNRmax = numpy.nanmax(SNRdB) + self.setup(id=id, nplots=nplots, wintitle=wintitle, show=show) - + if timerange != None: self.timerange = timerange - + self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - + if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) if zmin == None: zmin = numpy.nanmin(z) if zmax == None: zmax = numpy.nanmax(z) - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True self.figfile = figfile update_figfile = True - + self.setWinTitle(title) - + for i in range(self.nchan): index = channelIndexList[i] title = "Channel %d: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) @@ -748,7 +955,7 @@ class ParametersPlot(Figure): xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel='', cbsize="1%",colormap=colormap) - + if showSNR: title = "Channel %d SNR: %s" %(dataOut.channelList[index], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.plotFact + 1] @@ -757,15 +964,15 @@ class ParametersPlot(Figure): xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel='', cbsize="1%",colormap='jet') - - + + self.draw() - + if dataOut.ltctime >= self.xmax: self.counter_imagwr = wr_period self.isConfig = False update_figfile = True - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -774,82 +981,82 @@ class ParametersPlot(Figure): thisDatetime=thisDatetime, update_figfile=update_figfile) - - + + class Parameters1Plot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'prm' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 2*60*60 self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 800 - self.HEIGHT = 150 + self.HEIGHT = 180 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = PARMS_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - self.tmin = None + self.tmin = None self.tmax = None - + self.xmin = None self.xmax = None - + self.figfile = None - + def getSubplots(self): - + ncol = 1 nrow = self.nplots - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + if showprofile: self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=False, - xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None, + xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None,timerange=None, parameterIndex = None, onlyPositive = False, SNRthresh = -numpy.inf, SNR = True, SNRmin = None, SNRmax = None, onlySNR = False, DOP = True, @@ -857,9 +1064,9 @@ class Parameters1Plot(Figure): save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): - + #print inspect.getargspec(self.run).args """ - + Input: dataOut : id : @@ -873,21 +1080,21 @@ class Parameters1Plot(Figure): zmin : None, zmax : None """ - + data_param = getattr(dataOut, parameterObject) - + if channelList == None: channelIndexList = numpy.arange(data_param.shape[0]) else: channelIndexList = numpy.array(channelList) nchan = len(channelIndexList) #Number of channels being plotted - + if nchan < 1: return nGraphsByChannel = 0 - + if SNR: nGraphsByChannel += 1 if DOP: @@ -895,87 +1102,85 @@ class Parameters1Plot(Figure): if nGraphsByChannel < 1: return - + nplots = nGraphsByChannel*nchan - + if timerange is not None: self.timerange = timerange - + #tmin = None #tmax = None if parameterIndex == None: parameterIndex = 1 - + x = dataOut.getTimeRange1(dataOut.paramInterval) y = dataOut.heightList - z = data_param[channelIndexList,parameterIndex,:].copy() - - zRange = dataOut.abscissaList -# nChannels = z.shape[0] #Number of wind dimensions estimated -# thisDatetime = dataOut.datatime + + if dataOut.data_param.ndim == 3: + z = dataOut.data_param[channelIndexList,parameterIndex,:] + else: + z = dataOut.data_param[channelIndexList,:] if dataOut.data_SNR is not None: - SNRarray = dataOut.data_SNR[channelIndexList,:] - SNRdB = 10*numpy.log10(SNRarray) -# SNRavgdB = 10*numpy.log10(SNRavg) - ind = numpy.where(SNRdB < 10**(SNRthresh/10)) - z[ind] = numpy.nan - + if dataOut.data_SNR.ndim == 2: + SNRavg = numpy.average(dataOut.data_SNR, axis=0) + else: + SNRavg = dataOut.data_SNR + SNRdB = 10*numpy.log10(SNRavg) + thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) title = wintitle + " Parameters Plot" #: %s" %(thisDatetime.strftime("%d-%b-%Y")) xlabel = "" - ylabel = "Range (Km)" - - if (SNR and not onlySNR): nplots = 2*nplots - + ylabel = "Range (Km)" + if onlyPositive: colormap = "jet" - zmin = 0 + zmin = 0 else: colormap = "RdBu_r" - + if not self.isConfig: - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - + if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - if zmin == None: zmin = numpy.nanmin(zRange) - if zmax == None: zmax = numpy.nanmax(zRange) - + if zmin == None: zmin = numpy.nanmin(z) + if zmax == None: zmax = numpy.nanmax(z) + if SNR: if SNRmin == None: SNRmin = numpy.nanmin(SNRdB) - if SNRmax == None: SNRmax = numpy.nanmax(SNRdB) - + if SNRmax == None: SNRmax = numpy.nanmax(SNRdB) + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True self.figfile = figfile - + self.setWinTitle(title) - + if ((self.xmax - x[1]) < (x[1]-x[0])): x[1] = self.xmax - + for i in range(nchan): if (SNR and not onlySNR): j = 2*i else: j = i - + j = nGraphsByChannel*i if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith) - + if not onlySNR: axes = self.axesList[j*self.__nsubplots] z1 = z[i,:].reshape((1,-1)) @@ -986,7 +1191,7 @@ class Parameters1Plot(Figure): if DOP: title = "%s Channel %d: %s" %(parameterName, channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) - + if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): title = title + '_' + 'azimuth,zenith=%2.2f,%2.2f'%(dataOut.azimuth, dataOut.zenith) axes = self.axesList[j] @@ -995,30 +1200,29 @@ class Parameters1Plot(Figure): xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zmin, zmax=zmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap=colormap, ticksize=9, cblabel=zlabel, cbsize="1%") - - if SNR: - title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) - axes = self.axesList[(j)*self.__nsubplots] - if not onlySNR: - axes = self.axesList[(j + 1)*self.__nsubplots] - axes = self.axesList[(j + nGraphsByChannel-1)] + if SNR: + title = "Channel %d Signal Noise Ratio (SNR): %s" %(channelIndexList[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) + axes = self.axesList[(j)*self.__nsubplots] + if not onlySNR: + axes = self.axesList[(j + 1)*self.__nsubplots] + + axes = self.axesList[(j + nGraphsByChannel-1)] + z1 = SNRdB.reshape((1,-1)) + axes.pcolorbuffer(x, y, z1, + xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, + xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet", + ticksize=9, cblabel=zlabel, cbsize="1%") + - z1 = SNRdB[i,:].reshape((1,-1)) - axes.pcolorbuffer(x, y, z1, - xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, - xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True,colormap="jet", - ticksize=9, cblabel=zlabel, cbsize="1%") - - self.draw() - + if x[1] >= self.axesList[0].xmax: self.counter_imagwr = wr_period self.isConfig = False self.figfile = None - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -1026,79 +1230,80 @@ class Parameters1Plot(Figure): wr_period=wr_period, thisDatetime=thisDatetime, update_figfile=False) - + class SpectralFittingPlot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'prm' - - + + N = None ippSeconds = None - - def __init__(self): + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.PLOT_CODE = SPECFIT_CODE - + self.WIDTH = 450 self.HEIGHT = 250 self.WIDTHPROF = 0 self.HEIGHTPROF = 0 - + def getSubplots(self): - + ncol = int(numpy.sqrt(self.nplots)+0.9) nrow = int(self.nplots*1./ncol + 0.9) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=False, show=True): - - showprofile = False + + showprofile = False self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 5 colspan = 4 if showprofile: ncolspan = 5 colspan = 4 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + if showprofile: self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan+colspan, 1, 1) - + counter += 1 - + def run(self, dataOut, id, cutHeight=None, fit=False, wintitle="", channelList=None, showprofile=True, xmin=None, xmax=None, ymin=None, ymax=None, save=False, figpath='./', figfile=None, show=True): - + """ - + Input: dataOut : id : @@ -1110,18 +1315,18 @@ class SpectralFittingPlot(Figure): zmin : None, zmax : None """ - + if cutHeight==None: h=270 heightindex = numpy.abs(cutHeight - dataOut.heightList).argmin() cutHeight = dataOut.heightList[heightindex] - + factor = dataOut.normFactor x = dataOut.abscissaList[:-1] #y = dataOut.getHeiRange() - + z = dataOut.data_pre[:,:,heightindex]/factor - z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) avg = numpy.average(z, axis=1) listChannels = z.shape[0] @@ -1132,48 +1337,48 @@ class SpectralFittingPlot(Figure): listChannels.sort() spcFitLine = numpy.zeros(z.shape) constants = dataOut.constants - + nGroups = groupArray.shape[0] nChannels = groupArray.shape[1] nProfiles = z.shape[1] - + for f in range(nGroups): groupChann = groupArray[f,:] p = dataOut.data_param[f,:,heightindex] # p = numpy.array([ 89.343967,0.14036615,0.17086219,18.89835291,1.58388365,1.55099167]) fitLineAux = dataOut.library.modelFunction(p, constants)*nProfiles fitLineAux = fitLineAux.reshape((nChannels,nProfiles)) - spcFitLine[groupChann,:] = fitLineAux + spcFitLine[groupChann,:] = fitLineAux # spcFitLine = spcFitLine/factor - + z = z[listChannels,:] spcFitLine = spcFitLine[listChannels,:] spcFitLinedB = 10*numpy.log10(spcFitLine) - + zdB = 10*numpy.log10(z) #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) title = wintitle + " Doppler Spectra: %s" %(thisDatetime.strftime("%d-%b-%Y %H:%M:%S")) xlabel = "Velocity (m/s)" ylabel = "Spectrum" - + if not self.isConfig: - + nplots = listChannels.size - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if xmin == None: xmin = numpy.nanmin(x) if xmax == None: xmax = numpy.nanmax(x) if ymin == None: ymin = numpy.nanmin(zdB) if ymax == None: ymax = numpy.nanmax(zdB)+2 - + self.isConfig = True - + self.setWinTitle(title) for i in range(self.nplots): # title = "Channel %d: %4.2fdB" %(dataOut.channelList[i]+1, noisedB[i]) @@ -1191,94 +1396,94 @@ class SpectralFittingPlot(Figure): axes.pmultilineyaxis(x, y, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, xlabel=xlabel, ylabel=ylabel, title=title, - legendlabels=legendlabels, marker=None, + legendlabels=legendlabels, marker=None, linestyle='solid', grid='both') - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, ftp=ftp, wr_period=wr_period, thisDatetime=thisDatetime) - - + + class EWDriftsPlot(Figure): - + __isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'drift' - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 2*60*60 self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 800 self.HEIGHT = 150 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = EWDRIFT_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - self.tmin = None + self.tmin = None self.tmax = None - + self.xmin = None self.xmax = None - + self.figfile = None - + def getSubplots(self): - + ncol = 1 nrow = self.nplots - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): if counter >= self.nplots: break - - self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1) + + self.addAxes(nrow, ncol*ncolspan, y, 0, colspan, 1) counter += 1 - - def run(self, dataOut, id, wintitle="", channelList=None, + + def run(self, dataOut, id, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, zmaxVertical = None, zminVertical = None, zmaxZonal = None, zminZonal = None, timerange=None, SNRthresh = -numpy.inf, SNRmin = None, SNRmax = None, SNR_1 = False, save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): """ - + Input: dataOut : id : @@ -1292,133 +1497,134 @@ class EWDriftsPlot(Figure): zmin : None, zmax : None """ - + if timerange is not None: self.timerange = timerange - + tmin = None tmax = None - + x = dataOut.getTimeRange1(dataOut.outputInterval) # y = dataOut.heightList y = dataOut.heightList - + z = dataOut.data_output nplots = z.shape[0] #Number of wind dimensions estimated nplotsw = nplots - + #If there is a SNR function defined if dataOut.data_SNR is not None: nplots += 1 SNR = dataOut.data_SNR - + if SNR_1: SNR += 1 - + SNRavg = numpy.average(SNR, axis=0) - + SNRdB = 10*numpy.log10(SNR) SNRavgdB = 10*numpy.log10(SNRavg) - + ind = numpy.where(SNRavg < 10**(SNRthresh/10))[0] - + for i in range(nplotsw): z[i,ind] = numpy.nan - - - showprofile = False + + + showprofile = False # thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(x[1]) title = wintitle + " EW Drifts" xlabel = "" ylabel = "Height (Km)" - + if not self.isConfig: - + self.setup(id=id, nplots=nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - + if ymin == None: ymin = numpy.nanmin(y) if ymax == None: ymax = numpy.nanmax(y) - + if zmaxZonal == None: zmaxZonal = numpy.nanmax(abs(z[0,:])) if zminZonal == None: zminZonal = -zmaxZonal if zmaxVertical == None: zmaxVertical = numpy.nanmax(abs(z[1,:])) if zminVertical == None: zminVertical = -zmaxVertical - + if dataOut.data_SNR is not None: if SNRmin == None: SNRmin = numpy.nanmin(SNRavgdB) - if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) - + if SNRmax == None: SNRmax = numpy.nanmax(SNRavgdB) + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True - - + + self.setWinTitle(title) - + if ((self.xmax - x[1]) < (x[1]-x[0])): x[1] = self.xmax - + strWind = ['Zonal','Vertical'] strCb = 'Velocity (m/s)' zmaxVector = [zmaxZonal, zmaxVertical] zminVector = [zminZonal, zminVertical] - + for i in range(nplotsw): - + title = "%s Drifts: %s" %(strWind[i], thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.__nsubplots] - - z1 = z[i,:].reshape((1,-1)) - + + z1 = z[i,:].reshape((1,-1)) + axes.pcolorbuffer(x, y, z1, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=zminVector[i], zmax=zmaxVector[i], xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel=strCb, cbsize="1%", colormap="RdBu_r") - + if dataOut.data_SNR is not None: - i += 1 + i += 1 if SNR_1: title = "Signal Noise Ratio + 1 (SNR+1): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) else: title = "Signal Noise Ratio (SNR): %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) axes = self.axesList[i*self.__nsubplots] - SNRavgdB = SNRavgdB.reshape((1,-1)) - + SNRavgdB = SNRavgdB.reshape((1,-1)) + axes.pcolorbuffer(x, y, SNRavgdB, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, zmin=SNRmin, zmax=SNRmax, xlabel=xlabel, ylabel=ylabel, title=title, rti=True, XAxisAsTime=True, ticksize=9, cblabel='', cbsize="1%", colormap="jet") - + self.draw() - + if x[1] >= self.axesList[0].xmax: self.counter_imagwr = wr_period self.isConfig = False self.figfile = None - - - - + + + + class PhasePlot(Figure): - + __isConfig = None __nsubplots = None PREFIX = 'mphase' - - def __init__(self): - + + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 24*60*60 self.isConfig = False self.__nsubplots = 1 @@ -1429,43 +1635,43 @@ class PhasePlot(Figure): self.HEIGHTPROF = 0 self.xdata = None self.ydata = None - + self.PLOT_CODE = MPHASE_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - - + + self.filename_phase = None - + self.figfile = None - + def getSubplots(self): - + ncol = 1 nrow = 1 - + return nrow, ncol - + def setup(self, id, nplots, wintitle, showprofile=True, show=True): - + self.__showprofile = showprofile self.nplots = nplots - + ncolspan = 7 colspan = 6 self.__nsubplots = 2 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH+self.WIDTHPROF, heightplot = self.HEIGHT+self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + self.addAxes(nrow, ncol*ncolspan, 0, 0, colspan, 1) @@ -1475,89 +1681,89 @@ class PhasePlot(Figure): save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0): - - + + tmin = None tmax = None x = dataOut.getTimeRange1(dataOut.outputInterval) y = dataOut.getHeiRange() - + #thisDatetime = dataOut.datatime thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) title = wintitle + " Phase of Beacon Signal" # : %s" %(thisDatetime.strftime("%d-%b-%Y")) xlabel = "Local Time" ylabel = "Phase" - - + + #phase = numpy.zeros((len(pairsIndexList),len(dataOut.beacon_heiIndexList))) phase_beacon = dataOut.data_output update_figfile = False - + if not self.isConfig: - + self.nplots = phase_beacon.size - + self.setup(id=id, nplots=self.nplots, wintitle=wintitle, showprofile=showprofile, show=show) - + if timerange is not None: - self.timerange = timerange - + self.timerange = timerange + self.xmin, self.xmax = self.getTimeLim(x, xmin, xmax, timerange) - + if ymin == None: ymin = numpy.nanmin(phase_beacon) - 10.0 if ymax == None: ymax = numpy.nanmax(phase_beacon) + 10.0 - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.name = thisDatetime.strftime("%Y%m%d_%H%M%S") self.isConfig = True self.figfile = figfile self.xdata = numpy.array([]) self.ydata = numpy.array([]) - + #open file beacon phase path = '%s%03d' %(self.PREFIX, self.id) beacon_file = os.path.join(path,'%s.txt'%self.name) self.filename_phase = os.path.join(figpath,beacon_file) update_figfile = True - - + + #store data beacon phase #self.save_data(self.filename_phase, phase_beacon, thisDatetime) - + self.setWinTitle(title) - - + + title = "Phase Offset %s" %(thisDatetime.strftime("%Y/%m/%d %H:%M:%S")) - + legendlabels = ["phase %d"%(chan) for chan in numpy.arange(self.nplots)] axes = self.axesList[0] - + self.xdata = numpy.hstack((self.xdata, x[0:1])) - + if len(self.ydata)==0: self.ydata = phase_beacon.reshape(-1,1) else: self.ydata = numpy.hstack((self.ydata, phase_beacon.reshape(-1,1))) - - + + axes.pmultilineyaxis(x=self.xdata, y=self.ydata, xmin=self.xmin, xmax=self.xmax, ymin=ymin, ymax=ymax, xlabel=xlabel, ylabel=ylabel, title=title, legendlabels=legendlabels, marker='x', markersize=8, linestyle="solid", XAxisAsTime=True, grid='both' ) - + self.draw() - + self.save(figpath=figpath, figfile=figfile, save=save, @@ -1565,23 +1771,23 @@ class PhasePlot(Figure): wr_period=wr_period, thisDatetime=thisDatetime, update_figfile=update_figfile) - + if dataOut.ltctime + dataOut.outputInterval >= self.xmax: self.counter_imagwr = wr_period self.isConfig = False update_figfile = True - - + + class NSMeteorDetection1Plot(Figure): - + isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'nsm' - + zminList = None zmaxList = None cmapList = None @@ -1589,71 +1795,71 @@ class NSMeteorDetection1Plot(Figure): nPairs = None nChannels = None nParam = None - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 750 self.HEIGHT = 250 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = SPEC_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - + self.__xfilter_ena = False self.__yfilter_ena = False - + def getSubplots(self): - + ncol = 3 nrow = int(numpy.ceil(self.nplots/3.0)) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, show=True): - + self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True, - xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None, + xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None, vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA', save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False, xaxis="frequency"): - + """ - + Input: dataOut : id : @@ -1669,33 +1875,33 @@ class NSMeteorDetection1Plot(Figure): """ #SEPARAR EN DOS PLOTS nParam = dataOut.data_param.shape[1] - 3 - - utctime = dataOut.data_param[0,0] + + utctime = dataOut.data_param[0,0] tmet = dataOut.data_param[:,1].astype(int) hmet = dataOut.data_param[:,2].astype(int) - + x = dataOut.abscissaList y = dataOut.heightList - + z = numpy.zeros((nParam, y.size, x.size - 1)) z[:,:] = numpy.nan z[:,hmet,tmet] = dataOut.data_param[:,3:].T z[0,:,:] = 10*numpy.log10(z[0,:,:]) - + xlabel = "Time (s)" ylabel = "Range (km)" - + thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) - + if not self.isConfig: - + nplots = nParam - + self.setup(id=id, nplots=nplots, wintitle=wintitle, show=show) - + if xmin is None: xmin = numpy.nanmin(x) if xmax is None: xmax = numpy.nanmax(x) if ymin is None: ymin = numpy.nanmin(y) @@ -1706,32 +1912,32 @@ class NSMeteorDetection1Plot(Figure): if vmin is None: vmin = -vmax if wmin is None: wmin = 0 if wmax is None: wmax = 50 - + pairsList = dataOut.groupList self.nPairs = len(dataOut.groupList) - + zminList = [SNRmin, vmin, cmin] + [pmin]*self.nPairs zmaxList = [SNRmax, vmax, cmax] + [pmax]*self.nPairs titleList = ["SNR","Radial Velocity","Coherence"] cmapList = ["jet","RdBu_r","jet"] - + for i in range(self.nPairs): strAux1 = "Phase Difference "+ str(pairsList[i][0]) + str(pairsList[i][1]) titleList = titleList + [strAux1] cmapList = cmapList + ["RdBu_r"] - + self.zminList = zminList self.zmaxList = zmaxList self.cmapList = cmapList self.titleList = titleList - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.isConfig = True - + str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) for i in range(nParam): @@ -1741,31 +1947,31 @@ class NSMeteorDetection1Plot(Figure): xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i], xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='') self.draw() - + if figfile == None: str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") name = str_datetime if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): - name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith) + name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith) figfile = self.getFilename(name) - + self.save(figpath=figpath, figfile=figfile, save=save, ftp=ftp, wr_period=wr_period, thisDatetime=thisDatetime) - + class NSMeteorDetection2Plot(Figure): - + isConfig = None __nsubplots = None - + WIDTHPROF = None HEIGHTPROF = None PREFIX = 'nsm' - + zminList = None zmaxList = None cmapList = None @@ -1773,71 +1979,71 @@ class NSMeteorDetection2Plot(Figure): nPairs = None nChannels = None nParam = None - - def __init__(self): - + + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 - + self.WIDTH = 750 self.HEIGHT = 250 self.WIDTHPROF = 120 self.HEIGHTPROF = 0 self.counter_imagwr = 0 - + self.PLOT_CODE = SPEC_CODE - + self.FTP_WEI = None self.EXP_CODE = None self.SUB_EXP_CODE = None self.PLOT_POS = None - + self.__xfilter_ena = False self.__yfilter_ena = False - + def getSubplots(self): - + ncol = 3 nrow = int(numpy.ceil(self.nplots/3.0)) - + return nrow, ncol - + def setup(self, id, nplots, wintitle, show=True): - + self.nplots = nplots - + ncolspan = 1 colspan = 1 - + self.createFigure(id = id, wintitle = wintitle, widthplot = self.WIDTH + self.WIDTHPROF, heightplot = self.HEIGHT + self.HEIGHTPROF, show=show) - + nrow, ncol = self.getSubplots() - + counter = 0 for y in range(nrow): for x in range(ncol): - + if counter >= self.nplots: break - + self.addAxes(nrow, ncol*ncolspan, y, x*ncolspan, colspan, 1) - + counter += 1 - + def run(self, dataOut, id, wintitle="", channelList=None, showprofile=True, - xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None, + xmin=None, xmax=None, ymin=None, ymax=None, SNRmin=None, SNRmax=None, vmin=None, vmax=None, wmin=None, wmax=None, mode = 'SA', save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False, xaxis="frequency"): - + """ - + Input: dataOut : id : @@ -1851,36 +2057,36 @@ class NSMeteorDetection2Plot(Figure): zmin : None, zmax : None """ - #Rebuild matrix - utctime = dataOut.data_param[0,0] + #Rebuild matrix + utctime = dataOut.data_param[0,0] cmet = dataOut.data_param[:,1].astype(int) tmet = dataOut.data_param[:,2].astype(int) hmet = dataOut.data_param[:,3].astype(int) - + nParam = 3 nChan = len(dataOut.groupList) x = dataOut.abscissaList y = dataOut.heightList - + z = numpy.full((nChan, nParam, y.size, x.size - 1),numpy.nan) z[cmet,:,hmet,tmet] = dataOut.data_param[:,4:] z[:,0,:,:] = 10*numpy.log10(z[:,0,:,:]) #logarithmic scale z = numpy.reshape(z, (nChan*nParam, y.size, x.size-1)) - + xlabel = "Time (s)" ylabel = "Range (km)" - + thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.ltctime) - + if not self.isConfig: - + nplots = nParam*nChan - + self.setup(id=id, nplots=nplots, wintitle=wintitle, show=show) - + if xmin is None: xmin = numpy.nanmin(x) if xmax is None: xmax = numpy.nanmax(x) if ymin is None: ymin = numpy.nanmin(y) @@ -1891,10 +2097,10 @@ class NSMeteorDetection2Plot(Figure): if vmin is None: vmin = -vmax if wmin is None: wmin = 0 if wmax is None: wmax = 50 - + self.nChannels = nChan - - zminList = [] + + zminList = [] zmaxList = [] titleList = [] cmapList = [] @@ -1902,24 +2108,24 @@ class NSMeteorDetection2Plot(Figure): strAux1 = "SNR Channel "+ str(i) strAux2 = "Radial Velocity Channel "+ str(i) strAux3 = "Spectral Width Channel "+ str(i) - + titleList = titleList + [strAux1,strAux2,strAux3] cmapList = cmapList + ["jet","RdBu_r","jet"] zminList = zminList + [SNRmin,vmin,wmin] zmaxList = zmaxList + [SNRmax,vmax,wmax] - + self.zminList = zminList self.zmaxList = zmaxList self.cmapList = cmapList self.titleList = titleList - + self.FTP_WEI = ftp_wei self.EXP_CODE = exp_code self.SUB_EXP_CODE = sub_exp_code self.PLOT_POS = plot_pos - + self.isConfig = True - + str_datetime = '%s %s'%(thisDatetime.strftime("%Y/%m/%d"),thisDatetime.strftime("%H:%M:%S")) for i in range(self.nplots): @@ -1929,19 +2135,17 @@ class NSMeteorDetection2Plot(Figure): xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, zmin=self.zminList[i], zmax=self.zmaxList[i], xlabel=xlabel, ylabel=ylabel, title=title, colormap=self.cmapList[i],ticksize=9, cblabel='') self.draw() - + if figfile == None: str_datetime = thisDatetime.strftime("%Y%m%d_%H%M%S") name = str_datetime if ((dataOut.azimuth!=None) and (dataOut.zenith!=None)): - name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith) + name = name + '_az' + '_%2.2f'%(dataOut.azimuth) + '_zn' + '_%2.2f'%(dataOut.zenith) figfile = self.getFilename(name) - + self.save(figpath=figpath, figfile=figfile, save=save, ftp=ftp, wr_period=wr_period, - thisDatetime=thisDatetime) - - + thisDatetime=thisDatetime) diff --git a/schainpy/model/graphics/jroplot_spectra.py b/schainpy/model/graphics/jroplot_spectra.py index 0f7b38d..eafac9f 100644 --- a/schainpy/model/graphics/jroplot_spectra.py +++ b/schainpy/model/graphics/jroplot_spectra.py @@ -10,6 +10,7 @@ import numpy from figure import Figure, isRealtime, isTimeInHourRange from plotting_codes import * + class SpectraPlot(Figure): isConfig = None @@ -19,8 +20,8 @@ class SpectraPlot(Figure): HEIGHTPROF = None PREFIX = 'spc' - def __init__(self): - + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 @@ -86,7 +87,7 @@ class SpectraPlot(Figure): save=False, figpath='./', figfile=None, show=True, ftp=False, wr_period=1, server=None, folder=None, username=None, password=None, ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, realtime=False, - xaxis="velocity", **kwargs): + xaxis="frequency", colormap='jet', normFactor=None): """ @@ -103,9 +104,6 @@ class SpectraPlot(Figure): zmin : None, zmax : None """ - - colormap = kwargs.get('colormap','jet') - if realtime: if not(isRealtime(utcdatatime = dataOut.utctime)): print 'Skipping this plot function' @@ -120,8 +118,10 @@ class SpectraPlot(Figure): raise ValueError, "Channel %d is not in dataOut.channelList" %channel channelIndexList.append(dataOut.channelList.index(channel)) - factor = dataOut.normFactor - + if normFactor is None: + factor = dataOut.normFactor + else: + factor = normFactor if xaxis == "frequency": x = dataOut.getFreqRange(1)/1000. xlabel = "Frequency (kHz)" @@ -230,8 +230,8 @@ class CrossSpectraPlot(Figure): HEIGHTPROF = None PREFIX = 'cspc' - def __init__(self): - + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 4 self.counter_imagwr = 0 @@ -282,7 +282,7 @@ class CrossSpectraPlot(Figure): save=False, figpath='./', figfile=None, ftp=False, wr_period=1, power_cmap='jet', coherence_cmap='jet', phase_cmap='RdBu_r', show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None, xaxis='frequency'): """ @@ -315,8 +315,11 @@ class CrossSpectraPlot(Figure): if len(pairsIndexList) > 4: pairsIndexList = pairsIndexList[0:4] - - factor = dataOut.normFactor + + if normFactor is None: + factor = dataOut.normFactor + else: + factor = normFactor x = dataOut.getVelRange(1) y = dataOut.getHeiRange() z = dataOut.data_spc[:,:,:]/factor @@ -447,8 +450,9 @@ class RTIPlot(Figure): HEIGHTPROF = None PREFIX = 'rti' - def __init__(self): + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = None self.isConfig = False self.__nsubplots = 1 @@ -516,10 +520,10 @@ class RTIPlot(Figure): def run(self, dataOut, id, wintitle="", channelList=None, showprofile='True', xmin=None, xmax=None, ymin=None, ymax=None, zmin=None, zmax=None, - timerange=None, + timerange=None, colormap='jet', save=False, figpath='./', lastone=0,figfile=None, ftp=False, wr_period=1, show=True, server=None, folder=None, username=None, password=None, - ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, **kwargs): + ftp_wei=0, exp_code=0, sub_exp_code=0, plot_pos=0, normFactor=None, HEIGHT=None): """ @@ -537,7 +541,10 @@ class RTIPlot(Figure): zmax : None """ - colormap = kwargs.get('colormap', 'jet') + #colormap = kwargs.get('colormap', 'jet') + if HEIGHT is not None: + self.HEIGHT = HEIGHT + if not isTimeInHourRange(dataOut.datatime, xmin, xmax): return @@ -550,20 +557,21 @@ class RTIPlot(Figure): raise ValueError, "Channel %d is not in dataOut.channelList" channelIndexList.append(dataOut.channelList.index(channel)) - if hasattr(dataOut, 'normFactor'): + if normFactor is None: factor = dataOut.normFactor else: - factor = 1 + factor = normFactor # factor = dataOut.normFactor x = dataOut.getTimeRange() y = dataOut.getHeiRange() -# z = dataOut.data_spc/factor -# z = numpy.where(numpy.isfinite(z), z, numpy.NAN) -# avg = numpy.average(z, axis=1) -# avgdB = 10.*numpy.log10(avg) - avgdB = dataOut.getPower() + z = dataOut.data_spc/factor + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + avg = numpy.average(z, axis=1) + avgdB = 10.*numpy.log10(avg) + # avgdB = dataOut.getPower() + thisDatetime = dataOut.datatime # thisDatetime = datetime.datetime.utcfromtimestamp(dataOut.getTimeRange()[0]) @@ -651,7 +659,8 @@ class CoherenceMap(Figure): HEIGHTPROF = None PREFIX = 'cmap' - def __init__(self): + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 2*60*60 self.isConfig = False self.__nsubplots = 1 @@ -855,7 +864,8 @@ class PowerProfilePlot(Figure): HEIGHTPROF = None PREFIX = 'spcprofile' - def __init__(self): + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 @@ -978,7 +988,8 @@ class SpectraCutPlot(Figure): HEIGHTPROF = None PREFIX = 'spc_cut' - def __init__(self): + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.__nsubplots = 1 @@ -1107,8 +1118,9 @@ class Noise(Figure): PREFIX = 'noise' - def __init__(self): + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 24*60*60 self.isConfig = False self.__nsubplots = 1 @@ -1307,8 +1319,8 @@ class BeaconPhase(Figure): PREFIX = 'beacon_phase' - def __init__(self): - + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.timerange = 24*60*60 self.isConfig = False self.__nsubplots = 1 diff --git a/schainpy/model/graphics/jroplot_voltage.py b/schainpy/model/graphics/jroplot_voltage.py index a9f3993..ed4dfc5 100644 --- a/schainpy/model/graphics/jroplot_voltage.py +++ b/schainpy/model/graphics/jroplot_voltage.py @@ -13,8 +13,8 @@ class Scope(Figure): isConfig = None - def __init__(self): - + def __init__(self, **kwargs): + Figure.__init__(self, **kwargs) self.isConfig = False self.WIDTH = 300 self.HEIGHT = 200 @@ -113,7 +113,7 @@ class Scope(Figure): def run(self, dataOut, id, wintitle="", channelList=None, xmin=None, xmax=None, ymin=None, ymax=None, save=False, figpath='./', figfile=None, show=True, wr_period=1, - ftp=False, server=None, folder=None, username=None, password=None, type='power'): + ftp=False, server=None, folder=None, username=None, password=None, type='power', **kwargs): """ diff --git a/schainpy/model/graphics/jroplotter.py b/schainpy/model/graphics/jroplotter.py index 8dddbb5..118ca9b 100644 --- a/schainpy/model/graphics/jroplotter.py +++ b/schainpy/model/graphics/jroplotter.py @@ -25,153 +25,153 @@ from jroplot_voltage import * class Plotter(Operation): - + isConfig = None name = None __queue = None - - def __init__(self, plotter_name, plotter_queue=None): - - Operation.__init__(self) - + + def __init__(self, plotter_name, plotter_queue=None, **kwargs): + + Operation.__init__(self, **kwargs) + self.isConfig = False self.name = plotter_name self.__queue = plotter_queue - + def getSubplots(self): - + nrow = self.nplots ncol = 1 return nrow, ncol - + def setup(self, **kwargs): - + print "Initializing ..." - - + + def run(self, dataOut, id=None, **kwargs): - + """ - + Input: dataOut : id : """ - + packDict = {} - + packDict['id'] = id packDict['name'] = self.name packDict['kwargs'] = kwargs - + # packDict['data'] = obj2Dict(dataOut) packDict['data'] = dataOut - + self.__queue.put(packDict) # class PlotManager(Thread): class PlotManager(): - + __err = False __stop = False __realtime = False - + controllerThreadObj = None - + plotterList = ['Scope', 'SpectraPlot', 'RTIPlot', 'SpectraCutPlot', 'CrossSpectraPlot', 'CoherenceMap', 'PowerProfilePlot', 'Noise', 'BeaconPhase', 'CorrelationPlot', - 'SpectraHeisScope','RTIfromSpectraHeis'] - + 'SpectraHeisScope', 'RTIfromSpectraHeis'] + def __init__(self, plotter_queue): - + # Thread.__init__(self) # self.setDaemon(True) - + self.__queue = plotter_queue self.__lock = Lock() - + self.plotInstanceDict = {} - + self.__err = False self.__stop = False self.__realtime = False - + def __handleError(self, name="", send_email=False): - + err = traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]) - + print "***** Error occurred in PlotManager *****" print "***** [%s]: %s" %(name, err[-1]) message = "\nError ocurred in %s:\n" %name message += "".join(err) - + sys.stderr.write(message) - + if not send_email: return - + import socket - + subject = "SChain v%s: Error running %s\n" %(schainpy.__version__, name) - + subtitle = "%s:\n" %(name) subtitle += "Hostname: %s\n" %socket.gethostbyname(socket.gethostname()) subtitle += "Working directory: %s\n" %os.path.abspath("./") # subtitle += "Configuration file: %s\n" %self.filename subtitle += "Time: %s\n" %str(datetime.datetime.now()) - + adminObj = schainpy.admin.SchainNotify() adminObj.sendAlert(message=message, subject=subject, subtitle=subtitle) - + def run(self): - + if self.__queue.empty(): return - + if self.__err: serial_data = self.__queue.get() self.__queue.task_done() return - + self.__lock.acquire() - + # if self.__queue.full(): # for i in range(int(self.__queue.qsize()/2)): # serial_data = self.__queue.get() # self.__queue.task_done() - + n = int(self.__queue.qsize()/3 + 1) - + for i in range(n): - + if self.__queue.empty(): break - + serial_data = self.__queue.get() self.__queue.task_done() - + plot_id = serial_data['id'] plot_name = serial_data['name'] kwargs = serial_data['kwargs'] # dataDict = serial_data['data'] -# +# # dataPlot = dict2Obj(dataDict) - + dataPlot = serial_data['data'] - + if plot_id not in self.plotInstanceDict.keys(): className = eval(plot_name) - self.plotInstanceDict[plot_id] = className() - + self.plotInstanceDict[plot_id] = className(**kwargs) + plotter = self.plotInstanceDict[plot_id] try: plotter.run(dataPlot, plot_id, **kwargs) @@ -179,62 +179,62 @@ class PlotManager(): self.__err = True self.__handleError(plot_name, send_email=True) break - + self.__lock.release() - + def isEmpty(self): - + return self.__queue.empty() - + def stop(self): - + self.__lock.acquire() - + self.__stop = True - + self.__lock.release() - + def close(self): - + self.__lock.acquire() - + for plot_id in self.plotInstanceDict.keys(): plotter = self.plotInstanceDict[plot_id] plotter.close() - + self.__lock.release() - + def setController(self, controllerThreadObj): - + self.controllerThreadObj = controllerThreadObj - + def start(self): - + if not self.controllerThreadObj.isRunning(): raise RuntimeError, "controllerThreadObj has not been initialized. Use controllerThreadObj.start() before call this method" - + self.join() - + def join(self): - + #Execute plotter while controller is running while self.controllerThreadObj.isRunning(): self.run() - + self.controllerThreadObj.stop() - + #Wait until plotter queue is empty while not self.isEmpty(): self.run() - + self.close() - + def isErrorDetected(self): - + self.__lock.acquire() - + err = self.__err - + self.__lock.release() - - return err \ No newline at end of file + + return err diff --git a/schainpy/model/graphics/mpldriver.py b/schainpy/model/graphics/mpldriver.py index 46a3d60..6173cd6 100644 --- a/schainpy/model/graphics/mpldriver.py +++ b/schainpy/model/graphics/mpldriver.py @@ -1,35 +1,45 @@ -import numpy -import datetime +import os import sys +import datetime +import numpy import matplotlib -if 'linux' in sys.platform: - matplotlib.use("TKAgg") - -if 'darwin' in sys.platform: - matplotlib.use('TKAgg') -#Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX' +if 'BACKEND' in os.environ: + matplotlib.use(os.environ['BACKEND']) +elif 'linux' in sys.platform: + matplotlib.use("TkAgg") +elif 'darwin' in sys.platform: + matplotlib.use('TkAgg') +else: + from schainpy.utils import log + log.warning('Using default Backend="Agg"', 'INFO') + matplotlib.use('Agg') +# Qt4Agg', 'GTK', 'GTKAgg', 'ps', 'agg', 'cairo', 'MacOSX', 'GTKCairo', 'WXAgg', 'template', 'TkAgg', 'GTK3Cairo', 'GTK3Agg', 'svg', 'WebAgg', 'CocoaAgg', 'emf', 'gdk', 'WX' import matplotlib.pyplot from mpl_toolkits.axes_grid1 import make_axes_locatable from matplotlib.ticker import FuncFormatter, LinearLocator ########################################### -#Actualizacion de las funciones del driver +# Actualizacion de las funciones del driver ########################################### # create jro colormap jet_values = matplotlib.pyplot.get_cmap("jet", 100)(numpy.arange(100))[10:90] -blu_values = matplotlib.pyplot.get_cmap("seismic_r", 20)(numpy.arange(20))[10:15] -ncmap = matplotlib.colors.LinearSegmentedColormap.from_list("jro", numpy.vstack((blu_values, jet_values))) +blu_values = matplotlib.pyplot.get_cmap( + "seismic_r", 20)(numpy.arange(20))[10:15] +ncmap = matplotlib.colors.LinearSegmentedColormap.from_list( + "jro", numpy.vstack((blu_values, jet_values))) matplotlib.pyplot.register_cmap(cmap=ncmap) -def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi = 80): + +def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi=80): matplotlib.pyplot.ioff() - fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=(1.0*width/dpi, 1.0*height/dpi)) + fig = matplotlib.pyplot.figure(num=id, facecolor=facecolor, figsize=( + 1.0 * width / dpi, 1.0 * height / dpi)) fig.canvas.manager.set_window_title(wintitle) # fig.canvas.manager.resize(width, height) matplotlib.pyplot.ion() @@ -39,10 +49,11 @@ def createFigure(id, wintitle, width, height, facecolor="w", show=True, dpi = 80 return fig + def closeFigure(show=False, fig=None): -# matplotlib.pyplot.ioff() -# matplotlib.pyplot.pause(0) + # matplotlib.pyplot.ioff() + # matplotlib.pyplot.pause(0) if show: matplotlib.pyplot.show() @@ -60,45 +71,52 @@ def closeFigure(show=False, fig=None): return + def saveFigure(fig, filename): -# matplotlib.pyplot.ioff() + # matplotlib.pyplot.ioff() fig.savefig(filename, dpi=matplotlib.pyplot.gcf().dpi) # matplotlib.pyplot.ion() + def clearFigure(fig): fig.clf() + def setWinTitle(fig, title): fig.canvas.manager.set_window_title(title) + def setTitle(fig, title): fig.suptitle(title) + def createAxes(fig, nrow, ncol, xpos, ypos, colspan, rowspan, polar=False): matplotlib.pyplot.ioff() matplotlib.pyplot.figure(fig.number) axes = matplotlib.pyplot.subplot2grid((nrow, ncol), - (xpos, ypos), - colspan=colspan, - rowspan=rowspan, - polar=polar) + (xpos, ypos), + colspan=colspan, + rowspan=rowspan, + polar=polar) matplotlib.pyplot.ion() return axes + def setAxesText(ax, text): ax.annotate(text, - xy = (.1, .99), - xycoords = 'figure fraction', - horizontalalignment = 'left', - verticalalignment = 'top', - fontsize = 10) + xy=(.1, .99), + xycoords='figure fraction', + horizontalalignment='left', + verticalalignment='top', + fontsize=10) + def printLabels(ax, xlabel, ylabel, title): @@ -106,11 +124,11 @@ def printLabels(ax, xlabel, ylabel, title): ax.set_ylabel(ylabel, size=11) ax.set_title(title, size=8) + def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', ticksize=9, xtick_visible=True, ytick_visible=True, nxticks=4, nyticks=10, - grid=None,color='blue'): - + grid=None, color='blue'): """ Input: @@ -119,18 +137,19 @@ def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='' matplotlib.pyplot.ioff() - ax.set_xlim([xmin,xmax]) - ax.set_ylim([ymin,ymax]) + ax.set_xlim([xmin, xmax]) + ax.set_ylim([ymin, ymax]) printLabels(ax, xlabel, ylabel, title) ###################################################### - if (xmax-xmin)<=1: - xtickspos = numpy.linspace(xmin,xmax,nxticks) - xtickspos = numpy.array([float("%.1f"%i) for i in xtickspos]) + if (xmax - xmin) <= 1: + xtickspos = numpy.linspace(xmin, xmax, nxticks) + xtickspos = numpy.array([float("%.1f" % i) for i in xtickspos]) ax.set_xticks(xtickspos) else: - xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin) + xtickspos = numpy.arange(nxticks) * \ + int((xmax - xmin) / (nxticks)) + int(xmin) # xtickspos = numpy.arange(nxticks)*float(xmax-xmin)/float(nxticks) + int(xmin) ax.set_xticks(xtickspos) @@ -168,9 +187,11 @@ def createPline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='' return iplot + def set_linedata(ax, x, y, idline): - ax.lines[idline].set_data(x,y) + ax.lines[idline].set_data(x, y) + def pline(iplot, x, y, xlabel='', ylabel='', title=''): @@ -180,14 +201,15 @@ def pline(iplot, x, y, xlabel='', ylabel='', title=''): set_linedata(ax, x, y, idline=0) + def addpline(ax, x, y, color, linestyle, lw): - ax.plot(x,y,color=color,linestyle=linestyle,lw=lw) + ax.plot(x, y, color=color, linestyle=linestyle, lw=lw) def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, - xlabel='', ylabel='', title='', ticksize = 9, - colormap='jet',cblabel='', cbsize="5%", + xlabel='', ylabel='', title='', ticksize=9, + colormap='jet', cblabel='', cbsize="5%", XAxisAsTime=False): matplotlib.pyplot.ioff() @@ -197,16 +219,16 @@ def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, fig = ax.get_figure() fig.add_axes(ax_cb) - ax.set_xlim([xmin,xmax]) - ax.set_ylim([ymin,ymax]) + ax.set_xlim([xmin, xmax]) + ax.set_ylim([ymin, ymax]) printLabels(ax, xlabel, ylabel, title) z = numpy.ma.masked_invalid(z) - cmap=matplotlib.pyplot.get_cmap(colormap) - cmap.set_bad('white', 1.) - imesh = ax.pcolormesh(x,y,z.T, vmin=zmin, vmax=zmax, cmap=cmap) - cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb) + cmap = matplotlib.pyplot.get_cmap(colormap) + cmap.set_bad('black', 1.) + imesh = ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap) + cb = matplotlib.pyplot.colorbar(imesh, cax=ax_cb) cb.set_label(cblabel) # for tl in ax_cb.get_yticklabels(): @@ -235,13 +257,15 @@ def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax, if XAxisAsTime: - func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S")) + def func(x, pos): return ('%s') % ( + datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S")) ax.xaxis.set_major_formatter(FuncFormatter(func)) ax.xaxis.set_major_locator(LinearLocator(7)) matplotlib.pyplot.ion() return imesh + def pcolor(imesh, z, xlabel='', ylabel='', title=''): z = z.T @@ -249,11 +273,14 @@ def pcolor(imesh, z, xlabel='', ylabel='', title=''): printLabels(ax, xlabel, ylabel, title) imesh.set_array(z.ravel()) + def addpcolor(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'): printLabels(ax, xlabel, ylabel, title) - ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=matplotlib.pyplot.get_cmap(colormap)) + ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, + cmap=matplotlib.pyplot.get_cmap(colormap)) + def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', colormap='jet'): @@ -262,18 +289,17 @@ def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', col ax.collections.remove(ax.collections[0]) z = numpy.ma.masked_invalid(z) - - cmap=matplotlib.pyplot.get_cmap(colormap) - cmap.set_bad('white', 1.) - - ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=cmap) + cmap = matplotlib.pyplot.get_cmap(colormap) + cmap.set_bad('black', 1.) + + ax.pcolormesh(x, y, z.T, vmin=zmin, vmax=zmax, cmap=cmap) -def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None, - ticksize=9, xtick_visible=True, ytick_visible=True, - nxticks=4, nyticks=10, - grid=None): +def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None, + ticksize=9, xtick_visible=True, ytick_visible=True, + nxticks=4, nyticks=10, + grid=None): """ Input: @@ -285,11 +311,12 @@ def createPmultiline(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', tit lines = ax.plot(x.T, y) leg = ax.legend(lines, legendlabels, loc='upper right') leg.get_frame().set_alpha(0.5) - ax.set_xlim([xmin,xmax]) - ax.set_ylim([ymin,ymax]) + ax.set_xlim([xmin, xmax]) + ax.set_ylim([ymin, ymax]) printLabels(ax, xlabel, ylabel, title) - xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin) + xtickspos = numpy.arange(nxticks) * \ + int((xmax - xmin) / (nxticks)) + int(xmin) ax.set_xticks(xtickspos) for tick in ax.get_xticklabels(): @@ -332,13 +359,13 @@ def pmultiline(iplot, x, y, xlabel='', ylabel='', title=''): for i in range(len(ax.lines)): line = ax.lines[i] - line.set_data(x[i,:],y) + line.set_data(x[i, :], y) -def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None, - ticksize=9, xtick_visible=True, ytick_visible=True, - nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None", - grid=None, XAxisAsTime=False): +def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='', title='', legendlabels=None, + ticksize=9, xtick_visible=True, ytick_visible=True, + nxticks=4, nyticks=10, marker='.', markersize=10, linestyle="None", + grid=None, XAxisAsTime=False): """ Input: @@ -355,10 +382,11 @@ def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='' leg = ax.legend(lines, legendlabels, loc='upper right', bbox_to_anchor=(1.16, 1), borderaxespad=0) - for label in leg.get_texts(): label.set_fontsize(9) + for label in leg.get_texts(): + label.set_fontsize(9) - ax.set_xlim([xmin,xmax]) - ax.set_ylim([ymin,ymax]) + ax.set_xlim([xmin, xmax]) + ax.set_ylim([ymin, ymax]) printLabels(ax, xlabel, ylabel, title) # xtickspos = numpy.arange(nxticks)*int((xmax-xmin)/(nxticks)) + int(xmin) @@ -393,7 +421,8 @@ def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='' if XAxisAsTime: - func = lambda x, pos: ('%s') %(datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S")) + def func(x, pos): return ('%s') % ( + datetime.datetime.utcfromtimestamp(x).strftime("%H:%M:%S")) ax.xaxis.set_major_formatter(FuncFormatter(func)) ax.xaxis.set_major_locator(LinearLocator(7)) @@ -401,6 +430,7 @@ def createPmultilineYAxis(ax, x, y, xmin, xmax, ymin, ymax, xlabel='', ylabel='' return iplot + def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''): ax = iplot.axes @@ -409,19 +439,20 @@ def pmultilineyaxis(iplot, x, y, xlabel='', ylabel='', title=''): for i in range(len(ax.lines)): line = ax.lines[i] - line.set_data(x,y[i,:]) + line.set_data(x, y[i, :]) + def createPolar(ax, x, y, - xlabel='', ylabel='', title='', ticksize = 9, - colormap='jet',cblabel='', cbsize="5%", - XAxisAsTime=False): + xlabel='', ylabel='', title='', ticksize=9, + colormap='jet', cblabel='', cbsize="5%", + XAxisAsTime=False): matplotlib.pyplot.ioff() - ax.plot(x,y,'bo', markersize=5) + ax.plot(x, y, 'bo', markersize=5) # ax.set_rmax(90) - ax.set_ylim(0,90) - ax.set_yticks(numpy.arange(0,90,20)) + ax.set_ylim(0, 90) + ax.set_yticks(numpy.arange(0, 90, 20)) # ax.text(0, -110, ylabel, rotation='vertical', va ='center', ha = 'center' ,size='11') # ax.text(0, 50, ylabel, rotation='vertical', va ='center', ha = 'left' ,size='11') # ax.text(100, 100, 'example', ha='left', va='center', rotation='vertical') @@ -444,9 +475,9 @@ def createPolar(ax, x, y, matplotlib.pyplot.ion() - return iplot + def polar(iplot, x, y, xlabel='', ylabel='', title=''): ax = iplot.axes @@ -456,6 +487,7 @@ def polar(iplot, x, y, xlabel='', ylabel='', title=''): set_linedata(ax, x, y, idline=0) + def draw(fig): if type(fig) == 'int': @@ -463,6 +495,7 @@ def draw(fig): fig.canvas.draw() + def pause(interval=0.000001): matplotlib.pyplot.pause(interval) diff --git a/schainpy/model/io/MIRAtest.py b/schainpy/model/io/MIRAtest.py new file mode 100644 index 0000000..ea8e94f --- /dev/null +++ b/schainpy/model/io/MIRAtest.py @@ -0,0 +1,331 @@ +import os +import sys +import glob +import fnmatch +import datetime +import time +import re +import h5py +import numpy + +from scipy.optimize import curve_fit +from scipy import asarray as ar, exp +from scipy import stats + +from duplicity.path import Path +from numpy.ma.core import getdata + +SPEED_OF_LIGHT = 299792458 +SPEED_OF_LIGHT = 3e8 + +try: + from gevent import sleep +except: + from time import sleep + +from schainpy.model.data.jrodata import Spectra +#from schainpy.model.data.BLTRheaderIO import FileHeader, RecordHeader +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +#from schainpy.model.io.jroIO_bltr import BLTRReader +from numpy import imag, shape, NaN + + +startFp = open( + '/home/erick/Documents/MIRA35C/20160117/20160117_0000.zspc', "rb") + + +FILE_HEADER = numpy.dtype([ # HEADER 1024bytes + ('Hname', numpy.str_, 32), # Original file name + # Date and time when the file was created + ('Htime', numpy.str_, 32), + # Name of operator who created the file + ('Hoper', numpy.str_, 64), + # Place where the measurements was carried out + ('Hplace', numpy.str_, 128), + # Description of measurements + ('Hdescr', numpy.str_, 256), + ('Hdummy', numpy.str_, 512), # Reserved space + # Main chunk + ('Msign', '=5 + ('SPARrawGate1', ' dateFile) or (endDate < dateFile): + continue + + self.fileList.append(thisFile) + self.dateFileList.append(dateFile) + + return + + def setNextFile(self): + + file_id = self.fileIndex + + if file_id == len(self.fileList): + log.success('No more files in the folder', 'BLTRParamReader') + self.flagNoMoreFiles = 1 + return 0 + + log.success('Opening {}'.format(self.fileList[file_id]), 'BLTRParamReader') + filename = os.path.join(self.path, self.fileList[file_id]) + + dirname, name = os.path.split(filename) + # 'peru2' ---> Piura - 'peru1' ---> Huancayo or Porcuya + self.siteFile = name.split('.')[0] + if self.filename is not None: + self.fp.close() + self.filename = filename + self.fp = open(self.filename, 'rb') + self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1) + self.nrecords = self.header_file['nrec'][0] + self.sizeOfFile = os.path.getsize(self.filename) + self.counter_records = 0 + self.flagIsNewFile = 0 + self.fileIndex += 1 + + return 1 + + def readNextBlock(self): + + while True: + if self.counter_records == self.nrecords: + self.flagIsNewFile = 1 + if not self.setNextFile(): + return 0 + + self.readBlock() + + if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \ + (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)): + log.warning( + 'Reading Record No. {}/{} -> {} [Skipping]'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), + 'BLTRParamReader') + continue + break + + log.log('Reading Record No. {}/{} -> {}'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), 'BLTRParamReader') + + return 1 + + def readBlock(self): + + pointer = self.fp.tell() + header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1) + self.nchannels = header_rec['nchan'][0] / 2 + self.kchan = header_rec['nrxs'][0] + self.nmodes = header_rec['nmodes'][0] + self.nranges = header_rec['nranges'][0] + self.fp.seek(pointer) + self.height = numpy.empty((self.nmodes, self.nranges)) + self.snr = numpy.empty((self.nmodes, self.nchannels, self.nranges)) + self.buffer = numpy.empty((self.nmodes, 3, self.nranges)) + self.flagDiscontinuousBlock = 0 + + for mode in range(self.nmodes): + self.readHeader() + data = self.readData() + self.height[mode] = (data[0] - self.correction) / 1000. + self.buffer[mode] = data[1] + self.snr[mode] = data[2] + + self.counter_records = self.counter_records + self.nmodes + + return + + def readHeader(self): + ''' + RecordHeader of BLTR rawdata file + ''' + + header_structure = numpy.dtype( + REC_HEADER_STRUCTURE.descr + [ + ('antenna_coord', 'f4', (2, self.nchannels)), + ('rx_gains', 'u4', (self.nchannels,)), + ('rx_analysis', 'u4', (self.nchannels,)) + ] + ) + + self.header_rec = numpy.fromfile(self.fp, header_structure, 1) + self.lat = self.header_rec['lat'][0] + self.lon = self.header_rec['lon'][0] + self.delta = self.header_rec['delta_r'][0] + self.correction = self.header_rec['dmode_rngcorr'][0] + self.imode = self.header_rec['dmode_index'][0] + self.antenna = self.header_rec['antenna_coord'] + self.rx_gains = self.header_rec['rx_gains'] + self.time = self.header_rec['time'][0] + dt = datetime.datetime.utcfromtimestamp(self.time) + if dt.date()>self.datatime.date(): + self.flagDiscontinuousBlock = 1 + self.datatime = dt + + def readData(self): + ''' + Reading and filtering data block record of BLTR rawdata file, filtering is according to status_value. + + Input: + status_value - Array data is set to NAN for values that are not equal to status_value + + ''' + + data_structure = numpy.dtype( + DATA_STRUCTURE.descr + [ + ('rx_saturation', 'u4', (self.nchannels,)), + ('chan_offset', 'u4', (2 * self.nchannels,)), + ('rx_amp', 'u4', (self.nchannels,)), + ('rx_snr', 'f4', (self.nchannels,)), + ('cross_snr', 'f4', (self.kchan,)), + ('sea_power_relative', 'f4', (self.kchan,))] + ) + + data = numpy.fromfile(self.fp, data_structure, self.nranges) + + height = data['range'] + winds = numpy.array( + (data['zonal'], data['meridional'], data['vertical'])) + snr = data['rx_snr'].T + + winds[numpy.where(winds == -9999.)] = numpy.nan + winds[:, numpy.where(data['status'] != self.status_value)] = numpy.nan + snr[numpy.where(snr == -9999.)] = numpy.nan + snr[:, numpy.where(data['status'] != self.status_value)] = numpy.nan + snr = numpy.power(10, snr / 10) + + return height, winds, snr + + def set_output(self): + ''' + Storing data from databuffer to dataOut object + ''' + + self.dataOut.data_SNR = self.snr + self.dataOut.height = self.height + self.dataOut.data = self.buffer + self.dataOut.utctimeInit = self.time + self.dataOut.utctime = self.dataOut.utctimeInit + self.dataOut.useLocalTime = False + self.dataOut.paramInterval = 157 + self.dataOut.timezone = self.timezone + self.dataOut.site = self.siteFile + self.dataOut.nrecords = self.nrecords / self.nmodes + self.dataOut.sizeOfFile = self.sizeOfFile + self.dataOut.lat = self.lat + self.dataOut.lon = self.lon + self.dataOut.channelList = range(self.nchannels) + self.dataOut.kchan = self.kchan + self.dataOut.delta = self.delta + self.dataOut.correction = self.correction + self.dataOut.nmodes = self.nmodes + self.dataOut.imode = self.imode + self.dataOut.antenna = self.antenna + self.dataOut.rx_gains = self.rx_gains + self.dataOut.flagNoData = False + self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock + + def getData(self): + ''' + Storing data from databuffer to dataOut object + ''' + if self.flagNoMoreFiles: + self.dataOut.flagNoData = True + log.success('No file left to process', 'BLTRParamReader') + return 0 + + if not self.readNextBlock(): + self.dataOut.flagNoData = True + return 0 + + self.set_output() + + return 1 diff --git a/schainpy/model/io/jroIO_amisr.py b/schainpy/model/io/jroIO_amisr.py index adf4e9d..3be5aaa 100644 --- a/schainpy/model/io/jroIO_amisr.py +++ b/schainpy/model/io/jroIO_amisr.py @@ -267,7 +267,7 @@ class AMISRReader(ProcessingUnit): self.dirnameList = new_dirnameList return 1 - def __searchFilesOnline(self, + def searchFilesOnLine(self, path, walk=True): @@ -287,7 +287,7 @@ class AMISRReader(ProcessingUnit): return - def __searchFilesOffline(self, + def searchFilesOffLine(self, path, startDate, endDate, @@ -494,9 +494,9 @@ class AMISRReader(ProcessingUnit): self.online = online if not(online): #Busqueda de archivos offline - self.__searchFilesOffline(path, startDate, endDate, startTime, endTime, walk) + self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk) else: - self.__searchFilesOnline(path, walk) + self.searchFilesOnLine(path, walk) if not(self.filenameList): print "There is no files into the folder: %s"%(path) diff --git a/schainpy/model/io/jroIO_base.py b/schainpy/model/io/jroIO_base.py index de1e1b2..790e5ac 100644 --- a/schainpy/model/io/jroIO_base.py +++ b/schainpy/model/io/jroIO_base.py @@ -9,364 +9,374 @@ import glob import time import numpy import fnmatch -import time, datetime -#import h5py +import inspect +import time +import datetime import traceback +import zmq try: from gevent import sleep except: from time import sleep - + +import schainpy.admin from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader from schainpy.model.data.jroheaderIO import get_dtype_index, get_numpy_dtype, get_procflag_dtype, get_dtype_width +from schainpy.utils import log +import schainpy.admin LOCALTIME = True + def isNumber(cad): """ Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero. - Excepciones: + Excepciones: Si un determinado string no puede ser convertido a numero Input: str, string al cual se le analiza para determinar si convertible a un numero o no - + Return: True : si el string es uno numerico False : no es un string numerico """ try: - float( cad ) + float(cad) return True except: return False + def isFileInEpoch(filename, startUTSeconds, endUTSeconds): """ Esta funcion determina si un archivo de datos se encuentra o no dentro del rango de fecha especificado. - + Inputs: filename : nombre completo del archivo de datos en formato Jicamarca (.r) - + startUTSeconds : fecha inicial del rango seleccionado. La fecha esta dada en segundos contados desde 01/01/1970. endUTSeconds : fecha final del rango seleccionado. La fecha esta dada en segundos contados desde 01/01/1970. - + Return: Boolean : Retorna True si el archivo de datos contiene datos en el rango de fecha especificado, de lo contrario retorna False. - + Excepciones: Si el archivo no existe o no puede ser abierto Si la cabecera no puede ser leida. - + """ basicHeaderObj = BasicHeader(LOCALTIME) - + try: - fp = open(filename,'rb') + fp = open(filename, 'rb') except IOError: - print "The file %s can't be opened" %(filename) + print "The file %s can't be opened" % (filename) return 0 - + sts = basicHeaderObj.read(fp) fp.close() - + if not(sts): - print "Skipping the file %s because it has not a valid header" %(filename) + print "Skipping the file %s because it has not a valid header" % (filename) return 0 - + if not ((startUTSeconds <= basicHeaderObj.utc) and (endUTSeconds > basicHeaderObj.utc)): return 0 - + return 1 + def isTimeInRange(thisTime, startTime, endTime): - if endTime >= startTime: if (thisTime < startTime) or (thisTime > endTime): return 0 - return 1 else: if (thisTime < startTime) and (thisTime > endTime): return 0 - return 1 - + + def isFileInTimeRange(filename, startDate, endDate, startTime, endTime): """ Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. - + Inputs: filename : nombre completo del archivo de datos en formato Jicamarca (.r) - + startDate : fecha inicial del rango seleccionado en formato datetime.date - + endDate : fecha final del rango seleccionado en formato datetime.date - + startTime : tiempo inicial del rango seleccionado en formato datetime.time - + endTime : tiempo final del rango seleccionado en formato datetime.time - + Return: Boolean : Retorna True si el archivo de datos contiene datos en el rango de fecha especificado, de lo contrario retorna False. - + Excepciones: Si el archivo no existe o no puede ser abierto Si la cabecera no puede ser leida. - + """ - - + try: - fp = open(filename,'rb') + fp = open(filename, 'rb') except IOError: - print "The file %s can't be opened" %(filename) + print "The file %s can't be opened" % (filename) return None - + firstBasicHeaderObj = BasicHeader(LOCALTIME) systemHeaderObj = SystemHeader() radarControllerHeaderObj = RadarControllerHeader() processingHeaderObj = ProcessingHeader() - + lastBasicHeaderObj = BasicHeader(LOCALTIME) - + sts = firstBasicHeaderObj.read(fp) - + if not(sts): - print "[Reading] Skipping the file %s because it has not a valid header" %(filename) + print "[Reading] Skipping the file %s because it has not a valid header" % (filename) return None - + if not systemHeaderObj.read(fp): return None - + if not radarControllerHeaderObj.read(fp): return None - + if not processingHeaderObj.read(fp): return None - + filesize = os.path.getsize(filename) - - offset = processingHeaderObj.blockSize + 24 #header size - + + offset = processingHeaderObj.blockSize + 24 # header size + if filesize <= offset: - print "[Reading] %s: This file has not enough data" %filename + print "[Reading] %s: This file has not enough data" % filename return None - + fp.seek(-offset, 2) - + sts = lastBasicHeaderObj.read(fp) - + fp.close() - + thisDatetime = lastBasicHeaderObj.datatime thisTime_last_block = thisDatetime.time() - + thisDatetime = firstBasicHeaderObj.datatime thisDate = thisDatetime.date() thisTime_first_block = thisDatetime.time() - - #General case + + # General case # o>>>>>>>>>>>>>><<<<<<<<<<<<<= startTime: if (thisTime_last_block < startTime) or (thisTime_first_block > endTime): return None - + return thisDatetime - - #If endTime < startTime then endTime belongs to the next day - - + + # If endTime < startTime then endTime belongs to the next day + #<<<<<<<<<<>>>>>>>>>> #-----------o----------------------------o----------- # endTime startTime - + if (thisDate == startDate) and (thisTime_last_block < startTime): return None - + if (thisDate == endDate) and (thisTime_first_block > endTime): return None - + if (thisTime_last_block < startTime) and (thisTime_first_block > endTime): return None - + return thisDatetime + def isFolderInDateRange(folder, startDate=None, endDate=None): """ Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. - + Inputs: folder : nombre completo del directorio. Su formato deberia ser "/path_root/?YYYYDDD" - + siendo: YYYY : Anio (ejemplo 2015) DDD : Dia del anio (ejemplo 305) - + startDate : fecha inicial del rango seleccionado en formato datetime.date - + endDate : fecha final del rango seleccionado en formato datetime.date - + Return: Boolean : Retorna True si el archivo de datos contiene datos en el rango de fecha especificado, de lo contrario retorna False. Excepciones: Si el directorio no tiene el formato adecuado """ - + basename = os.path.basename(folder) - + if not isRadarFolder(basename): - print "The folder %s has not the rigth format" %folder + print "The folder %s has not the rigth format" % folder return 0 - + if startDate and endDate: thisDate = getDateFromRadarFolder(basename) - + if thisDate < startDate: return 0 - + if thisDate > endDate: return 0 - + return 1 + def isFileInDateRange(filename, startDate=None, endDate=None): """ Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. - + Inputs: filename : nombre completo del archivo de datos en formato Jicamarca (.r) - + Su formato deberia ser "?YYYYDDDsss" - + siendo: YYYY : Anio (ejemplo 2015) DDD : Dia del anio (ejemplo 305) sss : set - + startDate : fecha inicial del rango seleccionado en formato datetime.date - + endDate : fecha final del rango seleccionado en formato datetime.date - + Return: Boolean : Retorna True si el archivo de datos contiene datos en el rango de fecha especificado, de lo contrario retorna False. Excepciones: Si el archivo no tiene el formato adecuado """ - + basename = os.path.basename(filename) - + if not isRadarFile(basename): - print "The filename %s has not the rigth format" %filename + print "The filename %s has not the rigth format" % filename return 0 - + if startDate and endDate: thisDate = getDateFromRadarFile(basename) - + if thisDate < startDate: return 0 - + if thisDate > endDate: return 0 - + return 1 + def getFileFromSet(path, ext, set): validFilelist = [] fileList = os.listdir(path) - + # 0 1234 567 89A BCDE # H YYYY DDD SSS .ext - + for thisFile in fileList: try: year = int(thisFile[1:5]) - doy = int(thisFile[5:8]) + doy = int(thisFile[5:8]) except: continue - + if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): continue - + validFilelist.append(thisFile) - myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set)) - - if len(myfile)!= 0: + myfile = fnmatch.filter( + validFilelist, '*%4.4d%3.3d%3.3d*' % (year, doy, set)) + + if len(myfile) != 0: return myfile[0] else: - filename = '*%4.4d%3.3d%3.3d%s'%(year,doy,set,ext.lower()) - print 'the filename %s does not exist'%filename + filename = '*%4.4d%3.3d%3.3d%s' % (year, doy, set, ext.lower()) + print 'the filename %s does not exist' % filename print '...going to the last file: ' - + if validFilelist: - validFilelist = sorted( validFilelist, key=str.lower ) + validFilelist = sorted(validFilelist, key=str.lower) return validFilelist[-1] return None + def getlastFileFromPath(path, ext): """ Depura el fileList dejando solo los que cumplan el formato de "PYYYYDDDSSS.ext" - al final de la depuracion devuelve el ultimo file de la lista que quedo. - - Input: + al final de la depuracion devuelve el ultimo file de la lista que quedo. + + Input: fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta - ext : extension de los files contenidos en una carpeta - + ext : extension de los files contenidos en una carpeta + Return: El ultimo file de una determinada carpeta, no se considera el path. """ validFilelist = [] fileList = os.listdir(path) - + # 0 1234 567 89A BCDE # H YYYY DDD SSS .ext - + for thisFile in fileList: - + year = thisFile[1:5] if not isNumber(year): continue - + doy = thisFile[5:8] if not isNumber(doy): continue - + year = int(year) doy = int(doy) - + if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): continue - + validFilelist.append(thisFile) if validFilelist: - validFilelist = sorted( validFilelist, key=str.lower ) + validFilelist = sorted(validFilelist, key=str.lower) return validFilelist[-1] return None + def checkForRealPath(path, foldercounter, year, doy, set, ext): """ Por ser Linux Case Sensitive entonces checkForRealPath encuentra el nombre correcto de un path, Prueba por varias combinaciones de nombres entre mayusculas y minusculas para determinar el path exacto de un determinado file. - + Example : nombre correcto del file es .../.../D2009307/P2009307367.ext - + Entonces la funcion prueba con las siguientes combinaciones .../.../y2009307367.ext .../.../Y2009307367.ext @@ -374,39 +384,43 @@ def checkForRealPath(path, foldercounter, year, doy, set, ext): .../.../x2009307/Y2009307367.ext .../.../X2009307/y2009307367.ext .../.../X2009307/Y2009307367.ext - siendo para este caso, la ultima combinacion de letras, identica al file buscado - + siendo para este caso, la ultima combinacion de letras, identica al file buscado + Return: - Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file - caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas - para el filename + Si encuentra la cobinacion adecuada devuelve el path completo y el nombre del file + caso contrario devuelve None como path y el la ultima combinacion de nombre en mayusculas + para el filename """ fullfilename = None find_flag = False filename = None - - prefixDirList = [None,'d','D'] - if ext.lower() == ".r": #voltage - prefixFileList = ['d','D'] - elif ext.lower() == ".pdata": #spectra - prefixFileList = ['p','P'] + + prefixDirList = [None, 'd', 'D'] + if ext.lower() == ".r": # voltage + prefixFileList = ['d', 'D'] + elif ext.lower() == ".pdata": # spectra + prefixFileList = ['p', 'P'] else: return None, filename - - #barrido por las combinaciones posibles + + # barrido por las combinaciones posibles for prefixDir in prefixDirList: thispath = path if prefixDir != None: - #formo el nombre del directorio xYYYYDDD (x=d o x=D) + # formo el nombre del directorio xYYYYDDD (x=d o x=D) if foldercounter == 0: - thispath = os.path.join(path, "%s%04d%03d" % ( prefixDir, year, doy )) + thispath = os.path.join(path, "%s%04d%03d" % + (prefixDir, year, doy)) else: - thispath = os.path.join(path, "%s%04d%03d_%02d" % ( prefixDir, year, doy , foldercounter)) - for prefixFile in prefixFileList: #barrido por las dos combinaciones posibles de "D" - filename = "%s%04d%03d%03d%s" % ( prefixFile, year, doy, set, ext ) #formo el nombre del file xYYYYDDDSSS.ext - fullfilename = os.path.join( thispath, filename ) #formo el path completo - - if os.path.exists( fullfilename ): #verifico que exista + thispath = os.path.join(path, "%s%04d%03d_%02d" % ( + prefixDir, year, doy, foldercounter)) + for prefixFile in prefixFileList: # barrido por las dos combinaciones posibles de "D" + # formo el nombre del file xYYYYDDDSSS.ext + filename = "%s%04d%03d%03d%s" % (prefixFile, year, doy, set, ext) + fullfilename = os.path.join( + thispath, filename) # formo el path completo + + if os.path.exists(fullfilename): # verifico que exista find_flag = True break if find_flag: @@ -417,36 +431,40 @@ def checkForRealPath(path, foldercounter, year, doy, set, ext): return fullfilename, filename + def isRadarFolder(folder): try: year = int(folder[1:5]) doy = int(folder[5:8]) except: return 0 - + return 1 + def isRadarFile(file): - try: - year = int(file[1:5]) - doy = int(file[5:8]) - set = int(file[8:11]) - except: - return 0 - - return 1 + try: + year = int(file[1:5]) + doy = int(file[5:8]) + set = int(file[8:11]) + except: + return 0 + + return 1 + def getDateFromRadarFile(file): - try: + try: year = int(file[1:5]) doy = int(file[5:8]) - set = int(file[8:11]) + set = int(file[8:11]) except: return None - thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1) + thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1) return thisDate + def getDateFromRadarFolder(folder): try: year = int(folder[1:5]) @@ -454,140 +472,144 @@ def getDateFromRadarFolder(folder): except: return None - thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy-1) + thisDate = datetime.date(year, 1, 1) + datetime.timedelta(doy - 1) return thisDate - + + class JRODataIO: - + c = 3E8 - + isConfig = False - + basicHeaderObj = None - + systemHeaderObj = None - + radarControllerHeaderObj = None - + processingHeaderObj = None - + dtype = None - + pathList = [] - + filenameList = [] - + filename = None - + ext = None - + flagIsNewFile = 1 - + flagDiscontinuousBlock = 0 - + flagIsNewBlock = 0 - + fp = None - + firstHeaderSize = 0 - + basicHeaderSize = 24 - + versionFile = 1103 - + fileSize = None - + # ippSeconds = None - + fileSizeByHeader = None - + fileIndex = None - + profileIndex = None - + blockIndex = None - + nTotalBlocks = None - + maxTimeStep = 30 - + lastUTTime = None - + datablock = None - + dataOut = None - + blocksize = None - + getByBlock = False - + def __init__(self): - + raise NotImplementedError - + def run(self): - + raise NotImplementedError def getDtypeWidth(self): - + dtype_index = get_dtype_index(self.dtype) dtype_width = get_dtype_width(dtype_index) - + return dtype_width - + + def getAllowedArgs(self): + if hasattr(self, '__attrs__'): + return self.__attrs__ + else: + return inspect.getargspec(self.run).args + + class JRODataReader(JRODataIO): - - + online = 0 - + realtime = 0 - + nReadBlocks = 0 - - delay = 10 #number of seconds waiting a new file - - nTries = 3 #quantity tries - - nFiles = 3 #number of files for searching - + + delay = 10 # number of seconds waiting a new file + + nTries = 3 # quantity tries + + nFiles = 3 # number of files for searching + path = None - + foldercounter = 0 - + flagNoMoreFiles = 0 - + datetimeList = [] - + __isFirstTimeOnline = 1 - + __printInfo = True - + profileIndex = None - + nTxs = 1 - + txIndex = None - - #Added-------------------- - + + # Added-------------------- + selBlocksize = None - + selBlocktime = None - - + def __init__(self): - """ This class is used to find data files - + Example: reader = JRODataReader() fileList = reader.findDataFiles() - + """ pass - def createObjByDefault(self): """ @@ -596,88 +618,92 @@ class JRODataReader(JRODataIO): raise NotImplementedError def getBlockDimension(self): - + raise NotImplementedError - def __searchFilesOffLine(self, - path, - startDate=None, - endDate=None, - startTime=datetime.time(0,0,0), - endTime=datetime.time(23,59,59), - set=None, - expLabel='', - ext='.r', - walk=True): - + def searchFilesOffLine(self, + path, + startDate=None, + endDate=None, + startTime=datetime.time(0, 0, 0), + endTime=datetime.time(23, 59, 59), + set=None, + expLabel='', + ext='.r', + cursor=None, + skip=None, + walk=True): + self.filenameList = [] self.datetimeList = [] - + pathList = [] - - dateList, pathList = self.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True) - + + dateList, pathList = self.findDatafiles( + path, startDate, endDate, expLabel, ext, walk, include_path=True) + if dateList == []: - # print "[Reading] Date range selected invalid [%s - %s]: No *%s files in %s)" %(startDate, endDate, ext, path) - return None, None - + return [], [] + if len(dateList) > 1: - print "[Reading] Data found for date range [%s - %s]: total days = %d" %(startDate, endDate, len(dateList)) + print "[Reading] Data found for date range [%s - %s]: total days = %d" % (startDate, endDate, len(dateList)) else: - print "[Reading] Data found for date range [%s - %s]: date = %s" %(startDate, endDate, dateList[0]) - + print "[Reading] Data found for date range [%s - %s]: date = %s" % (startDate, endDate, dateList[0]) + filenameList = [] datetimeList = [] for thisPath in pathList: - # thisPath = pathList[pathDict[file]] - - fileList = glob.glob1(thisPath, "*%s" %ext) + + fileList = glob.glob1(thisPath, "*%s" % ext) fileList.sort() - + for file in fileList: - - filename = os.path.join(thisPath,file) - + + filename = os.path.join(thisPath, file) + if not isFileInDateRange(filename, startDate, endDate): continue - - thisDatetime = isFileInTimeRange(filename, startDate, endDate, startTime, endTime) - + + thisDatetime = isFileInTimeRange( + filename, startDate, endDate, startTime, endTime) + if not(thisDatetime): continue - + filenameList.append(filename) datetimeList.append(thisDatetime) - + + if cursor is not None and skip is not None: + filenameList = filenameList[cursor * skip:cursor * skip + skip] + datetimeList = datetimeList[cursor * skip:cursor * skip + skip] + if not(filenameList): - print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" %(startTime, endTime, ext, path) - return None, None - - print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime) - print - - for i in range(len(filenameList)): - print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) + print "[Reading] Time range selected invalid [%s - %s]: No *%s files in %s)" % (startTime, endTime, ext, path) + return [], [] + + print "[Reading] %d file(s) was(were) found in time range: %s - %s" % (len(filenameList), startTime, endTime) + + # for i in range(len(filenameList)): + # print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) self.filenameList = filenameList self.datetimeList = datetimeList - + return pathList, filenameList - def __searchFilesOnLine(self, path, expLabel = "", ext = None, walk=True, set=None): - + def __searchFilesOnLine(self, path, expLabel="", ext=None, walk=True, set=None): """ Busca el ultimo archivo de la ultima carpeta (determinada o no por startDateTime) y devuelve el archivo encontrado ademas de otros datos. - - Input: + + Input: path : carpeta donde estan contenidos los files que contiene data - + expLabel : Nombre del subexperimento (subfolder) - + ext : extension de los files - + walk : Si es habilitado no realiza busquedas dentro de los ubdirectorios (doypath) Return: @@ -686,38 +712,38 @@ class JRODataReader(JRODataIO): year : el anho doy : el numero de dia del anho set : el set del archivo - - + + """ if not os.path.isdir(path): return None, None, None, None, None, None - + dirList = [] - + if not walk: fullpath = path foldercounter = 0 else: - #Filtra solo los directorios + # Filtra solo los directorios for thisPath in os.listdir(path): - if not os.path.isdir(os.path.join(path,thisPath)): + if not os.path.isdir(os.path.join(path, thisPath)): continue if not isRadarFolder(thisPath): continue - + dirList.append(thisPath) - + if not(dirList): return None, None, None, None, None, None - - dirList = sorted( dirList, key=str.lower ) - + + dirList = sorted(dirList, key=str.lower) + doypath = dirList[-1] - foldercounter = int(doypath.split('_')[1]) if len(doypath.split('_'))>1 else 0 + foldercounter = int(doypath.split('_')[1]) if len( + doypath.split('_')) > 1 else 0 fullpath = os.path.join(path, doypath, expLabel) - - - print "[Reading] %s folder was found: " %(fullpath ) + + print "[Reading] %s folder was found: " % (fullpath) if set == None: filename = getlastFileFromPath(fullpath, ext) @@ -726,27 +752,27 @@ class JRODataReader(JRODataIO): if not(filename): return None, None, None, None, None, None - - print "[Reading] %s file was found" %(filename) - + + print "[Reading] %s file was found" % (filename) + if not(self.__verifyFile(os.path.join(fullpath, filename))): return None, None, None, None, None, None - year = int( filename[1:5] ) - doy = int( filename[5:8] ) - set = int( filename[8:11] ) - + year = int(filename[1:5]) + doy = int(filename[5:8]) + set = int(filename[8:11]) + return fullpath, foldercounter, filename, year, doy, set - + def __setNextFileOffline(self): - + idFile = self.fileIndex while (True): idFile += 1 if not(idFile < len(self.filenameList)): self.flagNoMoreFiles = 1 - # print "[Reading] No more Files" +# print "[Reading] No more Files" return 0 filename = self.filenameList[idFile] @@ -755,7 +781,7 @@ class JRODataReader(JRODataIO): continue fileSize = os.path.getsize(filename) - fp = open(filename,'rb') + fp = open(filename, 'rb') break self.flagIsNewFile = 1 @@ -764,7 +790,7 @@ class JRODataReader(JRODataIO): self.fileSize = fileSize self.fp = fp - # print "[Reading] Setting the file: %s"%self.filename +# print "[Reading] Setting the file: %s"%self.filename return 1 @@ -772,9 +798,9 @@ class JRODataReader(JRODataIO): """ Busca el siguiente file que tenga suficiente data para ser leida, dentro de un folder especifico, si no encuentra un file valido espera un tiempo determinado y luego busca en los posibles n files - siguientes. - - Affected: + siguientes. + + Affected: self.flagIsNewFile self.filename self.fileSize @@ -782,82 +808,86 @@ class JRODataReader(JRODataIO): self.set self.flagNoMoreFiles - Return: + Return: 0 : si luego de una busqueda del siguiente file valido este no pudo ser encontrado 1 : si el file fue abierto con exito y esta listo a ser leido - - Excepciones: + + Excepciones: Si un determinado file no puede ser abierto """ nFiles = 0 - fileOk_flag = False + fileOk_flag = False firstTime_flag = True self.set += 1 - + if self.set > 999: self.set = 0 - self.foldercounter += 1 - - #busca el 1er file disponible - fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext ) + self.foldercounter += 1 + + # busca el 1er file disponible + fullfilename, filename = checkForRealPath( + self.path, self.foldercounter, self.year, self.doy, self.set, self.ext) if fullfilename: if self.__verifyFile(fullfilename, False): fileOk_flag = True - #si no encuentra un file entonces espera y vuelve a buscar - if not(fileOk_flag): - for nFiles in range(self.nFiles+1): #busco en los siguientes self.nFiles+1 files posibles + # si no encuentra un file entonces espera y vuelve a buscar + if not(fileOk_flag): + # busco en los siguientes self.nFiles+1 files posibles + for nFiles in range(self.nFiles + 1): - if firstTime_flag: #si es la 1era vez entonces hace el for self.nTries veces + if firstTime_flag: # si es la 1era vez entonces hace el for self.nTries veces tries = self.nTries else: - tries = 1 #si no es la 1era vez entonces solo lo hace una vez - - for nTries in range( tries ): + tries = 1 # si no es la 1era vez entonces solo lo hace una vez + + for nTries in range(tries): if firstTime_flag: - print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % ( self.delay, filename, nTries+1 ) - sleep( self.delay ) + print "\t[Reading] Waiting %0.2f sec for the next file: \"%s\" , try %03d ..." % (self.delay, filename, nTries + 1) + sleep(self.delay) else: print "\t[Reading] Searching the next \"%s%04d%03d%03d%s\" file ..." % (self.optchar, self.year, self.doy, self.set, self.ext) - - fullfilename, filename = checkForRealPath( self.path, self.foldercounter, self.year, self.doy, self.set, self.ext ) + + fullfilename, filename = checkForRealPath( + self.path, self.foldercounter, self.year, self.doy, self.set, self.ext) if fullfilename: if self.__verifyFile(fullfilename): fileOk_flag = True break - + if fileOk_flag: break firstTime_flag = False - print "\t[Reading] Skipping the file \"%s\" due to this file doesn't exist" % filename + log.warning('Skipping the file {} due to this file doesn\'t exist'.format(filename)) self.set += 1 - - if nFiles == (self.nFiles-1): #si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta + + # si no encuentro el file buscado cambio de carpeta y busco en la siguiente carpeta + if nFiles == (self.nFiles - 1): self.set = 0 self.doy += 1 self.foldercounter = 0 if fileOk_flag: - self.fileSize = os.path.getsize( fullfilename ) + self.fileSize = os.path.getsize(fullfilename) self.filename = fullfilename self.flagIsNewFile = 1 - if self.fp != None: self.fp.close() + if self.fp != None: + self.fp.close() self.fp = open(fullfilename, 'rb') self.flagNoMoreFiles = 0 - # print '[Reading] Setting the file: %s' % fullfilename +# print '[Reading] Setting the file: %s' % fullfilename else: self.fileSize = 0 self.filename = None self.flagIsNewFile = 0 self.fp = None self.flagNoMoreFiles = 1 - # print '[Reading] No more files to read' return fileOk_flag - + def setNextFile(self): if self.fp != None: self.fp.close() @@ -867,147 +897,149 @@ class JRODataReader(JRODataIO): else: newFile = self.__setNextFileOffline() - if not(newFile): - print '[Reading] No more files to read' + if not(newFile): + raise schainpy.admin.SchainWarning('No more files to read') return 0 - print '[Reading] Setting the file: %s' % self.filename - + if self.verbose: + print '[Reading] Setting the file: %s' % self.filename + self.__readFirstHeader() self.nReadBlocks = 0 return 1 def __waitNewBlock(self): """ - Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma. - + Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma. + Si el modo de lectura es OffLine siempre retorn 0 """ if not self.online: return 0 - + if (self.nReadBlocks >= self.processingHeaderObj.dataBlocksPerFile): return 0 - + currentPointer = self.fp.tell() - + neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize - - for nTries in range( self.nTries ): - + + for nTries in range(self.nTries): + self.fp.close() - self.fp = open( self.filename, 'rb' ) - self.fp.seek( currentPointer ) + self.fp = open(self.filename, 'rb') + self.fp.seek(currentPointer) - self.fileSize = os.path.getsize( self.filename ) + self.fileSize = os.path.getsize(self.filename) currentSize = self.fileSize - currentPointer - if ( currentSize >= neededSize ): + if (currentSize >= neededSize): self.basicHeaderObj.read(self.fp) return 1 - + if self.fileSize == self.fileSizeByHeader: - # self.flagEoF = True + # self.flagEoF = True return 0 - - print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1) - sleep( self.delay ) - - - return 0 - def waitDataBlock(self,pointer_location): - + print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1) + sleep(self.delay) + + return 0 + + def waitDataBlock(self, pointer_location): + currentPointer = pointer_location - - neededSize = self.processingHeaderObj.blockSize #+ self.basicHeaderSize - - for nTries in range( self.nTries ): + + neededSize = self.processingHeaderObj.blockSize # + self.basicHeaderSize + + for nTries in range(self.nTries): self.fp.close() - self.fp = open( self.filename, 'rb' ) - self.fp.seek( currentPointer ) - - self.fileSize = os.path.getsize( self.filename ) + self.fp = open(self.filename, 'rb') + self.fp.seek(currentPointer) + + self.fileSize = os.path.getsize(self.filename) currentSize = self.fileSize - currentPointer - - if ( currentSize >= neededSize ): + + if (currentSize >= neededSize): return 1 - - print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1) - sleep( self.delay ) - + + print "[Reading] Waiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries + 1) + sleep(self.delay) + return 0 def __jumpToLastBlock(self): - + if not(self.__isFirstTimeOnline): return - + csize = self.fileSize - self.fp.tell() blocksize = self.processingHeaderObj.blockSize - - #salta el primer bloque de datos + + # salta el primer bloque de datos if csize > self.processingHeaderObj.blockSize: self.fp.seek(self.fp.tell() + blocksize) else: return - + csize = self.fileSize - self.fp.tell() neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize while True: - - if self.fp.tell() 0: - # self.fp.seek(self.fp.tell() + factor*neededsize) - + +# csize = self.fileSize - self.fp.tell() +# neededsize = self.processingHeaderObj.blockSize + self.basicHeaderSize +# factor = int(csize/neededsize) +# if factor > 0: +# self.fp.seek(self.fp.tell() + factor*neededsize) + self.flagIsNewFile = 0 self.__isFirstTimeOnline = 0 def __setNewBlock(self): - + # if self.server is None: if self.fp == None: return 0 - - # if self.online: - # self.__jumpToLastBlock() - + +# if self.online: +# self.__jumpToLastBlock() + if self.flagIsNewFile: self.lastUTTime = self.basicHeaderObj.utc return 1 - + if self.realtime: self.flagDiscontinuousBlock = 1 if not(self.setNextFile()): return 0 else: return 1 - + # if self.server is None: currentSize = self.fileSize - self.fp.tell() neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize - if (currentSize >= neededSize): self.basicHeaderObj.read(self.fp) self.lastUTTime = self.basicHeaderObj.utc return 1 - + # else: + # self.basicHeaderObj.read(self.zHeader) + # self.lastUTTime = self.basicHeaderObj.utc + # return 1 if self.__waitNewBlock(): self.lastUTTime = self.basicHeaderObj.utc return 1 - + # if self.server is None: if not(self.setNextFile()): return 0 - deltaTime = self.basicHeaderObj.utc - self.lastUTTime # + deltaTime = self.basicHeaderObj.utc - self.lastUTTime self.lastUTTime = self.basicHeaderObj.utc - + self.flagDiscontinuousBlock = 0 if deltaTime > self.maxTimeStep: @@ -1016,33 +1048,33 @@ class JRODataReader(JRODataIO): return 1 def readNextBlock(self): - - #Skip block out of startTime and endTime + + # Skip block out of startTime and endTime while True: if not(self.__setNewBlock()): + raise(schainpy.admin.SchainWarning('No more files')) return 0 - + if not(self.readBlock()): return 0 - + self.getBasicHeader() - - if not isTimeInRange(self.dataOut.datatime.time(), self.startTime, self.endTime): - - print "[Reading] Block No. %d/%d -> %s [Skipping]" %(self.nReadBlocks, - self.processingHeaderObj.dataBlocksPerFile, - self.dataOut.datatime.ctime()) + if (self.dataOut.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or (self.dataOut.datatime > datetime.datetime.combine(self.endDate, self.endTime)): + print "[Reading] Block No. %d/%d -> %s [Skipping]" % (self.nReadBlocks, + self.processingHeaderObj.dataBlocksPerFile, + self.dataOut.datatime.ctime()) continue - + break - - print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks, - self.processingHeaderObj.dataBlocksPerFile, - self.dataOut.datatime.ctime()) + + if self.verbose: + print "[Reading] Block No. %d/%d -> %s" % (self.nReadBlocks, + self.processingHeaderObj.dataBlocksPerFile, + self.dataOut.datatime.ctime()) return 1 def __readFirstHeader(self): - + self.basicHeaderObj.read(self.fp) self.systemHeaderObj.read(self.fp) self.radarControllerHeaderObj.read(self.fp) @@ -1050,42 +1082,45 @@ class JRODataReader(JRODataIO): self.firstHeaderSize = self.basicHeaderObj.size - datatype = int(numpy.log2((self.processingHeaderObj.processFlags & PROCFLAG.DATATYPE_MASK))-numpy.log2(PROCFLAG.DATATYPE_CHAR)) + datatype = int(numpy.log2((self.processingHeaderObj.processFlags & + PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR)) if datatype == 0: - datatype_str = numpy.dtype([('real',' %s" %(self.nReadBlocks, - self.processingHeaderObj.dataBlocksPerFile, - self.dataOut.datatime.ctime()) + 'SPAM!' + +# if self.flagIsNewBlock: +# print "[Reading] Block No. %d/%d -> %s" %(self.nReadBlocks, +# self.processingHeaderObj.dataBlocksPerFile, +# self.dataOut.datatime.ctime()) def printInfo(self): - + if self.__printInfo == False: return - + self.basicHeaderObj.printInfo() self.systemHeaderObj.printInfo() self.radarControllerHeaderObj.printInfo() self.processingHeaderObj.printInfo() - + self.__printInfo = False - - - def run(self, **kwargs): - + + def run(self, + path=None, + startDate=None, + endDate=None, + startTime=datetime.time(0, 0, 0), + endTime=datetime.time(23, 59, 59), + set=None, + expLabel="", + ext=None, + online=False, + delay=60, + walk=True, + getblock=False, + nTxs=1, + realtime=False, + blocksize=None, + blocktime=None, + skip=None, + cursor=None, + warnings=True, + server=None, + verbose=True, + format=None, + oneDDict=None, + twoDDict=None, + ind2DList=None, **kwargs): + if not(self.isConfig): - -# self.dataOut = dataOut - self.setup(**kwargs) + self.setup(path=path, + startDate=startDate, + endDate=endDate, + startTime=startTime, + endTime=endTime, + set=set, + expLabel=expLabel, + ext=ext, + online=online, + delay=delay, + walk=walk, + getblock=getblock, + nTxs=nTxs, + realtime=realtime, + blocksize=blocksize, + blocktime=blocktime, + skip=skip, + cursor=cursor, + warnings=warnings, + server=server, + verbose=verbose, + format=format, + oneDDict=oneDDict, + twoDDict=twoDDict, + ind2DList=ind2DList) self.isConfig = True - - self.getData() + if server is None: + self.getData() + else: + self.getFromServer() + class JRODataWriter(JRODataIO): - """ + """ Esta clase permite escribir datos a archivos procesados (.r o ,pdata). La escritura - de los datos siempre se realiza por bloques. + de los datos siempre se realiza por bloques. """ - + blockIndex = 0 - + path = None - + setFile = None - + profilesPerBlock = None - + blocksPerFile = None - + nWriteBlocks = 0 - + fileDate = None - + def __init__(self, dataOut=None): raise NotImplementedError - def hasAllDataInBuffer(self): raise NotImplementedError - def setBlockDimension(self): raise NotImplementedError - def writeBlock(self): raise NotImplementedError - def putData(self): raise NotImplementedError - def getProcessFlags(self): - + processFlags = 0 - + dtype_index = get_dtype_index(self.dtype) procflag_dtype = get_procflag_dtype(dtype_index) - + processFlags += procflag_dtype - + if self.dataOut.flagDecodeData: processFlags += PROCFLAG.DECODE_DATA - + if self.dataOut.flagDeflipData: processFlags += PROCFLAG.DEFLIP_DATA - + if self.dataOut.code is not None: processFlags += PROCFLAG.DEFINE_PROCESS_CODE - + if self.dataOut.nCohInt > 1: processFlags += PROCFLAG.COHERENT_INTEGRATION - + if self.dataOut.type == "Spectra": if self.dataOut.nIncohInt > 1: processFlags += PROCFLAG.INCOHERENT_INTEGRATION - + if self.dataOut.data_dc is not None: processFlags += PROCFLAG.SAVE_CHANNELS_DC - + if self.dataOut.flagShiftFFT: processFlags += PROCFLAG.SHIFT_FFT_DATA - + return processFlags - + def setBasicHeader(self): - - self.basicHeaderObj.size = self.basicHeaderSize #bytes + + self.basicHeaderObj.size = self.basicHeaderSize # bytes self.basicHeaderObj.version = self.versionFile self.basicHeaderObj.dataBlock = self.nTotalBlocks - + utc = numpy.floor(self.dataOut.utctime) - milisecond = (self.dataOut.utctime - utc)* 1000.0 - + milisecond = (self.dataOut.utctime - utc) * 1000.0 + self.basicHeaderObj.utc = utc self.basicHeaderObj.miliSecond = milisecond self.basicHeaderObj.timeZone = self.dataOut.timeZone self.basicHeaderObj.dstFlag = self.dataOut.dstFlag self.basicHeaderObj.errorCount = self.dataOut.errorCount - + def setFirstHeader(self): """ Obtiene una copia del First Header - + Affected: - + self.basicHeaderObj self.systemHeaderObj self.radarControllerHeaderObj self.processingHeaderObj self. - + Return: None """ - + raise NotImplementedError - + def __writeFirstHeader(self): """ Escribe el primer header del file es decir el Basic header y el Long header (SystemHeader, RadarControllerHeader, ProcessingHeader) - + Affected: __dataType - + Return: None """ - + # CALCULAR PARAMETROS - - sizeLongHeader = self.systemHeaderObj.size + self.radarControllerHeaderObj.size + self.processingHeaderObj.size + + sizeLongHeader = self.systemHeaderObj.size + \ + self.radarControllerHeaderObj.size + self.processingHeaderObj.size self.basicHeaderObj.size = self.basicHeaderSize + sizeLongHeader - + self.basicHeaderObj.write(self.fp) self.systemHeaderObj.write(self.fp) self.radarControllerHeaderObj.write(self.fp) self.processingHeaderObj.write(self.fp) - + def __setNewBlock(self): """ Si es un nuevo file escribe el First Header caso contrario escribe solo el Basic Header - + Return: 0 : si no pudo escribir nada 1 : Si escribio el Basic el First Header - """ + """ if self.fp == None: self.setNextFile() - + if self.flagIsNewFile: return 1 - + if self.blockIndex < self.processingHeaderObj.dataBlocksPerFile: self.basicHeaderObj.write(self.fp) return 1 - - if not( self.setNextFile() ): + + if not(self.setNextFile()): return 0 - - return 1 + return 1 def writeNextBlock(self): """ Selecciona el bloque siguiente de datos y los escribe en un file - - Return: - 0 : Si no hizo pudo escribir el bloque de datos + + Return: + 0 : Si no hizo pudo escribir el bloque de datos 1 : Si no pudo escribir el bloque de datos """ - if not( self.__setNewBlock() ): + if not(self.__setNewBlock()): return 0 - + self.writeBlock() - - print "[Writing] Block No. %d/%d" %(self.blockIndex, - self.processingHeaderObj.dataBlocksPerFile) - - return 1 + + print "[Writing] Block No. %d/%d" % (self.blockIndex, + self.processingHeaderObj.dataBlocksPerFile) + + return 1 def setNextFile(self): - """ + """ Determina el siguiente file que sera escrito - Affected: + Affected: self.filename self.subfolder self.fp @@ -1600,72 +1701,74 @@ class JRODataWriter(JRODataIO): """ ext = self.ext path = self.path - + if self.fp != None: self.fp.close() - - timeTuple = time.localtime( self.dataOut.utctime) - subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) - fullpath = os.path.join( path, subfolder ) + timeTuple = time.localtime(self.dataOut.utctime) + subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year, timeTuple.tm_yday) + + fullpath = os.path.join(path, subfolder) setFile = self.setFile - - if not( os.path.exists(fullpath) ): + + if not(os.path.exists(fullpath)): os.mkdir(fullpath) - setFile = -1 #inicializo mi contador de seteo + setFile = -1 # inicializo mi contador de seteo else: - filesList = os.listdir( fullpath ) - if len( filesList ) > 0: - filesList = sorted( filesList, key=str.lower ) + filesList = os.listdir(fullpath) + if len(filesList) > 0: + filesList = sorted(filesList, key=str.lower) filen = filesList[-1] # el filename debera tener el siguiente formato # 0 1234 567 89A BCDE (hex) # x YYYY DDD SSS .ext - if isNumber( filen[8:11] ): - setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file - else: + if isNumber(filen[8:11]): + # inicializo mi contador de seteo al seteo del ultimo file + setFile = int(filen[8:11]) + else: setFile = -1 else: - setFile = -1 #inicializo mi contador de seteo - + setFile = -1 # inicializo mi contador de seteo + setFile += 1 - - #If this is a new day it resets some values + + # If this is a new day it resets some values if self.dataOut.datatime.date() > self.fileDate: setFile = 0 self.nTotalBlocks = 0 - - filen = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext ) + + filen = '{}{:04d}{:03d}{:03d}{}'.format( + self.optchar, timeTuple.tm_year, timeTuple.tm_yday, setFile, ext) - filename = os.path.join( path, subfolder, filen ) + filename = os.path.join(path, subfolder, filen) + + fp = open(filename, 'wb') - fp = open( filename,'wb' ) - self.blockIndex = 0 - - #guardando atributos + + # guardando atributos self.filename = filename self.subfolder = subfolder self.fp = fp self.setFile = setFile self.flagIsNewFile = 1 self.fileDate = self.dataOut.datatime.date() - + self.setFirstHeader() - - print '[Writing] Opening file: %s'%self.filename - + + print '[Writing] Opening file: %s' % self.filename + self.__writeFirstHeader() - + return 1 - + def setup(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4): """ - Setea el tipo de formato en la cual sera guardada la data y escribe el First Header - + Setea el tipo de formato en la cual sera guardada la data y escribe el First Header + Inputs: path : directory where data will be saved - profilesPerBlock : number of profiles per block + profilesPerBlock : number of profiles per block set : initial file set datatype : An integer number that defines data type: 0 : int8 (1 byte) @@ -1674,50 +1777,50 @@ class JRODataWriter(JRODataIO): 3 : int64 (8 bytes) 4 : float32 (4 bytes) 5 : double64 (8 bytes) - + Return: 0 : Si no realizo un buen seteo - 1 : Si realizo un buen seteo + 1 : Si realizo un buen seteo """ - + if ext == None: ext = self.ext - + self.ext = ext.lower() - + self.path = path if set is None: self.setFile = -1 else: - self.setFile = set - 1 - + self.setFile = set - 1 + self.blocksPerFile = blocksPerFile - + self.profilesPerBlock = profilesPerBlock - + self.dataOut = dataOut self.fileDate = self.dataOut.datatime.date() - #By default + # By default self.dtype = self.dataOut.dtype - + if datatype is not None: self.dtype = get_numpy_dtype(datatype) - + if not(self.setNextFile()): print "[Writing] There isn't a next file" return 0 - + self.setBlockDimension() - + return 1 - - def run(self, dataOut, **kwargs): - + + def run(self, dataOut, path, blocksPerFile, profilesPerBlock=64, set=None, ext=None, datatype=4, **kwargs): + if not(self.isConfig): - - self.setup(dataOut, **kwargs) + + self.setup(dataOut, path, blocksPerFile, profilesPerBlock=profilesPerBlock, + set=set, ext=ext, datatype=datatype, **kwargs) self.isConfig = True - - self.putData() + self.putData() diff --git a/schainpy/model/io/jroIO_bltr.py b/schainpy/model/io/jroIO_bltr.py new file mode 100644 index 0000000..6a1c6a5 --- /dev/null +++ b/schainpy/model/io/jroIO_bltr.py @@ -0,0 +1,1180 @@ +import os +import sys +import glob +import fnmatch +import datetime +import time +import re +import h5py +import numpy + +import pylab as plb +from scipy.optimize import curve_fit +from scipy import asarray as ar, exp +from scipy import stats + +from numpy.ma.core import getdata + +SPEED_OF_LIGHT = 299792458 +SPEED_OF_LIGHT = 3e8 + +try: + from gevent import sleep +except: + from time import sleep + +from schainpy.model.data.jrodata import Spectra +#from schainpy.model.data.BLTRheaderIO import FileHeader, RecordHeader +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +#from schainpy.model.io.jroIO_bltr import BLTRReader +from numpy import imag, shape, NaN + +from jroIO_base import JRODataReader + + +class Header(object): + + def __init__(self): + raise NotImplementedError + + def read(self): + + raise NotImplementedError + + def write(self): + + raise NotImplementedError + + def printInfo(self): + + message = "#" * 50 + "\n" + message += self.__class__.__name__.upper() + "\n" + message += "#" * 50 + "\n" + + keyList = self.__dict__.keys() + keyList.sort() + + for key in keyList: + message += "%s = %s" % (key, self.__dict__[key]) + "\n" + + if "size" not in keyList: + attr = getattr(self, "size") + + if attr: + message += "%s = %s" % ("size", attr) + "\n" + + # print message + + +FILE_STRUCTURE = numpy.dtype([ # HEADER 48bytes + ('FileMgcNumber', ' vertical) + ('BeamAngleZen', ' endFp: + sys.stderr.write( + "Warning %s: Size value read from System Header is lower than it has to be\n" % fp) + return 0 + + if OffRHeader < endFp: + sys.stderr.write( + "Warning %s: Size value read from System Header size is greater than it has to be\n" % fp) + return 0 + + return 1 + + +class BLTRSpectraReader (ProcessingUnit, FileHeaderBLTR, RecordHeaderBLTR, JRODataReader): + + path = None + startDate = None + endDate = None + startTime = None + endTime = None + walk = None + isConfig = False + + fileList = None + + # metadata + TimeZone = None + Interval = None + heightList = None + + # data + data = None + utctime = None + + def __init__(self, **kwargs): + + # Eliminar de la base la herencia + ProcessingUnit.__init__(self, **kwargs) + + #self.isConfig = False + + #self.pts2read_SelfSpectra = 0 + #self.pts2read_CrossSpectra = 0 + #self.pts2read_DCchannels = 0 + #self.datablock = None + self.utc = None + self.ext = ".fdt" + self.optchar = "P" + self.fpFile = None + self.fp = None + self.BlockCounter = 0 + self.dtype = None + self.fileSizeByHeader = None + self.filenameList = [] + self.fileSelector = 0 + self.Off2StartNxtRec = 0 + self.RecCounter = 0 + self.flagNoMoreFiles = 0 + self.data_spc = None + self.data_cspc = None + self.data_output = None + self.path = None + self.OffsetStartHeader = 0 + self.Off2StartData = 0 + self.ipp = 0 + self.nFDTdataRecors = 0 + self.blocksize = 0 + self.dataOut = Spectra() + self.profileIndex = 1 # Always + self.dataOut.flagNoData = False + self.dataOut.nRdPairs = 0 + self.dataOut.data_spc = None + self.dataOut.velocityX = [] + self.dataOut.velocityY = [] + self.dataOut.velocityV = [] + + def Files2Read(self, fp): + ''' + Function that indicates the number of .fdt files that exist in the folder to be read. + It also creates an organized list with the names of the files to read. + ''' + # self.__checkPath() + + # Gets the list of files within the fp address + ListaData = os.listdir(fp) + # Sort the list of files from least to largest by names + ListaData = sorted(ListaData) + nFiles = 0 # File Counter + FileList = [] # A list is created that will contain the .fdt files + for IndexFile in ListaData: + if '.fdt' in IndexFile: + FileList.append(IndexFile) + nFiles += 1 + + # print 'Files2Read' + # print 'Existen '+str(nFiles)+' archivos .fdt' + + self.filenameList = FileList # List of files from least to largest by names + + def run(self, **kwargs): + ''' + This method will be the one that will initiate the data entry, will be called constantly. + You should first verify that your Setup () is set up and then continue to acquire + the data to be processed with getData (). + ''' + if not self.isConfig: + self.setup(**kwargs) + self.isConfig = True + + self.getData() + # print 'running' + + def setup(self, path=None, + startDate=None, + endDate=None, + startTime=None, + endTime=None, + walk=True, + timezone='utc', + code=None, + online=False, + ReadMode=None, + **kwargs): + + self.isConfig = True + + self.path = path + self.startDate = startDate + self.endDate = endDate + self.startTime = startTime + self.endTime = endTime + self.walk = walk + self.ReadMode = int(ReadMode) + + pass + + def getData(self): + ''' + Before starting this function, you should check that there is still an unread file, + If there are still blocks to read or if the data block is empty. + + You should call the file "read". + + ''' + + if self.flagNoMoreFiles: + self.dataOut.flagNoData = True + print 'NoData se vuelve true' + return 0 + + self.fp = self.path + self.Files2Read(self.fp) + self.readFile(self.fp) + self.dataOut.data_spc = self.data_spc + self.dataOut.data_cspc = self.data_cspc + self.dataOut.data_output = self.data_output + + print 'self.dataOut.data_output', shape(self.dataOut.data_output) + + # self.removeDC() + return self.dataOut.data_spc + + def readFile(self, fp): + ''' + You must indicate if you are reading in Online or Offline mode and load the + The parameters for this file reading mode. + + Then you must do 2 actions: + + 1. Get the BLTR FileHeader. + 2. Start reading the first block. + ''' + + # The address of the folder is generated the name of the .fdt file that will be read + print "File: ", self.fileSelector + 1 + + if self.fileSelector < len(self.filenameList): + + self.fpFile = str(fp) + '/' + \ + str(self.filenameList[self.fileSelector]) + # print self.fpFile + fheader = FileHeaderBLTR() + fheader.FHread(self.fpFile) # Bltr FileHeader Reading + self.nFDTdataRecors = fheader.nFDTdataRecors + + self.readBlock() # Block reading + else: + print 'readFile FlagNoData becomes true' + self.flagNoMoreFiles = True + self.dataOut.flagNoData = True + return 0 + + def getVelRange(self, extrapoints=0): + Lambda = SPEED_OF_LIGHT / 50000000 + # 1./(self.dataOut.ippSeconds * self.dataOut.nCohInt) + PRF = self.dataOut.PRF + Vmax = -Lambda / (4. * (1. / PRF) * self.dataOut.nCohInt * 2.) + deltafreq = PRF / (self.nProfiles) + deltavel = (Vmax * 2) / (self.nProfiles) + freqrange = deltafreq * \ + (numpy.arange(self.nProfiles) - self.nProfiles / 2.) - deltafreq / 2 + velrange = deltavel * \ + (numpy.arange(self.nProfiles) - self.nProfiles / 2.) + return velrange + + def readBlock(self): + ''' + It should be checked if the block has data, if it is not passed to the next file. + + Then the following is done: + + 1. Read the RecordHeader + 2. Fill the buffer with the current block number. + + ''' + + if self.BlockCounter < self.nFDTdataRecors - 2: + print self.nFDTdataRecors, 'CONDICION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + if self.ReadMode == 1: + rheader = RecordHeaderBLTR(RecCounter=self.BlockCounter + 1) + elif self.ReadMode == 0: + rheader = RecordHeaderBLTR(RecCounter=self.BlockCounter) + + rheader.RHread(self.fpFile) # Bltr FileHeader Reading + + self.OffsetStartHeader = rheader.OffsetStartHeader + self.RecCounter = rheader.RecCounter + self.Off2StartNxtRec = rheader.Off2StartNxtRec + self.Off2StartData = rheader.Off2StartData + self.nProfiles = rheader.nProfiles + self.nChannels = rheader.nChannels + self.nHeights = rheader.nHeights + self.frequency = rheader.TransmitFrec + self.DualModeIndex = rheader.DualModeIndex + + self.pairsList = [(0, 1), (0, 2), (1, 2)] + self.dataOut.pairsList = self.pairsList + + self.nRdPairs = len(self.dataOut.pairsList) + self.dataOut.nRdPairs = self.nRdPairs + + self.__firstHeigth = rheader.StartRangeSamp + self.__deltaHeigth = rheader.SampResolution + self.dataOut.heightList = self.__firstHeigth + \ + numpy.array(range(self.nHeights)) * self.__deltaHeigth + self.dataOut.channelList = range(self.nChannels) + self.dataOut.nProfiles = rheader.nProfiles + self.dataOut.nIncohInt = rheader.nIncohInt + self.dataOut.nCohInt = rheader.nCohInt + self.dataOut.ippSeconds = 1 / float(rheader.PRFhz) + self.dataOut.PRF = rheader.PRFhz + self.dataOut.nFFTPoints = rheader.nProfiles + self.dataOut.utctime = rheader.nUtime + self.dataOut.timeZone = 0 + self.dataOut.normFactor = self.dataOut.nProfiles * \ + self.dataOut.nIncohInt * self.dataOut.nCohInt + self.dataOut.outputInterval = self.dataOut.ippSeconds * \ + self.dataOut.nCohInt * self.dataOut.nIncohInt * self.nProfiles + + self.data_output = numpy.ones([3, rheader.nHeights]) * numpy.NaN + print 'self.data_output', shape(self.data_output) + self.dataOut.velocityX = [] + self.dataOut.velocityY = [] + self.dataOut.velocityV = [] + + '''Block Reading, the Block Data is received and Reshape is used to give it + shape. + ''' + + # Procedure to take the pointer to where the date block starts + startDATA = open(self.fpFile, "rb") + OffDATA = self.OffsetStartHeader + self.RecCounter * \ + self.Off2StartNxtRec + self.Off2StartData + startDATA.seek(OffDATA, os.SEEK_SET) + + def moving_average(x, N=2): + return numpy.convolve(x, numpy.ones((N,)) / N)[(N - 1):] + + def gaus(xSamples, a, x0, sigma): + return a * exp(-(xSamples - x0)**2 / (2 * sigma**2)) + + def Find(x, value): + for index in range(len(x)): + if x[index] == value: + return index + + def pol2cart(rho, phi): + x = rho * numpy.cos(phi) + y = rho * numpy.sin(phi) + return(x, y) + + if self.DualModeIndex == self.ReadMode: + + self.data_fft = numpy.fromfile( + startDATA, [('complex', ' 0.0001) : +# +# try: +# popt,pcov = curve_fit(gaus,xSamples,yMean,p0=[1,meanGauss,sigma]) +# +# if numpy.amax(popt)>numpy.amax(yMean)*0.3: +# FitGauss=gaus(xSamples,*popt) +# +# else: +# FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) +# print 'Verificador: Dentro', Height +# except RuntimeError: +# +# try: +# for j in range(len(ySamples[1])): +# yMean2=numpy.append(yMean2,numpy.average([ySamples[1,j],ySamples[2,j]])) +# popt,pcov = curve_fit(gaus,xSamples,yMean2,p0=[1,meanGauss,sigma]) +# FitGauss=gaus(xSamples,*popt) +# print 'Verificador: Exepcion1', Height +# except RuntimeError: +# +# try: +# popt,pcov = curve_fit(gaus,xSamples,ySamples[1],p0=[1,meanGauss,sigma]) +# FitGauss=gaus(xSamples,*popt) +# print 'Verificador: Exepcion2', Height +# except RuntimeError: +# FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) +# print 'Verificador: Exepcion3', Height +# else: +# FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) +# #print 'Verificador: Fuera', Height +# +# +# +# Maximun=numpy.amax(yMean) +# eMinus1=Maximun*numpy.exp(-1) +# +# HWpos=Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1))) +# HalfWidth= xFrec[HWpos] +# GCpos=Find(FitGauss, numpy.amax(FitGauss)) +# Vpos=Find(FactNorm, numpy.amax(FactNorm)) +# #Vpos=numpy.sum(FactNorm)/len(FactNorm) +# #Vpos=Find(FactNorm, min(FactNorm, key=lambda value:abs(value- numpy.mean(FactNorm) ))) +# #print 'GCpos',GCpos, numpy.amax(FitGauss), 'HWpos',HWpos +# '''****** Getting Fij ******''' +# +# GaussCenter=xFrec[GCpos] +# if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0): +# Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001 +# else: +# Fij=abs(GaussCenter-HalfWidth)+0.0000001 +# +# '''****** Getting Frecuency range of significant data ******''' +# +# Rangpos=Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10))) +# +# if Rangpos5 and len(FrecRange) 0.: +# self.dataOut.velocityX=numpy.append(self.dataOut.velocityX, Vzon) #Vmag +# #print 'Vmag',Vmag +# else: +# self.dataOut.velocityX=numpy.append(self.dataOut.velocityX, NaN) +# +# if abs(Vx)<100 and abs(Vx) > 0.: +# self.dataOut.velocityY=numpy.append(self.dataOut.velocityY, Vmer) #Vang +# #print 'Vang',Vang +# else: +# self.dataOut.velocityY=numpy.append(self.dataOut.velocityY, NaN) +# +# if abs(GaussCenter)<2: +# self.dataOut.velocityV=numpy.append(self.dataOut.velocityV, xFrec[Vpos]) +# +# else: +# self.dataOut.velocityV=numpy.append(self.dataOut.velocityV, NaN) +# +# +# # print '********************************************' +# # print 'HalfWidth ', HalfWidth +# # print 'Maximun ', Maximun +# # print 'eMinus1 ', eMinus1 +# # print 'Rangpos ', Rangpos +# # print 'GaussCenter ',GaussCenter +# # print 'E01 ',E01 +# # print 'N01 ',N01 +# # print 'E02 ',E02 +# # print 'N02 ',N02 +# # print 'E12 ',E12 +# # print 'N12 ',N12 +# #print 'self.dataOut.velocityX ', self.dataOut.velocityX +# # print 'Fij ', Fij +# # print 'cC ', cC +# # print 'cF ', cF +# # print 'cG ', cG +# # print 'cA ', cA +# # print 'cB ', cB +# # print 'cH ', cH +# # print 'Vx ', Vx +# # print 'Vy ', Vy +# # print 'Vmag ', Vmag +# # print 'Vang ', Vang*180/numpy.pi +# # print 'PhaseSlope ',PhaseSlope[0] +# # print 'PhaseSlope ',PhaseSlope[1] +# # print 'PhaseSlope ',PhaseSlope[2] +# # print '********************************************' +# #print 'data_output',shape(self.dataOut.velocityX), shape(self.dataOut.velocityY) +# +# #print 'self.dataOut.velocityX', len(self.dataOut.velocityX) +# #print 'self.dataOut.velocityY', len(self.dataOut.velocityY) +# #print 'self.dataOut.velocityV', self.dataOut.velocityV +# +# self.data_output[0]=numpy.array(self.dataOut.velocityX) +# self.data_output[1]=numpy.array(self.dataOut.velocityY) +# self.data_output[2]=numpy.array(self.dataOut.velocityV) +# +# prin= self.data_output[0][~numpy.isnan(self.data_output[0])] +# print ' ' +# print 'VmagAverage',numpy.mean(prin) +# print ' ' +# # plt.figure(5) +# # plt.subplot(211) +# # plt.plot(self.dataOut.velocityX,'yo:') +# # plt.subplot(212) +# # plt.plot(self.dataOut.velocityY,'yo:') +# +# # plt.figure(1) +# # # plt.subplot(121) +# # # plt.plot(xFrec,ySamples[0],'k',label='Ch0') +# # # plt.plot(xFrec,ySamples[1],'g',label='Ch1') +# # # plt.plot(xFrec,ySamples[2],'r',label='Ch2') +# # # plt.plot(xFrec,FitGauss,'yo:',label='fit') +# # # plt.legend() +# # plt.title('DATOS A ALTURA DE 2850 METROS') +# # +# # plt.xlabel('Frecuencia (KHz)') +# # plt.ylabel('Magnitud') +# # # plt.subplot(122) +# # # plt.title('Fit for Time Constant') +# # #plt.plot(xFrec,zline) +# # #plt.plot(xFrec,SmoothSPC,'g') +# # plt.plot(xFrec,FactNorm) +# # plt.axis([-4, 4, 0, 0.15]) +# # # plt.xlabel('SelfSpectra KHz') +# # +# # plt.figure(10) +# # # plt.subplot(121) +# # plt.plot(xFrec,ySamples[0],'b',label='Ch0') +# # plt.plot(xFrec,ySamples[1],'y',label='Ch1') +# # plt.plot(xFrec,ySamples[2],'r',label='Ch2') +# # # plt.plot(xFrec,FitGauss,'yo:',label='fit') +# # plt.legend() +# # plt.title('SELFSPECTRA EN CANALES') +# # +# # plt.xlabel('Frecuencia (KHz)') +# # plt.ylabel('Magnitud') +# # # plt.subplot(122) +# # # plt.title('Fit for Time Constant') +# # #plt.plot(xFrec,zline) +# # #plt.plot(xFrec,SmoothSPC,'g') +# # # plt.plot(xFrec,FactNorm) +# # # plt.axis([-4, 4, 0, 0.15]) +# # # plt.xlabel('SelfSpectra KHz') +# # +# # plt.figure(9) +# # +# # +# # plt.title('DATOS SUAVIZADOS') +# # plt.xlabel('Frecuencia (KHz)') +# # plt.ylabel('Magnitud') +# # plt.plot(xFrec,SmoothSPC,'g') +# # +# # #plt.plot(xFrec,FactNorm) +# # plt.axis([-4, 4, 0, 0.15]) +# # # plt.xlabel('SelfSpectra KHz') +# # # +# # plt.figure(2) +# # # #plt.subplot(121) +# # plt.plot(xFrec,yMean,'r',label='Mean SelfSpectra') +# # plt.plot(xFrec,FitGauss,'yo:',label='Ajuste Gaussiano') +# # # plt.plot(xFrec[Rangpos],FitGauss[Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.1)))],'bo') +# # # #plt.plot(xFrec,phase) +# # # plt.xlabel('Suavizado, promediado KHz') +# # plt.title('SELFSPECTRA PROMEDIADO') +# # # #plt.subplot(122) +# # # #plt.plot(xSamples,zline) +# # plt.xlabel('Frecuencia (KHz)') +# # plt.ylabel('Magnitud') +# # plt.legend() +# # # +# # # plt.figure(3) +# # # plt.subplot(311) +# # # #plt.plot(xFrec,phase[0]) +# # # plt.plot(xFrec,phase[0],'g') +# # # plt.subplot(312) +# # # plt.plot(xFrec,phase[1],'g') +# # # plt.subplot(313) +# # # plt.plot(xFrec,phase[2],'g') +# # # #plt.plot(xFrec,phase[2]) +# # # +# # # plt.figure(4) +# # # +# # # plt.plot(xSamples,coherence[0],'b') +# # # plt.plot(xSamples,coherence[1],'r') +# # # plt.plot(xSamples,coherence[2],'g') +# # plt.show() +# # # +# # # plt.clf() +# # # plt.cla() +# # # plt.close() +# +# print ' ' + + self.BlockCounter += 2 + + else: + self.fileSelector += 1 + self.BlockCounter = 0 + print "Next File" diff --git a/schainpy/model/io/jroIO_digitalRF.py b/schainpy/model/io/jroIO_digitalRF.py new file mode 100644 index 0000000..d9e120f --- /dev/null +++ b/schainpy/model/io/jroIO_digitalRF.py @@ -0,0 +1,800 @@ + +''' +Created on Jul 3, 2014 + +@author: roj-idl71 +''' +# SUBCHANNELS EN VEZ DE CHANNELS +# BENCHMARKS -> PROBLEMAS CON ARCHIVOS GRANDES -> INCONSTANTE EN EL TIEMPO +# ACTUALIZACION DE VERSION +# HEADERS +# MODULO DE ESCRITURA +# METADATA + +import os +import datetime +import numpy +import timeit +from fractions import Fraction + +try: + from gevent import sleep +except: + from time import sleep + +from schainpy.model.data.jroheaderIO import RadarControllerHeader, SystemHeader +from schainpy.model.data.jrodata import Voltage +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +from time import time + +import cPickle +try: + import digital_rf +except: + print 'You should install "digital_rf" module if you want to read Digital RF data' + + +class DigitalRFReader(ProcessingUnit): + ''' + classdocs + ''' + + def __init__(self, **kwargs): + ''' + Constructor + ''' + + ProcessingUnit.__init__(self, **kwargs) + + self.dataOut = Voltage() + self.__printInfo = True + self.__flagDiscontinuousBlock = False + self.__bufferIndex = 9999999 + self.__ippKm = None + self.__codeType = 0 + self.__nCode = None + self.__nBaud = None + self.__code = None + self.dtype = None + self.oldAverage = None + + def close(self): + print 'Average of writing to digital rf format is ', self.oldAverage * 1000 + return + + def __getCurrentSecond(self): + + return self.__thisUnixSample / self.__sample_rate + + thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.") + + def __setFileHeader(self): + ''' + In this method will be initialized every parameter of dataOut object (header, no data) + ''' + ippSeconds = 1.0 * self.__nSamples / self.__sample_rate + + nProfiles = 1.0 / ippSeconds # Number of profiles in one second + + try: + self.dataOut.radarControllerHeaderObj = RadarControllerHeader( + self.__radarControllerHeader) + except: + self.dataOut.radarControllerHeaderObj = RadarControllerHeader( + txA=0, + txB=0, + nWindows=1, + nHeights=self.__nSamples, + firstHeight=self.__firstHeigth, + deltaHeight=self.__deltaHeigth, + codeType=self.__codeType, + nCode=self.__nCode, nBaud=self.__nBaud, + code=self.__code) + + try: + self.dataOut.systemHeaderObj = SystemHeader(self.__systemHeader) + except: + self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples, + nProfiles=nProfiles, + nChannels=len( + self.__channelList), + adcResolution=14) + self.dataOut.type = "Voltage" + + self.dataOut.data = None + + self.dataOut.dtype = self.dtype + + # self.dataOut.nChannels = 0 + + # self.dataOut.nHeights = 0 + + self.dataOut.nProfiles = int(nProfiles) + + self.dataOut.heightList = self.__firstHeigth + \ + numpy.arange(self.__nSamples, dtype=numpy.float) * \ + self.__deltaHeigth + + self.dataOut.channelList = range(self.__num_subchannels) + + self.dataOut.blocksize = self.dataOut.getNChannels() * self.dataOut.getNHeights() + + # self.dataOut.channelIndexList = None + + self.dataOut.flagNoData = True + + self.dataOut.flagDataAsBlock = False + # Set to TRUE if the data is discontinuous + self.dataOut.flagDiscontinuousBlock = False + + self.dataOut.utctime = None + + # timezone like jroheader, difference in minutes between UTC and localtime + self.dataOut.timeZone = self.__timezone / 60 + + self.dataOut.dstFlag = 0 + + self.dataOut.errorCount = 0 + + try: + self.dataOut.nCohInt = self.fixed_metadata_dict.get( + 'nCohInt', self.nCohInt) + + # asumo que la data esta decodificada + self.dataOut.flagDecodeData = self.fixed_metadata_dict.get( + 'flagDecodeData', self.flagDecodeData) + + # asumo que la data esta sin flip + self.dataOut.flagDeflipData = self.fixed_metadata_dict['flagDeflipData'] + + self.dataOut.flagShiftFFT = self.fixed_metadata_dict['flagShiftFFT'] + + self.dataOut.useLocalTime = self.fixed_metadata_dict['useLocalTime'] + except: + pass + + self.dataOut.ippSeconds = ippSeconds + + # Time interval between profiles + # self.dataOut.timeInterval = self.dataOut.ippSeconds * self.dataOut.nCohInt + + self.dataOut.frequency = self.__frequency + + self.dataOut.realtime = self.__online + + def findDatafiles(self, path, startDate=None, endDate=None): + + if not os.path.isdir(path): + return [] + + try: + digitalReadObj = digital_rf.DigitalRFReader( + path, load_all_metadata=True) + except: + digitalReadObj = digital_rf.DigitalRFReader(path) + + channelNameList = digitalReadObj.get_channels() + + if not channelNameList: + return [] + + metadata_dict = digitalReadObj.get_rf_file_metadata(channelNameList[0]) + + sample_rate = metadata_dict['sample_rate'][0] + + this_metadata_file = digitalReadObj.get_metadata(channelNameList[0]) + + try: + timezone = this_metadata_file['timezone'].value + except: + timezone = 0 + + startUTCSecond, endUTCSecond = digitalReadObj.get_bounds( + channelNameList[0]) / sample_rate - timezone + + startDatetime = datetime.datetime.utcfromtimestamp(startUTCSecond) + endDatatime = datetime.datetime.utcfromtimestamp(endUTCSecond) + + if not startDate: + startDate = startDatetime.date() + + if not endDate: + endDate = endDatatime.date() + + dateList = [] + + thisDatetime = startDatetime + + while(thisDatetime <= endDatatime): + + thisDate = thisDatetime.date() + + if thisDate < startDate: + continue + + if thisDate > endDate: + break + + dateList.append(thisDate) + thisDatetime += datetime.timedelta(1) + + return dateList + + def setup(self, path=None, + startDate=None, + endDate=None, + startTime=datetime.time(0, 0, 0), + endTime=datetime.time(23, 59, 59), + channelList=None, + nSamples=None, + online=False, + delay=60, + buffer_size=1024, + ippKm=None, + nCohInt=1, + nCode=1, + nBaud=1, + flagDecodeData=False, + code=numpy.ones((1, 1), dtype=numpy.int), + **kwargs): + ''' + In this method we should set all initial parameters. + + Inputs: + path + startDate + endDate + startTime + endTime + set + expLabel + ext + online + delay + ''' + self.nCohInt = nCohInt + self.flagDecodeData = flagDecodeData + self.i = 0 + if not os.path.isdir(path): + raise ValueError, "[Reading] Directory %s does not exist" % path + + try: + self.digitalReadObj = digital_rf.DigitalRFReader( + path, load_all_metadata=True) + except: + self.digitalReadObj = digital_rf.DigitalRFReader(path) + + channelNameList = self.digitalReadObj.get_channels() + + if not channelNameList: + raise ValueError, "[Reading] Directory %s does not have any files" % path + + if not channelList: + channelList = range(len(channelNameList)) + + ########## Reading metadata ###################### + + top_properties = self.digitalReadObj.get_properties( + channelNameList[channelList[0]]) + + self.__num_subchannels = top_properties['num_subchannels'] + self.__sample_rate = 1.0 * \ + top_properties['sample_rate_numerator'] / \ + top_properties['sample_rate_denominator'] + # self.__samples_per_file = top_properties['samples_per_file'][0] + self.__deltaHeigth = 1e6 * 0.15 / self.__sample_rate # why 0.15? + + this_metadata_file = self.digitalReadObj.get_digital_metadata( + channelNameList[channelList[0]]) + metadata_bounds = this_metadata_file.get_bounds() + self.fixed_metadata_dict = this_metadata_file.read( + metadata_bounds[0])[metadata_bounds[0]] # GET FIRST HEADER + + try: + self.__processingHeader = self.fixed_metadata_dict['processingHeader'] + self.__radarControllerHeader = self.fixed_metadata_dict['radarControllerHeader'] + self.__systemHeader = self.fixed_metadata_dict['systemHeader'] + self.dtype = cPickle.loads(self.fixed_metadata_dict['dtype']) + except: + pass + + self.__frequency = None + + self.__frequency = self.fixed_metadata_dict.get('frequency', 1) + + self.__timezone = self.fixed_metadata_dict.get('timezone', 300) + + try: + nSamples = self.fixed_metadata_dict['nSamples'] + except: + nSamples = None + + self.__firstHeigth = 0 + + try: + codeType = self.__radarControllerHeader['codeType'] + except: + codeType = 0 + + try: + if codeType: + nCode = self.__radarControllerHeader['nCode'] + nBaud = self.__radarControllerHeader['nBaud'] + code = self.__radarControllerHeader['code'] + except: + pass + + if not ippKm: + try: + # seconds to km + ippKm = self.__radarControllerHeader['ipp'] + except: + ippKm = None + #################################################### + self.__ippKm = ippKm + startUTCSecond = None + endUTCSecond = None + + if startDate: + startDatetime = datetime.datetime.combine(startDate, startTime) + startUTCSecond = ( + startDatetime - datetime.datetime(1970, 1, 1)).total_seconds() + self.__timezone + + if endDate: + endDatetime = datetime.datetime.combine(endDate, endTime) + endUTCSecond = (endDatetime - datetime.datetime(1970, + 1, 1)).total_seconds() + self.__timezone + + start_index, end_index = self.digitalReadObj.get_bounds( + channelNameList[channelList[0]]) + + if not startUTCSecond: + startUTCSecond = start_index / self.__sample_rate + + if start_index > startUTCSecond * self.__sample_rate: + startUTCSecond = start_index / self.__sample_rate + + if not endUTCSecond: + endUTCSecond = end_index / self.__sample_rate + + if end_index < endUTCSecond * self.__sample_rate: + endUTCSecond = end_index / self.__sample_rate + if not nSamples: + if not ippKm: + raise ValueError, "[Reading] nSamples or ippKm should be defined" + nSamples = int(ippKm / (1e6 * 0.15 / self.__sample_rate)) + channelBoundList = [] + channelNameListFiltered = [] + + for thisIndexChannel in channelList: + thisChannelName = channelNameList[thisIndexChannel] + start_index, end_index = self.digitalReadObj.get_bounds( + thisChannelName) + channelBoundList.append((start_index, end_index)) + channelNameListFiltered.append(thisChannelName) + + self.profileIndex = 0 + self.i = 0 + self.__delay = delay + + self.__codeType = codeType + self.__nCode = nCode + self.__nBaud = nBaud + self.__code = code + + self.__datapath = path + self.__online = online + self.__channelList = channelList + self.__channelNameList = channelNameListFiltered + self.__channelBoundList = channelBoundList + self.__nSamples = nSamples + self.__samples_to_read = long(nSamples) # FIJO: AHORA 40 + self.__nChannels = len(self.__channelList) + + self.__startUTCSecond = startUTCSecond + self.__endUTCSecond = endUTCSecond + + self.__timeInterval = 1.0 * self.__samples_to_read / \ + self.__sample_rate # Time interval + + if online: + # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read) + startUTCSecond = numpy.floor(endUTCSecond) + + # por que en el otro metodo lo primero q se hace es sumar samplestoread + self.__thisUnixSample = long( + startUTCSecond * self.__sample_rate) - self.__samples_to_read + + self.__data_buffer = numpy.zeros( + (self.__num_subchannels, self.__samples_to_read), dtype=numpy.complex) + + self.__setFileHeader() + self.isConfig = True + + print "[Reading] Digital RF Data was found from %s to %s " % ( + datetime.datetime.utcfromtimestamp( + self.__startUTCSecond - self.__timezone), + datetime.datetime.utcfromtimestamp( + self.__endUTCSecond - self.__timezone) + ) + + print "[Reading] Starting process from %s to %s" % (datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone), + datetime.datetime.utcfromtimestamp( + endUTCSecond - self.__timezone) + ) + self.oldAverage = None + self.count = 0 + self.executionTime = 0 + + def __reload(self): + # print + # print "%s not in range [%s, %s]" %( + # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), + # datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone), + # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone) + # ) + print "[Reading] reloading metadata ..." + + try: + self.digitalReadObj.reload(complete_update=True) + except: + self.digitalReadObj.reload() + + start_index, end_index = self.digitalReadObj.get_bounds( + self.__channelNameList[self.__channelList[0]]) + + if start_index > self.__startUTCSecond * self.__sample_rate: + self.__startUTCSecond = 1.0 * start_index / self.__sample_rate + + if end_index > self.__endUTCSecond * self.__sample_rate: + self.__endUTCSecond = 1.0 * end_index / self.__sample_rate + print + print "[Reading] New timerange found [%s, %s] " % ( + datetime.datetime.utcfromtimestamp( + self.__startUTCSecond - self.__timezone), + datetime.datetime.utcfromtimestamp( + self.__endUTCSecond - self.__timezone) + ) + + return True + + return False + + def timeit(self, toExecute): + t0 = time() + toExecute() + self.executionTime = time() - t0 + if self.oldAverage is None: + self.oldAverage = self.executionTime + self.oldAverage = (self.executionTime + self.count * + self.oldAverage) / (self.count + 1.0) + self.count = self.count + 1.0 + return + + def __readNextBlock(self, seconds=30, volt_scale=1): + ''' + ''' + + # Set the next data + self.__flagDiscontinuousBlock = False + self.__thisUnixSample += self.__samples_to_read + + if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate: + print "[Reading] There are no more data into selected time-range" + if self.__online: + self.__reload() + else: + return False + + if self.__thisUnixSample + 2 * self.__samples_to_read > self.__endUTCSecond * self.__sample_rate: + return False + self.__thisUnixSample -= self.__samples_to_read + + indexChannel = 0 + + dataOk = False + for thisChannelName in self.__channelNameList: # TODO VARIOS CHANNELS? + for indexSubchannel in range(self.__num_subchannels): + try: + t0 = time() + result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample, + self.__samples_to_read, + thisChannelName, sub_channel=indexSubchannel) + self.executionTime = time() - t0 + if self.oldAverage is None: + self.oldAverage = self.executionTime + self.oldAverage = ( + self.executionTime + self.count * self.oldAverage) / (self.count + 1.0) + self.count = self.count + 1.0 + + except IOError, e: + # read next profile + self.__flagDiscontinuousBlock = True + print "[Reading] %s" % datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e + break + + if result.shape[0] != self.__samples_to_read: + self.__flagDiscontinuousBlock = True + print "[Reading] %s: Too few samples were found, just %d/%d samples" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), + result.shape[0], + self.__samples_to_read) + break + + self.__data_buffer[indexSubchannel, :] = result * volt_scale + + indexChannel += 1 + + dataOk = True + + self.__utctime = self.__thisUnixSample / self.__sample_rate + + if not dataOk: + return False + + print "[Reading] %s: %d samples <> %f sec" % (datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), + self.__samples_to_read, + self.__timeInterval) + + self.__bufferIndex = 0 + + return True + + def __isBufferEmpty(self): + return self.__bufferIndex > self.__samples_to_read - self.__nSamples # 40960 - 40 + + def getData(self, seconds=30, nTries=5): + ''' + This method gets the data from files and put the data into the dataOut object + + In addition, increase el the buffer counter in one. + + Return: + data : retorna un perfil de voltages (alturas * canales) copiados desde el + buffer. Si no hay mas archivos a leer retorna None. + + Affected: + self.dataOut + self.profileIndex + self.flagDiscontinuousBlock + self.flagIsNewBlock + ''' + + err_counter = 0 + self.dataOut.flagNoData = True + + if self.__isBufferEmpty(): + self.__flagDiscontinuousBlock = False + + while True: + if self.__readNextBlock(): + break + if self.__thisUnixSample > self.__endUTCSecond * self.__sample_rate: + return False + + if self.__flagDiscontinuousBlock: + print '[Reading] discontinuous block found ... continue with the next block' + continue + + if not self.__online: + return False + + err_counter += 1 + if err_counter > nTries: + return False + + print '[Reading] waiting %d seconds to read a new block' % seconds + sleep(seconds) + + self.dataOut.data = self.__data_buffer[:, + self.__bufferIndex:self.__bufferIndex + self.__nSamples] + self.dataOut.utctime = ( + self.__thisUnixSample + self.__bufferIndex) / self.__sample_rate + self.dataOut.flagNoData = False + self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock + self.dataOut.profileIndex = self.profileIndex + + self.__bufferIndex += self.__nSamples + self.profileIndex += 1 + + if self.profileIndex == self.dataOut.nProfiles: + self.profileIndex = 0 + + return True + + def printInfo(self): + ''' + ''' + if self.__printInfo == False: + return + + # self.systemHeaderObj.printInfo() + # self.radarControllerHeaderObj.printInfo() + + self.__printInfo = False + + def printNumberOfBlock(self): + ''' + ''' + return + # print self.profileIndex + + def run(self, **kwargs): + ''' + This method will be called many times so here you should put all your code + ''' + + if not self.isConfig: + self.setup(**kwargs) + #self.i = self.i+1 + self.getData(seconds=self.__delay) + + return + + +class DigitalRFWriter(Operation): + ''' + classdocs + ''' + + def __init__(self, **kwargs): + ''' + Constructor + ''' + Operation.__init__(self, **kwargs) + self.metadata_dict = {} + self.dataOut = None + self.dtype = None + self.oldAverage = 0 + + def setHeader(self): + + self.metadata_dict['frequency'] = self.dataOut.frequency + self.metadata_dict['timezone'] = self.dataOut.timeZone + self.metadata_dict['dtype'] = cPickle.dumps(self.dataOut.dtype) + self.metadata_dict['nProfiles'] = self.dataOut.nProfiles + self.metadata_dict['heightList'] = self.dataOut.heightList + self.metadata_dict['channelList'] = self.dataOut.channelList + self.metadata_dict['flagDecodeData'] = self.dataOut.flagDecodeData + self.metadata_dict['flagDeflipData'] = self.dataOut.flagDeflipData + self.metadata_dict['flagShiftFFT'] = self.dataOut.flagShiftFFT + self.metadata_dict['useLocalTime'] = self.dataOut.useLocalTime + self.metadata_dict['nCohInt'] = self.dataOut.nCohInt + self.metadata_dict['type'] = self.dataOut.type + self.metadata_dict['flagDataAsBlock'] = getattr( + self.dataOut, 'flagDataAsBlock', None) # chequear + + def setup(self, dataOut, path, frequency, fileCadence, dirCadence, metadataCadence, set=0, metadataFile='metadata', ext='.h5'): + ''' + In this method we should set all initial parameters. + Input: + dataOut: Input data will also be outputa data + ''' + self.setHeader() + self.__ippSeconds = dataOut.ippSeconds + self.__deltaH = dataOut.getDeltaH() + self.__sample_rate = 1e6 * 0.15 / self.__deltaH + self.__dtype = dataOut.dtype + if len(dataOut.dtype) == 2: + self.__dtype = dataOut.dtype[0] + self.__nSamples = dataOut.systemHeaderObj.nSamples + self.__nProfiles = dataOut.nProfiles + + if self.dataOut.type != 'Voltage': + raise 'Digital RF cannot be used with this data type' + self.arr_data = numpy.ones((1, dataOut.nFFTPoints * len( + self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)]) + else: + self.arr_data = numpy.ones((self.__nSamples, len( + self.dataOut.channelList)), dtype=[('r', self.__dtype), ('i', self.__dtype)]) + + file_cadence_millisecs = 1000 + + sample_rate_fraction = Fraction(self.__sample_rate).limit_denominator() + sample_rate_numerator = long(sample_rate_fraction.numerator) + sample_rate_denominator = long(sample_rate_fraction.denominator) + start_global_index = dataOut.utctime * self.__sample_rate + + uuid = 'prueba' + compression_level = 0 + checksum = False + is_complex = True + num_subchannels = len(dataOut.channelList) + is_continuous = True + marching_periods = False + + self.digitalWriteObj = digital_rf.DigitalRFWriter(path, self.__dtype, dirCadence, + fileCadence, start_global_index, + sample_rate_numerator, sample_rate_denominator, uuid, compression_level, checksum, + is_complex, num_subchannels, is_continuous, marching_periods) + metadata_dir = os.path.join(path, 'metadata') + os.system('mkdir %s' % (metadata_dir)) + self.digitalMetadataWriteObj = digital_rf.DigitalMetadataWriter(metadata_dir, dirCadence, 1, # 236, file_cadence_millisecs / 1000 + sample_rate_numerator, sample_rate_denominator, + metadataFile) + self.isConfig = True + self.currentSample = 0 + self.oldAverage = 0 + self.count = 0 + return + + def writeMetadata(self): + start_idx = self.__sample_rate * self.dataOut.utctime + + self.metadata_dict['processingHeader'] = self.dataOut.processingHeaderObj.getAsDict( + ) + self.metadata_dict['radarControllerHeader'] = self.dataOut.radarControllerHeaderObj.getAsDict( + ) + self.metadata_dict['systemHeader'] = self.dataOut.systemHeaderObj.getAsDict( + ) + self.digitalMetadataWriteObj.write(start_idx, self.metadata_dict) + return + + def timeit(self, toExecute): + t0 = time() + toExecute() + self.executionTime = time() - t0 + if self.oldAverage is None: + self.oldAverage = self.executionTime + self.oldAverage = (self.executionTime + self.count * + self.oldAverage) / (self.count + 1.0) + self.count = self.count + 1.0 + return + + def writeData(self): + if self.dataOut.type != 'Voltage': + raise 'Digital RF cannot be used with this data type' + for channel in self.dataOut.channelList: + for i in range(self.dataOut.nFFTPoints): + self.arr_data[1][channel * self.dataOut.nFFTPoints + + i]['r'] = self.dataOut.data[channel][i].real + self.arr_data[1][channel * self.dataOut.nFFTPoints + + i]['i'] = self.dataOut.data[channel][i].imag + else: + for i in range(self.dataOut.systemHeaderObj.nSamples): + for channel in self.dataOut.channelList: + self.arr_data[i][channel]['r'] = self.dataOut.data[channel][i].real + self.arr_data[i][channel]['i'] = self.dataOut.data[channel][i].imag + + def f(): return self.digitalWriteObj.rf_write(self.arr_data) + self.timeit(f) + + return + + def run(self, dataOut, frequency=49.92e6, path=None, fileCadence=1000, dirCadence=36000, metadataCadence=1, **kwargs): + ''' + This method will be called many times so here you should put all your code + Inputs: + dataOut: object with the data + ''' + # print dataOut.__dict__ + self.dataOut = dataOut + if not self.isConfig: + self.setup(dataOut, path, frequency, fileCadence, + dirCadence, metadataCadence, **kwargs) + self.writeMetadata() + + self.writeData() + + ## self.currentSample += 1 + # if self.dataOut.flagDataAsBlock or self.currentSample == 1: + # self.writeMetadata() + ## if self.currentSample == self.__nProfiles: self.currentSample = 0 + + def close(self): + print '[Writing] - Closing files ' + print 'Average of writing to digital rf format is ', self.oldAverage * 1000 + try: + self.digitalWriteObj.close() + except: + pass + + + # raise +if __name__ == '__main__': + + readObj = DigitalRFReader() + + while True: + readObj.run(path='/home/jchavez/jicamarca/mocked_data/') + # readObj.printInfo() + # readObj.printNumberOfBlock() diff --git a/schainpy/model/io/jroIO_heispectra.py b/schainpy/model/io/jroIO_heispectra.py index 947a098..ddbffab 100644 --- a/schainpy/model/io/jroIO_heispectra.py +++ b/schainpy/model/io/jroIO_heispectra.py @@ -15,14 +15,14 @@ try: import pyfits except ImportError, e: print "Fits data cannot be used. Install pyfits module" - + from xml.etree.ElementTree import ElementTree from jroIO_base import isRadarFolder, isNumber from schainpy.model.data.jrodata import Fits from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit - -class PyFits(object): + +class PyFits(object): name=None format=None array =None @@ -30,11 +30,11 @@ class PyFits(object): thdulist=None prihdr=None hdu=None - + def __init__(self): - + pass - + def setColF(self,name,format,array): self.name=name self.format=format @@ -42,7 +42,7 @@ class PyFits(object): a1=numpy.array([self.array],dtype=numpy.float32) self.col1 = pyfits.Column(name=self.name, format=self.format, array=a1) return self.col1 - + # def setColP(self,name,format,data): # self.name=name # self.format=format @@ -50,7 +50,7 @@ class PyFits(object): # a2=numpy.array([self.data],dtype=numpy.float32) # self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2) # return self.col2 - + def writeData(self,name,format,data): self.name=name @@ -59,7 +59,7 @@ class PyFits(object): a2=numpy.array([self.data],dtype=numpy.float32) self.col2 = pyfits.Column(name=self.name, format=self.format, array=a2) return self.col2 - + def cFImage(self,idblock,year,month,day,hour,minute,second): self.hdu= pyfits.PrimaryHDU(idblock) self.hdu.header.set("Year",year) @@ -68,22 +68,22 @@ class PyFits(object): self.hdu.header.set("Hour",hour) self.hdu.header.set("Minute",minute) self.hdu.header.set("Second",second) - return self.hdu + return self.hdu def Ctable(self,colList): self.cols=pyfits.ColDefs(colList) self.tbhdu = pyfits.new_table(self.cols) return self.tbhdu - - + + def CFile(self,hdu,tbhdu): self.thdulist=pyfits.HDUList([hdu,tbhdu]) - + def wFile(self,filename): if os.path.isfile(filename): os.remove(filename) - self.thdulist.writeto(filename) + self.thdulist.writeto(filename) class ParameterConf: @@ -100,27 +100,27 @@ class ParameterConf: return self.ELEMENTNAME class Metadata(object): - + def __init__(self, filename): self.parmConfObjList = [] self.readXml(filename) - + def readXml(self, filename): self.projectElement = None self.procUnitConfObjDict = {} self.projectElement = ElementTree().parse(filename) - self.project = self.projectElement.tag + self.project = self.projectElement.tag parmElementList = self.projectElement.getiterator(ParameterConf().getElementName()) - + for parmElement in parmElementList: parmConfObj = ParameterConf() parmConfObj.readXml(parmElement) self.parmConfObjList.append(parmConfObj) class FitsWriter(Operation): - - def __init__(self): + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.isConfig = False self.dataBlocksPerFile = None self.blockIndex = 0 @@ -129,60 +129,60 @@ class FitsWriter(Operation): self.optchar = 'P' self.ext = '.fits' self.setFile = 0 - + def setFitsHeader(self, dataOut, metadatafile=None): - + header_data = pyfits.PrimaryHDU() - + header_data.header['EXPNAME'] = "RADAR DATA" header_data.header['DATATYPE'] = "SPECTRA" header_data.header['COMMENT'] = "" - + if metadatafile: - + metadata4fits = Metadata(metadatafile) - + for parameter in metadata4fits.parmConfObjList: parm_name = parameter.name parm_value = parameter.value - + header_data.header[parm_name] = parm_value - + header_data.header['DATETIME'] = time.strftime("%b %d %Y %H:%M:%S", dataOut.datatime.timetuple()) header_data.header['CHANNELLIST'] = str(dataOut.channelList) header_data.header['NCHANNELS'] = dataOut.nChannels #header_data.header['HEIGHTS'] = dataOut.heightList header_data.header['NHEIGHTS'] = dataOut.nHeights - + header_data.header['IPPSECONDS'] = dataOut.ippSeconds header_data.header['NCOHINT'] = dataOut.nCohInt header_data.header['NINCOHINT'] = dataOut.nIncohInt header_data.header['TIMEZONE'] = dataOut.timeZone header_data.header['NBLOCK'] = self.blockIndex - + header_data.writeto(self.filename) - + self.addExtension(dataOut.heightList,'HEIGHTLIST') - - + + def setup(self, dataOut, path, dataBlocksPerFile=100, metadatafile=None): - + self.path = path self.dataOut = dataOut self.metadatafile = metadatafile self.dataBlocksPerFile = dataBlocksPerFile - + def open(self): self.fitsObj = pyfits.open(self.filename, mode='update') - + def addExtension(self, data, tagname): self.open() extension = pyfits.ImageHDU(data=data, name=tagname) #extension.header['TAG'] = tagname self.fitsObj.append(extension) self.write() - + def addData(self, data): self.open() extension = pyfits.ImageHDU(data=data, name=self.fitsObj[0].header['DATATYPE']) @@ -194,16 +194,16 @@ class FitsWriter(Operation): self.write() def write(self): - + self.fitsObj.flush(verbose=True) self.fitsObj.close() - - + + def setNextFile(self): ext = self.ext path = self.path - + timeTuple = time.localtime( self.dataOut.utctime) subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) @@ -216,17 +216,17 @@ class FitsWriter(Operation): if len( filesList ) > 0: filesList = sorted( filesList, key=str.lower ) filen = filesList[-1] - + if isNumber( filen[8:11] ): self.setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file - else: + else: self.setFile = -1 else: self.setFile = -1 #inicializo mi contador de seteo - + setFile = self.setFile setFile += 1 - + thisFile = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, timeTuple.tm_year, timeTuple.tm_yday, @@ -234,71 +234,72 @@ class FitsWriter(Operation): ext ) filename = os.path.join( path, subfolder, thisFile ) - + self.blockIndex = 0 self.filename = filename self.setFile = setFile self.flagIsNewFile = 1 print 'Writing the file: %s'%self.filename - + self.setFitsHeader(self.dataOut, self.metadatafile) - + return 1 def writeBlock(self): - self.addData(self.dataOut.data_spc) + self.addData(self.dataOut.data_spc) self.flagIsNewFile = 0 - + def __setNewBlock(self): if self.flagIsNewFile: return 1 - + if self.blockIndex < self.dataBlocksPerFile: return 1 - + if not( self.setNextFile() ): return 0 - + return 1 def writeNextBlock(self): if not( self.__setNewBlock() ): return 0 self.writeBlock() - return 1 - - def putData(self): + return 1 + + def putData(self): if self.flagIsNewFile: self.setNextFile() self.writeNextBlock() - - def run(self, dataOut, **kwargs): + + def run(self, dataOut, path, dataBlocksPerFile=100, metadatafile=None, **kwargs): if not(self.isConfig): - self.setup(dataOut, **kwargs) + self.setup(dataOut, path, dataBlocksPerFile=dataBlocksPerFile, metadatafile=metadatafile, **kwargs) self.isConfig = True self.putData() - - + + class FitsReader(ProcessingUnit): - + # __TIMEZONE = time.timezone - + expName = None datetimestr = None utc = None nChannels = None nSamples = None dataBlocksPerFile = None - comments = None + comments = None lastUTTime = None header_dict = None data = None data_header_dict = None - - def __init__(self): + + def __init__(self, **kwargs): + ProcessingUnit.__init__(self, **kwargs) self.isConfig = False self.ext = '.fits' self.setFile = 0 @@ -314,39 +315,39 @@ class FitsReader(ProcessingUnit): self.nTotalBlocks = 0 self.dataOut = self.createObjByDefault() self.maxTimeStep = 10# deberia ser definido por el usuario usando el metodo setup() - self.blockIndex = 1 - + self.blockIndex = 1 + def createObjByDefault(self): - + dataObj = Fits() - + return dataObj - + def isFileinThisTime(self, filename, startTime, endTime, useLocalTime=False): try: fitsObj = pyfits.open(filename,'readonly') except: print "File %s can't be opened" %(filename) return None - + header = fitsObj[0].header struct_time = time.strptime(header['DATETIME'], "%b %d %Y %H:%M:%S") utc = time.mktime(struct_time) - time.timezone #TIMEZONE debe ser un parametro del header FITS - + ltc = utc if useLocalTime: ltc -= time.timezone thisDatetime = datetime.datetime.utcfromtimestamp(ltc) thisTime = thisDatetime.time() - + if not ((startTime <= thisTime) and (endTime > thisTime)): return None - + return thisDatetime - + def __setNextFileOnline(self): raise NotImplementedError - + def __setNextFileOffline(self): idFile = self.fileIndex @@ -375,34 +376,34 @@ class FitsReader(ProcessingUnit): print "Setting the file: %s"%self.filename return 1 - + def __setValuesFromHeader(self): - - self.dataOut.header = self.header_dict + + self.dataOut.header = self.header_dict self.dataOut.expName = self.expName - + self.dataOut.timeZone = self.timeZone self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile - self.dataOut.comments = self.comments + self.dataOut.comments = self.comments # self.dataOut.timeInterval = self.timeInterval self.dataOut.channelList = self.channelList self.dataOut.heightList = self.heightList - + self.dataOut.nCohInt = self.nCohInt self.dataOut.nIncohInt = self.nIncohInt - + self.dataOut.ippSeconds = self.ippSeconds - + def readHeader(self): headerObj = self.fitsObj[0] - + self.header_dict = headerObj.header if 'EXPNAME' in headerObj.header.keys(): self.expName = headerObj.header['EXPNAME'] - + if 'DATATYPE' in headerObj.header.keys(): self.dataType = headerObj.header['DATATYPE'] - + self.datetimestr = headerObj.header['DATETIME'] channelList = headerObj.header['CHANNELLIST'] channelList = channelList.split('[') @@ -417,25 +418,25 @@ class FitsReader(ProcessingUnit): self.nIncohInt = headerObj.header['NINCOHINT'] self.dataBlocksPerFile = headerObj.header['NBLOCK'] self.timeZone = headerObj.header['TIMEZONE'] - + # self.timeInterval = self.ippSeconds * self.nCohInt * self.nIncohInt - + if 'COMMENT' in headerObj.header.keys(): self.comments = headerObj.header['COMMENT'] - + self.readHeightList() - + def readHeightList(self): self.blockIndex = self.blockIndex + 1 obj = self.fitsObj[self.blockIndex] self.heightList = obj.data self.blockIndex = self.blockIndex + 1 - + def readExtension(self): obj = self.fitsObj[self.blockIndex] self.heightList = obj.data self.blockIndex = self.blockIndex + 1 - + def setNextFile(self): if self.online: @@ -445,14 +446,14 @@ class FitsReader(ProcessingUnit): if not(newFile): return 0 - + self.readHeader() self.__setValuesFromHeader() self.nReadBlocks = 0 # self.blockIndex = 1 return 1 - def __searchFilesOffLine(self, + def searchFilesOffLine(self, path, startDate, endDate, @@ -462,12 +463,12 @@ class FitsReader(ProcessingUnit): expLabel='', ext='.fits', walk=True): - + pathList = [] - + if not walk: pathList.append(path) - + else: dirList = [] for thisPath in os.listdir(path): @@ -475,105 +476,105 @@ class FitsReader(ProcessingUnit): continue if not isRadarFolder(thisPath): continue - + dirList.append(thisPath) - + if not(dirList): return None, None - + thisDate = startDate - + while(thisDate <= endDate): year = thisDate.timetuple().tm_year doy = thisDate.timetuple().tm_yday - + matchlist = fnmatch.filter(dirList, '?' + '%4.4d%3.3d' % (year,doy) + '*') if len(matchlist) == 0: thisDate += datetime.timedelta(1) continue for match in matchlist: pathList.append(os.path.join(path,match,expLabel)) - + thisDate += datetime.timedelta(1) - + if pathList == []: print "Any folder was found for the date range: %s-%s" %(startDate, endDate) return None, None - + print "%d folder(s) was(were) found for the date range: %s - %s" %(len(pathList), startDate, endDate) - + filenameList = [] datetimeList = [] - + for i in range(len(pathList)): - + thisPath = pathList[i] - + fileList = glob.glob1(thisPath, "*%s" %ext) fileList.sort() - + for thisFile in fileList: - + filename = os.path.join(thisPath,thisFile) thisDatetime = self.isFileinThisTime(filename, startTime, endTime) - + if not(thisDatetime): continue - + filenameList.append(filename) datetimeList.append(thisDatetime) - + if not(filenameList): print "Any file was found for the time range %s - %s" %(startTime, endTime) return None, None - + print "%d file(s) was(were) found for the time range: %s - %s" %(len(filenameList), startTime, endTime) print - + for i in range(len(filenameList)): print "%s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) self.filenameList = filenameList self.datetimeList = datetimeList - + return pathList, filenameList - + def setup(self, path=None, - startDate=None, - endDate=None, - startTime=datetime.time(0,0,0), - endTime=datetime.time(23,59,59), - set=0, - expLabel = "", - ext = None, + startDate=None, + endDate=None, + startTime=datetime.time(0,0,0), + endTime=datetime.time(23,59,59), + set=0, + expLabel = "", + ext = None, online = False, delay = 60, walk = True): - + if path == None: raise ValueError, "The path is not valid" if ext == None: ext = self.ext - + if not(online): print "Searching files in offline mode ..." - pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate, + pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate, startTime=startTime, endTime=endTime, set=set, expLabel=expLabel, ext=ext, walk=walk) - + if not(pathList): print "No *%s files into the folder %s \nfor the range: %s - %s"%(ext, path, datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()) - + sys.exit(-1) self.fileIndex = -1 self.pathList = pathList self.filenameList = filenameList - + self.online = online self.delay = delay ext = ext.lower() @@ -588,44 +589,44 @@ class FitsReader(ProcessingUnit): print "No files" sys.exit(-1) - - + + def readBlock(self): dataObj = self.fitsObj[self.blockIndex] self.data = dataObj.data self.data_header_dict = dataObj.header self.utc = self.data_header_dict['UTCTIME'] - + self.flagIsNewFile = 0 self.blockIndex += 1 self.nTotalBlocks += 1 self.nReadBlocks += 1 - + return 1 - + def __jumpToLastBlock(self): raise NotImplementedError def __waitNewBlock(self): """ - Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma. - + Return 1 si se encontro un nuevo bloque de datos, 0 de otra forma. + Si el modo de lectura es OffLine siempre retorn 0 """ if not self.online: return 0 - + if (self.nReadBlocks >= self.dataBlocksPerFile): return 0 - + currentPointer = self.fp.tell() - + neededSize = self.processingHeaderObj.blockSize + self.basicHeaderSize - + for nTries in range( self.nTries ): - + self.fp.close() self.fp = open( self.filename, 'rb' ) self.fp.seek( currentPointer ) @@ -636,43 +637,43 @@ class FitsReader(ProcessingUnit): if ( currentSize >= neededSize ): self.__rdBasicHeader() return 1 - + print "\tWaiting %0.2f seconds for the next block, try %03d ..." % (self.delay, nTries+1) sleep( self.delay ) - - + + return 0 - + def __setNewBlock(self): if self.online: self.__jumpToLastBlock() - + if self.flagIsNewFile: return 1 - + self.lastUTTime = self.utc if self.online: if self.__waitNewBlock(): return 1 - + if self.nReadBlocks < self.dataBlocksPerFile: return 1 - + if not(self.setNextFile()): return 0 - - deltaTime = self.utc - self.lastUTTime - + + deltaTime = self.utc - self.lastUTTime + self.flagDiscontinuousBlock = 0 if deltaTime > self.maxTimeStep: self.flagDiscontinuousBlock = 1 return 1 - - + + def readNextBlock(self): if not(self.__setNewBlock()): return 0 @@ -681,63 +682,64 @@ class FitsReader(ProcessingUnit): return 0 return 1 - + def printInfo(self): - + pass - + def getData(self): - + if self.flagNoMoreFiles: self.dataOut.flagNoData = True print 'Process finished' return 0 - + self.flagDiscontinuousBlock = 0 self.flagIsNewBlock = 0 if not(self.readNextBlock()): return 0 - + if self.data is None: self.dataOut.flagNoData = True return 0 - + self.dataOut.data = self.data self.dataOut.data_header = self.data_header_dict self.dataOut.utctime = self.utc - -# self.dataOut.header = self.header_dict + +# self.dataOut.header = self.header_dict # self.dataOut.expName = self.expName # self.dataOut.nChannels = self.nChannels # self.dataOut.timeZone = self.timeZone # self.dataOut.dataBlocksPerFile = self.dataBlocksPerFile -# self.dataOut.comments = self.comments +# self.dataOut.comments = self.comments # # self.dataOut.timeInterval = self.timeInterval # self.dataOut.channelList = self.channelList # self.dataOut.heightList = self.heightList self.dataOut.flagNoData = False - + return self.dataOut.data - + def run(self, **kwargs): - + if not(self.isConfig): self.setup(**kwargs) self.isConfig = True - + self.getData() -class SpectraHeisWriter(Operation): +class SpectraHeisWriter(Operation): # set = None setFile = None idblock = None doypath = None subfolder = None - - def __init__(self): + + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.wrObj = PyFits() -# self.dataOut = dataOut +# self.dataOut = dataOut self.nTotalBlocks=0 # self.set = None self.setFile = None @@ -745,17 +747,17 @@ class SpectraHeisWriter(Operation): self.wrpath = None self.doypath = None self.subfolder = None - self.isConfig = False - + self.isConfig = False + def isNumber(str): """ Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero. - Excepciones: + Excepciones: Si un determinado string no puede ser convertido a numero Input: str, string al cual se le analiza para determinar si convertible a un numero o no - + Return: True : si el string es uno numerico False : no es un string numerico @@ -764,83 +766,83 @@ class SpectraHeisWriter(Operation): float( str ) return True except: - return False - + return False + def setup(self, dataOut, wrpath): if not(os.path.exists(wrpath)): os.mkdir(wrpath) - + self.wrpath = wrpath # self.setFile = 0 self.dataOut = dataOut def putData(self): name= time.localtime( self.dataOut.utctime) - ext=".fits" - + ext=".fits" + if self.doypath == None: self.subfolder = 'F%4.4d%3.3d_%d' % (name.tm_year,name.tm_yday,time.mktime(datetime.datetime.now().timetuple())) self.doypath = os.path.join( self.wrpath, self.subfolder ) os.mkdir(self.doypath) - + if self.setFile == None: # self.set = self.dataOut.set self.setFile = 0 # if self.set != self.dataOut.set: ## self.set = self.dataOut.set # self.setFile = 0 - + #make the filename - thisFile = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext) + thisFile = 'D%4.4d%3.3d_%3.3d%s' % (name.tm_year,name.tm_yday,self.setFile,ext) + + filename = os.path.join(self.wrpath,self.subfolder, thisFile) - filename = os.path.join(self.wrpath,self.subfolder, thisFile) - idblock = numpy.array([self.idblock],dtype="int64") - header=self.wrObj.cFImage(idblock=idblock, + header=self.wrObj.cFImage(idblock=idblock, year=time.gmtime(self.dataOut.utctime).tm_year, month=time.gmtime(self.dataOut.utctime).tm_mon, - day=time.gmtime(self.dataOut.utctime).tm_mday, + day=time.gmtime(self.dataOut.utctime).tm_mday, hour=time.gmtime(self.dataOut.utctime).tm_hour, - minute=time.gmtime(self.dataOut.utctime).tm_min, + minute=time.gmtime(self.dataOut.utctime).tm_min, second=time.gmtime(self.dataOut.utctime).tm_sec) - + c=3E8 deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0] freq=numpy.arange(-1*self.dataOut.nHeights/2.,self.dataOut.nHeights/2.)*(c/(2*deltaHeight*1000)) - + colList = [] - + colFreq=self.wrObj.setColF(name="freq", format=str(self.dataOut.nFFTPoints)+'E', array=freq) - + colList.append(colFreq) nchannel=self.dataOut.nChannels - + for i in range(nchannel): col = self.wrObj.writeData(name="PCh"+str(i+1), format=str(self.dataOut.nFFTPoints)+'E', data=10*numpy.log10(self.dataOut.data_spc[i,:])) - + colList.append(col) - + data=self.wrObj.Ctable(colList=colList) - + self.wrObj.CFile(header,data) - - self.wrObj.wFile(filename) - + + self.wrObj.wFile(filename) + #update the setFile self.setFile += 1 self.idblock += 1 - + return 1 - + def run(self, dataOut, **kwargs): - + if not(self.isConfig): - + self.setup(dataOut, **kwargs) self.isConfig = True - - self.putData() \ No newline at end of file + + self.putData() diff --git a/schainpy/model/io/jroIO_hf.py b/schainpy/model/io/jroIO_hf.py index 382f4c9..5ba1787 100644 --- a/schainpy/model/io/jroIO_hf.py +++ b/schainpy/model/io/jroIO_hf.py @@ -1,7 +1,7 @@ ''' Created on Jul 3, 2014 -@author: roj-com0419 +@author: roj-com0419 ''' import os,sys @@ -20,11 +20,11 @@ def isNumber(str): """ Chequea si el conjunto de caracteres que componen un string puede ser convertidos a un numero. - Excepciones: + Excepciones: Si un determinado string no puede ser convertido a numero Input: str, string al cual se le analiza para determinar si convertible a un numero o no - + Return: True : si el string es uno numerico False : no es un string numerico @@ -45,19 +45,19 @@ def getFileFromSet(path, ext, set=None): # 0 1234 567 89A BCDE # H YYYY DDD SSS .ext - + for thisFile in fileList: try: number= int(thisFile[6:16]) - + # year = int(thisFile[1:5]) # doy = int(thisFile[5:8]) except: continue - + if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): continue - + validFilelist.append(thisFile) if len(validFilelist) < 1: @@ -67,25 +67,25 @@ def getFileFromSet(path, ext, set=None): if set == None: return validFilelist[-1] - + print "set =" ,set for thisFile in validFilelist: if set <= int(thisFile[6:16]): print thisFile,int(thisFile[6:16]) - return thisFile + return thisFile return validFilelist[-1] myfile = fnmatch.filter(validFilelist,'*%10d*'%(set)) #myfile = fnmatch.filter(validFilelist,'*%4.4d%3.3d%3.3d*'%(year,doy,set)) - + if len(myfile)!= 0: return myfile[0] else: filename = '*%10.10d%s'%(set,ext.lower()) print 'the filename %s does not exist'%filename print '...going to the last file: ' - + if validFilelist: validFilelist = sorted( validFilelist, key=str.lower ) return validFilelist[-1] @@ -95,48 +95,48 @@ def getFileFromSet(path, ext, set=None): def getlastFileFromPath(path, ext): """ Depura el fileList dejando solo los que cumplan el formato de "res-xxxxxx.ext" - al final de la depuracion devuelve el ultimo file de la lista que quedo. - - Input: + al final de la depuracion devuelve el ultimo file de la lista que quedo. + + Input: fileList : lista conteniendo todos los files (sin path) que componen una determinada carpeta - ext : extension de los files contenidos en una carpeta - + ext : extension de los files contenidos en una carpeta + Return: El ultimo file de una determinada carpeta, no se considera el path. """ validFilelist = [] fileList = os.listdir(path) - + # 0 1234 567 89A BCDE # H YYYY DDD SSS .ext - + for thisFile in fileList: - + try: number= int(thisFile[6:16]) except: print "There is a file or folder with different format" if not isNumber(number): continue - + # year = thisFile[1:5] # if not isNumber(year): # continue - + # doy = thisFile[5:8] # if not isNumber(doy): # continue - + number= int(number) # year = int(year) # doy = int(doy) - + if (os.path.splitext(thisFile)[-1].lower() != ext.lower()): continue - - + + validFilelist.append(thisFile) - + if validFilelist: validFilelist = sorted( validFilelist, key=str.lower ) @@ -145,7 +145,7 @@ Depura el fileList dejando solo los que cumplan el formato de "res-xxxxxx.ext" return None - + class HFReader(ProcessingUnit): ''' classdocs @@ -161,61 +161,61 @@ class HFReader(ProcessingUnit): nTries = 3 ext = ".hdf5" - def __init__(self): + def __init__(self, **kwargs): ''' Constructor ''' - ProcessingUnit.__init__(self) - + ProcessingUnit.__init__(self, **kwargs) + self.isConfig =False - + self.datablock = None - + self.filename_current=None - + self.utc = 0 - + self.ext='.hdf5' - + self.flagIsNewFile = 1 #------------------------------------------------- self.fileIndex=None - + self.profileIndex_offset=None - + self.filenameList=[] - + self.hfFilePointer= None - + self.filename_online = None - + self.status=True - + self.flagNoMoreFiles= False - + self.__waitForNewFile = 20 - + #-------------------------------------------------- - + self.dataOut = self.createObjByDefault() - - + + def createObjByDefault(self): - + dataObj = Voltage() - + return dataObj - + def setObjProperties(self): - + pass - + def getBlockDimension(self): """ Obtiene la cantidad de puntos a leer por cada bloque de datos - + Affected: self.blocksize @@ -223,13 +223,13 @@ class HFReader(ProcessingUnit): None """ pts2read =self.nChannels*self.nHeights*self.nProfiles - self.blocksize = pts2read - + self.blocksize = pts2read + def __readHeader(self): - + self.nProfiles = 100 self.nHeights = 1000 - self.nChannels = 2 + self.nChannels = 2 self.__firstHeigth=0 self.__nSamples=1000 self.__deltaHeigth=1.5 @@ -239,10 +239,10 @@ class HFReader(ProcessingUnit): self.__frequency=None self.__online = False self.filename_next_set=None - - #print "Frequency of Operation:", self.__frequency - - + + #print "Frequency of Operation:", self.__frequency + + def __setParameters(self,path='', startDate='',endDate='',startTime='', endTime='', walk=''): self.path = path self.startDate = startDate @@ -250,7 +250,7 @@ class HFReader(ProcessingUnit): self.startTime = startTime self.endTime = endTime self.walk = walk - + def __checkPath(self): if os.path.exists(self.path): self.status=1 @@ -259,7 +259,7 @@ class HFReader(ProcessingUnit): print 'Path %s does not exits'%self.path return return - + def __selDates(self, hf_dirname_format): try: dir_hf_filename= self.path+"/"+hf_dirname_format @@ -275,29 +275,29 @@ class HFReader(ProcessingUnit): return hf_dirname_format except: return None - + def __findDataForDates(self,online=False): if not(self.status): return None - + pat = '\d+.\d+' dirnameList = [re.search(pat,x) for x in os.listdir(self.path)] dirnameList = filter(lambda x:x!=None,dirnameList) dirnameList = [x.string for x in dirnameList] - if not(online): - + if not(online): + dirnameList = [self.__selDates(x) for x in dirnameList] dirnameList = filter(lambda x:x!=None,dirnameList) - + if len(dirnameList)>0: self.status = 1 self.dirnameList = dirnameList self.dirnameList.sort() - + else: self.status = 0 return None - + def __getTimeFromData(self): startDateTime_Reader = datetime.datetime.combine(self.startDate,self.startTime) endDateTime_Reader = datetime.datetime.combine(self.endDate,self.endTime) @@ -319,23 +319,23 @@ class HFReader(ProcessingUnit): hour =int(date_time[11:13]) min =int(date_time[14:16]) sec =int(date_time[17:19]) - this_time=datetime.datetime(year,month,dom,hour,min,sec) + this_time=datetime.datetime(year,month,dom,hour,min,sec) if (this_time>=startDateTime_Reader and this_time <= endDateTime_Reader): filter_filenameList.append(filename) filter_filenameList.sort() self.filenameList = filter_filenameList return 1 - + def __getFilenameList(self): #print "hola" #print self.dirnameList dirList = [os.path.join(self.path,x) for x in self.dirnameList] - self.filenameList= dirList + self.filenameList= dirList #print self.filenameList #print "pase",len(self.filenameList) - + def __selectDataForTimes(self, online=False): - + if not(self.status): return None #---------------- @@ -360,7 +360,7 @@ class HFReader(ProcessingUnit): fullfilename=self.path+"/"+filename self.filenameList=[fullfilename] self.filename_next_set=int(filename[6:16])+10 - + self.flag_nextfile=False else: print filename @@ -381,19 +381,19 @@ class HFReader(ProcessingUnit): pass else: print "ESTOY AQUI PORQUE NO EXISTE EL SIGUIENTE ARCHIVO" - + else: filename =getlastFileFromPath(self.path,self.ext) - + if self.flag_nextfile==True: self.dirnameList=[filename] fullfilename=self.path+"/"+filename self.filenameList=[self.filenameList[-1]] self.filename_next_set=int(filename[6:16])+10 - + self.flag_nextfile=False else: - filename=getFileFromSet(self.path,self.ext,self.set) + filename=getFileFromSet(self.path,self.ext,self.set) print filename print "PRIMERA CONDICION" #if self.filename_next_set== int(filename[6:16]): @@ -401,7 +401,7 @@ class HFReader(ProcessingUnit): if filename == None: raise ValueError, "corregir" - + self.dirnameList=[filename] fullfilename=self.path+"/"+filename self.filenameList=[fullfilename] @@ -412,10 +412,10 @@ class HFReader(ProcessingUnit): pass else: print "ESTOY AQUI PORQUE NO EXISTE EL SIGUIENTE ARCHIVO" - - - def __searchFilesOffline(self, + + + def searchFilesOffLine(self, path, startDate, endDate, @@ -423,22 +423,22 @@ class HFReader(ProcessingUnit): startTime=datetime.time(0,0,0), endTime=datetime.time(23,59,59), walk=True): - + self.__setParameters(path, startDate, endDate, startTime, endTime, walk) - + self.__checkPath() - + self.__findDataForDates() #print self.dirnameList - + self.__selectDataForTimes() - + for i in range(len(self.filenameList)): - print "%s"% (self.filenameList[i]) - + print "%s"% (self.filenameList[i]) + return - - def __searchFilesOnline(self, + + def searchFilesOnLine(self, path, expLabel= "", ext=None, @@ -446,40 +446,40 @@ class HFReader(ProcessingUnit): endDate=None, walk=True, set=None): - - + + startDate = datetime.datetime.utcnow().date() endDate = datetime.datetime.utcnow().date() - + self.__setParameters(path=path,startDate=startDate,endDate=endDate,walk=walk) - + self.__checkPath() - - fullpath=path + + fullpath=path print "%s folder was found: " %(fullpath ) - + if set == None: self.set=None filename =getlastFileFromPath(fullpath,ext) startDate= datetime.datetime.utcnow().date endDate= datetime.datetime.utcnow().date() -# +# else: filename= getFileFromSet(fullpath,ext,set) startDate=None endDate=None -# +# if not (filename): return None,None,None,None,None - #print "%s file was found" %(filename) - -# + #print "%s file was found" %(filename) + +# # dir_hf_filename= self.path+"/"+filename # fp= h5py.File(dir_hf_filename,'r') # hipoc=fp['t'].value # fp.close() # date_time=datetime.datetime.utcfromtimestamp(hipoc) -# +# # year =int(date_time[0:4]) # month=int(date_time[5:7]) # dom =int(date_time[8:10]) @@ -497,7 +497,7 @@ class HFReader(ProcessingUnit): #self.__selectDataForTimes(online=True) #return fullpath,filename,year,month,dom,set return - + def __setNextFile(self,online=False): """ """ @@ -505,11 +505,11 @@ class HFReader(ProcessingUnit): newFile = self.__setNextFileOffline() else: newFile = self.__setNextFileOnline() - + if not(newFile): return 0 - return 1 - + return 1 + def __setNextFileOffline(self): """ """ @@ -522,11 +522,11 @@ class HFReader(ProcessingUnit): return 0 filename = self.filenameList[idFile] hfFilePointer =h5py.File(filename,'r') - + epoc=hfFilePointer['t'].value #this_time=datetime.datetime(year,month,dom,hour,min,sec) break - + self.flagIsNewFile = 1 self.fileIndex = idFile self.filename = filename @@ -535,18 +535,18 @@ class HFReader(ProcessingUnit): hfFilePointer.close() self.__t0=epoc print "Setting the file: %s"%self.filename - + return 1 - + def __setNextFileOnline(self): """ - """ + """ print "SOY NONE",self.set if self.set==None: pass else: self.set +=10 - + filename = self.filenameList[0]#fullfilename if self.filename_online != None: self.__selectDataForTimes(online=True) @@ -559,96 +559,96 @@ class HFReader(ProcessingUnit): self.__selectDataForTimes(online=True) filename = self.filenameList[0] sizeoffile=os.path.getsize(filename) - + #print filename sizeoffile=os.path.getsize(filename) if sizeoffile<1670240: print "%s is not the rigth size"%filename delay=50 print 'waiting %d seconds for delay...'%(delay) - time.sleep(delay) + time.sleep(delay) sizeoffile=os.path.getsize(filename) if sizeoffile<1670240: delay=50 print 'waiting %d more seconds for delay...'%(delay) - time.sleep(delay) + time.sleep(delay) sizeoffile=os.path.getsize(filename) if sizeoffile<1670240: delay=50 print 'waiting %d more seconds for delay...'%(delay) - time.sleep(delay) - - try: + time.sleep(delay) + + try: hfFilePointer=h5py.File(filename,'r') - + except: print "Error reading file %s"%filename - + self.filename_online=filename epoc=hfFilePointer['t'].value - + self.hfFilePointer=hfFilePointer hfFilePointer.close() self.__t0=epoc - - + + self.flagIsNewFile = 1 self.filename = filename - + print "Setting the file: %s"%self.filename - return 1 - + return 1 + def __getExpParameters(self): if not(self.status): - return None - + return None + def setup(self, path = None, startDate = None, endDate = None, startTime = datetime.time(0,0,0), - endTime = datetime.time(23,59,59), - set = None, + endTime = datetime.time(23,59,59), + set = None, expLabel = "", ext = None, all=0, timezone=0, - online = False, + online = False, delay = 60, walk = True): ''' In this method we should set all initial parameters. - + ''' if path==None: raise ValueError,"The path is not valid" - + if ext==None: ext = self.ext - + self.timezone= timezone self.online= online self.all=all #if set==None: - + #print set if not(online): print "Searching files in offline mode..." - self.__searchFilesOffline(path, startDate, endDate, ext, startTime, endTime, walk) + self.searchFilesOffLine(path, startDate, endDate, ext, startTime, endTime, walk) else: print "Searching files in online mode..." - self.__searchFilesOnline(path, walk,ext,set=set) + self.searchFilesOnLine(path, walk,ext,set=set) if set==None: pass else: self.set=set-10 - + # for nTries in range(self.nTries): -# -# fullpath,file,year,month,day,set = self.__searchFilesOnline(path=path,expLabel=expLabel,ext=ext, walk=walk,set=set) -# +# +# fullpath,file,year,month,day,set = self.searchFilesOnLine(path=path,expLabel=expLabel,ext=ext, walk=walk,set=set) +# # if fullpath: # break # print '\tWaiting %0.2f sec for an valid file in %s: try %02d ...' % (self.delay, path, nTries+1) @@ -656,57 +656,57 @@ class HFReader(ProcessingUnit): # if not(fullpath): # print "There ins't valid files in %s" % path # return None - - + + if not(self.filenameList): print "There is no files into the folder: %s"%(path) sys.exit(-1) - + self.__getExpParameters() - - + + self.fileIndex = -1 - + self.__setNextFile(online) - + self.__readMetadata() - + self.__setLocalVariables() - + self.__setHeaderDO() #self.profileIndex_offset= 0 - + #self.profileIndex = self.profileIndex_offset - + self.isConfig = True def __readMetadata(self): self.__readHeader() - - + + def __setLocalVariables(self): - + self.datablock = numpy.zeros((self.nChannels, self.nHeights,self.nProfiles), dtype = numpy.complex) # - - - + + + self.profileIndex = 9999 - - + + def __setHeaderDO(self): - - + + self.dataOut.radarControllerHeaderObj = RadarControllerHeader() - + self.dataOut.systemHeaderObj = SystemHeader() - - + + #--------------------------------------------------------- self.dataOut.systemHeaderObj.nProfiles=100 self.dataOut.systemHeaderObj.nSamples=1000 - - + + SAMPLING_STRUCTURE=[('h0', '= self.nProfiles: return 1 return 0 - + def readNextBlock(self): if not(self.__setNewBlock()): return 0 @@ -797,27 +797,27 @@ class HFReader(ProcessingUnit): return 0 return 1 - + def __setNewBlock(self): - + if self.hfFilePointer==None: return 0 - + if self.flagIsNewFile: return 1 - + if self.profileIndex < self.nProfiles: - return 1 - + return 1 + self.__setNextFile(self.online) - + return 1 - - + + def readBlock(self): fp=h5py.File(self.filename,'r') - #Puntero que apunta al archivo hdf5 + #Puntero que apunta al archivo hdf5 ch0=(fp['ch0']).value #Primer canal (100,1000)--(perfiles,alturas) ch1=(fp['ch1']).value #Segundo canal (100,1000)--(perfiles,alturas) fp.close() @@ -825,43 +825,39 @@ class HFReader(ProcessingUnit): ch1= ch1.swapaxes(0,1) #Segundo canal (100,1000)--(alturas,perfiles) self.datablock = numpy.array([ch0,ch1]) self.flagIsNewFile=0 - + self.profileIndex=0 - + return 1 - + def getData(self): if self.flagNoMoreFiles: self.dataOut.flagNoData = True print 'Process finished' return 0 - + if self.__hasNotDataInBuffer(): if not(self.readNextBlock()): self.dataOut.flagNodata=True return 0 - + ############################## ############################## self.dataOut.data = self.datablock[:,:,self.profileIndex] self.dataOut.utctime = self.__t0 + self.dataOut.ippSeconds*self.profileIndex self.dataOut.profileIndex= self.profileIndex self.dataOut.flagNoData=False - self.profileIndex +=1 - + self.profileIndex +=1 + return self.dataOut.data - - + + def run(self, **kwargs): ''' This method will be called many times so here you should put all your code ''' - + if not self.isConfig: self.setup(**kwargs) self.isConfig = True self.getData() - - - - diff --git a/schainpy/model/io/jroIO_kamisr.py b/schainpy/model/io/jroIO_kamisr.py index 9fcbf1c..7e4d14a 100644 --- a/schainpy/model/io/jroIO_kamisr.py +++ b/schainpy/model/io/jroIO_kamisr.py @@ -106,9 +106,9 @@ class AMISRReader(ProcessingUnit): #self.findFiles() if not(online): #Busqueda de archivos offline - self.__searchFilesOffline(path, startDate, endDate, startTime, endTime, walk) + self.searchFilesOffLine(path, startDate, endDate, startTime, endTime, walk) else: - self.__searchFilesOnline(path, startDate, endDate, startTime,endTime,walk) + self.searchFilesOnLine(path, startDate, endDate, startTime,endTime,walk) if not(self.filenameList): print "There is no files into the folder: %s"%(path) @@ -329,7 +329,7 @@ class AMISRReader(ProcessingUnit): self.dirnameList = new_dirnameList return 1 - def __searchFilesOnline(self, path, startDate, endDate, startTime=datetime.time(0,0,0), + def searchFilesOnLine(self, path, startDate, endDate, startTime=datetime.time(0,0,0), endTime=datetime.time(23,59,59),walk=True): if endDate ==None: @@ -349,7 +349,7 @@ class AMISRReader(ProcessingUnit): return - def __searchFilesOffline(self, + def searchFilesOffLine(self, path, startDate, endDate, diff --git a/schainpy/model/io/jroIO_madrigal.py b/schainpy/model/io/jroIO_madrigal.py new file mode 100644 index 0000000..eb764d0 --- /dev/null +++ b/schainpy/model/io/jroIO_madrigal.py @@ -0,0 +1,642 @@ +''' +Created on Aug 1, 2017 + +@author: Juan C. Espinoza +''' + +import os +import sys +import time +import json +import glob +import datetime + +import numpy +import h5py + +from schainpy.model.io.jroIO_base import JRODataReader +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +from schainpy.model.data.jrodata import Parameters +from schainpy.utils import log + +try: + import madrigal.cedar +except: + log.warning( + 'You should install "madrigal library" module if you want to read/write Madrigal data' + ) + +DEF_CATALOG = { + 'principleInvestigator': 'Marco Milla', + 'expPurpose': None, + 'cycleTime': None, + 'correlativeExp': None, + 'sciRemarks': None, + 'instRemarks': None + } +DEF_HEADER = { + 'kindatDesc': None, + 'analyst': 'Jicamarca User', + 'comments': None, + 'history': None + } +MNEMONICS = { + 10: 'jro', + 11: 'jbr', + 840: 'jul', + 13: 'jas', + 1000: 'pbr', + 1001: 'hbr', + 1002: 'obr', +} + +UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone) + +def load_json(obj): + ''' + Parse json as string instead of unicode + ''' + + if isinstance(obj, str): + iterable = json.loads(obj) + else: + iterable = obj + + if isinstance(iterable, dict): + return {str(k): load_json(v) if isinstance(v, dict) else str(v) if isinstance(v, unicode) else v + for k, v in iterable.items()} + elif isinstance(iterable, (list, tuple)): + return [str(v) if isinstance(v, unicode) else v for v in iterable] + + return iterable + + +class MADReader(JRODataReader, ProcessingUnit): + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + + self.dataOut = Parameters() + self.counter_records = 0 + self.nrecords = None + self.flagNoMoreFiles = 0 + self.isConfig = False + self.filename = None + self.intervals = set() + + def setup(self, + path=None, + startDate=None, + endDate=None, + format=None, + startTime=datetime.time(0, 0, 0), + endTime=datetime.time(23, 59, 59), + **kwargs): + + self.path = path + self.startDate = startDate + self.endDate = endDate + self.startTime = startTime + self.endTime = endTime + self.datatime = datetime.datetime(1900,1,1) + self.oneDDict = load_json(kwargs.get('oneDDict', + "{\"GDLATR\":\"lat\", \"GDLONR\":\"lon\"}")) + self.twoDDict = load_json(kwargs.get('twoDDict', + "{\"GDALT\": \"heightList\"}")) + self.ind2DList = load_json(kwargs.get('ind2DList', + "[\"GDALT\"]")) + if self.path is None: + raise ValueError, 'The path is not valid' + + if format is None: + raise ValueError, 'The format is not valid choose simple or hdf5' + elif format.lower() in ('simple', 'txt'): + self.ext = '.txt' + elif format.lower() in ('cedar',): + self.ext = '.001' + else: + self.ext = '.hdf5' + + self.search_files(self.path) + self.fileId = 0 + + if not self.fileList: + raise Warning, 'There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path) + + self.setNextFile() + + def search_files(self, path): + ''' + Searching for madrigal files in path + Creating a list of files to procces included in [startDate,endDate] + + Input: + path - Path to find files + ''' + + log.log('Searching files {} in {} '.format(self.ext, path), 'MADReader') + foldercounter = 0 + fileList0 = glob.glob1(path, '*{}'.format(self.ext)) + fileList0.sort() + + self.fileList = [] + self.dateFileList = [] + + startDate = self.startDate - datetime.timedelta(1) + endDate = self.endDate + datetime.timedelta(1) + + for thisFile in fileList0: + year = thisFile[3:7] + if not year.isdigit(): + continue + + month = thisFile[7:9] + if not month.isdigit(): + continue + + day = thisFile[9:11] + if not day.isdigit(): + continue + + year, month, day = int(year), int(month), int(day) + dateFile = datetime.date(year, month, day) + + if (startDate > dateFile) or (endDate < dateFile): + continue + + self.fileList.append(thisFile) + self.dateFileList.append(dateFile) + + return + + def parseHeader(self): + ''' + ''' + + self.output = {} + self.version = '2' + s_parameters = None + if self.ext == '.txt': + self.parameters = [s.strip().lower() for s in self.fp.readline().strip().split(' ') if s] + elif self.ext == '.hdf5': + metadata = self.fp['Metadata'] + data = self.fp['Data']['Array Layout'] + if 'Independent Spatial Parameters' in metadata: + s_parameters = [s[0].lower() for s in metadata['Independent Spatial Parameters']] + self.version = '3' + one = [s[0].lower() for s in data['1D Parameters']['Data Parameters']] + one_d = [1 for s in one] + two = [s[0].lower() for s in data['2D Parameters']['Data Parameters']] + two_d = [2 for s in two] + self.parameters = one + two + self.parameters_d = one_d + two_d + + log.success('Parameters found: {}'.format(','.join(self.parameters)), + 'MADReader') + if s_parameters: + log.success('Spatial parameters: {}'.format(','.join(s_parameters)), + 'MADReader') + + for param in self.oneDDict.keys(): + if param.lower() not in self.parameters: + log.warning( + 'Parameter {} not found will be ignored'.format( + param), + 'MADReader') + self.oneDDict.pop(param, None) + + for param, value in self.twoDDict.items(): + if param.lower() not in self.parameters: + log.warning( + 'Parameter {} not found, it will be ignored'.format( + param), + 'MADReader') + self.twoDDict.pop(param, None) + continue + if isinstance(value, list): + if value[0] not in self.output: + self.output[value[0]] = [] + self.output[value[0]].append(None) + + def parseData(self): + ''' + ''' + + if self.ext == '.txt': + self.data = numpy.genfromtxt(self.fp, missing_values=('missing')) + self.nrecords = self.data.shape[0] + self.ranges = numpy.unique(self.data[:,self.parameters.index(self.ind2DList[0].lower())]) + elif self.ext == '.hdf5': + self.data = self.fp['Data']['Array Layout'] + self.nrecords = len(self.data['timestamps'].value) + self.ranges = self.data['range'].value + + def setNextFile(self): + ''' + ''' + + file_id = self.fileId + + if file_id == len(self.fileList): + log.success('No more files', 'MADReader') + self.flagNoMoreFiles = 1 + return 0 + + log.success( + 'Opening: {}'.format(self.fileList[file_id]), + 'MADReader' + ) + + filename = os.path.join(self.path, self.fileList[file_id]) + + if self.filename is not None: + self.fp.close() + + self.filename = filename + self.filedate = self.dateFileList[file_id] + + if self.ext=='.hdf5': + self.fp = h5py.File(self.filename, 'r') + else: + self.fp = open(self.filename, 'rb') + + self.parseHeader() + self.parseData() + self.sizeOfFile = os.path.getsize(self.filename) + self.counter_records = 0 + self.flagIsNewFile = 0 + self.fileId += 1 + + return 1 + + def readNextBlock(self): + + while True: + self.flagDiscontinuousBlock = 0 + if self.flagIsNewFile: + if not self.setNextFile(): + return 0 + + self.readBlock() + + if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \ + (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)): + log.warning( + 'Reading Record No. {}/{} -> {} [Skipping]'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), + 'MADReader') + continue + break + + log.log( + 'Reading Record No. {}/{} -> {}'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), + 'MADReader') + + return 1 + + def readBlock(self): + ''' + ''' + dum = [] + if self.ext == '.txt': + dt = self.data[self.counter_records][:6].astype(int) + if datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]).date() > self.datatime.date(): + self.flagDiscontinuousBlock = 1 + self.datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]) + while True: + dt = self.data[self.counter_records][:6].astype(int) + datatime = datetime.datetime(dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]) + if datatime == self.datatime: + dum.append(self.data[self.counter_records]) + self.counter_records += 1 + if self.counter_records == self.nrecords: + self.flagIsNewFile = True + break + continue + self.intervals.add((datatime-self.datatime).seconds) + break + elif self.ext == '.hdf5': + datatime = datetime.datetime.utcfromtimestamp( + self.data['timestamps'][self.counter_records]) + nHeights = len(self.ranges) + for n, param in enumerate(self.parameters): + if self.parameters_d[n] == 1: + dum.append(numpy.ones(nHeights)*self.data['1D Parameters'][param][self.counter_records]) + else: + if self.version == '2': + dum.append(self.data['2D Parameters'][param][self.counter_records]) + else: + tmp = self.data['2D Parameters'][param].value.T + dum.append(tmp[self.counter_records]) + self.intervals.add((datatime-self.datatime).seconds) + if datatime.date()>self.datatime.date(): + self.flagDiscontinuousBlock = 1 + self.datatime = datatime + self.counter_records += 1 + if self.counter_records == self.nrecords: + self.flagIsNewFile = True + + self.buffer = numpy.array(dum) + return + + def set_output(self): + ''' + Storing data from buffer to dataOut object + ''' + + parameters = [None for __ in self.parameters] + + for param, attr in self.oneDDict.items(): + x = self.parameters.index(param.lower()) + setattr(self.dataOut, attr, self.buffer[0][x]) + + for param, value in self.twoDDict.items(): + x = self.parameters.index(param.lower()) + if self.ext == '.txt': + y = self.parameters.index(self.ind2DList[0].lower()) + ranges = self.buffer[:,y] + if self.ranges.size == ranges.size: + continue + index = numpy.where(numpy.in1d(self.ranges, ranges))[0] + dummy = numpy.zeros(self.ranges.shape) + numpy.nan + dummy[index] = self.buffer[:,x] + else: + dummy = self.buffer[x] + + if isinstance(value, str): + if value not in self.ind2DList: + setattr(self.dataOut, value, dummy.reshape(1,-1)) + elif isinstance(value, list): + self.output[value[0]][value[1]] = dummy + parameters[value[1]] = param + + for key, value in self.output.items(): + setattr(self.dataOut, key, numpy.array(value)) + + self.dataOut.parameters = [s for s in parameters if s] + self.dataOut.heightList = self.ranges + self.dataOut.utctime = (self.datatime - datetime.datetime(1970, 1, 1)).total_seconds() + self.dataOut.utctimeInit = self.dataOut.utctime + self.dataOut.paramInterval = min(self.intervals) + self.dataOut.useLocalTime = False + self.dataOut.flagNoData = False + self.dataOut.nrecords = self.nrecords + self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock + + def getData(self): + ''' + Storing data from databuffer to dataOut object + ''' + if self.flagNoMoreFiles: + self.dataOut.flagNoData = True + log.error('No file left to process', 'MADReader') + return 0 + + if not self.readNextBlock(): + self.dataOut.flagNoData = True + return 0 + + self.set_output() + + return 1 + + +class MADWriter(Operation): + + missing = -32767 + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + self.dataOut = Parameters() + self.counter = 0 + self.path = None + self.fp = None + + def run(self, dataOut, path, oneDDict, ind2DList='[]', twoDDict='{}', + metadata='{}', format='cedar', **kwargs): + ''' + Inputs: + path - path where files will be created + oneDDict - json of one-dimensional parameters in record where keys + are Madrigal codes (integers or mnemonics) and values the corresponding + dataOut attribute e.g: { + 'gdlatr': 'lat', + 'gdlonr': 'lon', + 'gdlat2':'lat', + 'glon2':'lon'} + ind2DList - list of independent spatial two-dimensional parameters e.g: + ['heighList'] + twoDDict - json of two-dimensional parameters in record where keys + are Madrigal codes (integers or mnemonics) and values the corresponding + dataOut attribute if multidimensional array specify as tupple + ('attr', pos) e.g: { + 'gdalt': 'heightList', + 'vn1p2': ('data_output', 0), + 'vn2p2': ('data_output', 1), + 'vn3': ('data_output', 2), + 'snl': ('data_SNR', 'db') + } + metadata - json of madrigal metadata (kinst, kindat, catalog and header) + ''' + if not self.isConfig: + self.setup(path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs) + self.isConfig = True + + self.dataOut = dataOut + self.putData() + return + + def setup(self, path, oneDDict, ind2DList, twoDDict, metadata, format, **kwargs): + ''' + Configure Operation + ''' + + self.path = path + self.blocks = kwargs.get('blocks', None) + self.counter = 0 + self.oneDDict = load_json(oneDDict) + self.twoDDict = load_json(twoDDict) + self.ind2DList = load_json(ind2DList) + meta = load_json(metadata) + self.kinst = meta.get('kinst') + self.kindat = meta.get('kindat') + self.catalog = meta.get('catalog', DEF_CATALOG) + self.header = meta.get('header', DEF_HEADER) + if format == 'cedar': + self.ext = '.dat' + self.extra_args = {} + elif format == 'hdf5': + self.ext = '.hdf5' + self.extra_args = {'ind2DList': self.ind2DList} + + self.keys = [k.lower() for k in self.twoDDict] + if 'range' in self.keys: + self.keys.remove('range') + if 'gdalt' in self.keys: + self.keys.remove('gdalt') + + def setFile(self): + ''' + Create new cedar file object + ''' + + self.mnemonic = MNEMONICS[self.kinst] #TODO get mnemonic from madrigal + date = datetime.datetime.utcfromtimestamp(self.dataOut.utctime) + + filename = '{}{}{}'.format(self.mnemonic, + date.strftime('%Y%m%d_%H%M%S'), + self.ext) + + self.fullname = os.path.join(self.path, filename) + + if os.path.isfile(self.fullname) : + log.warning( + 'Destination file {} already exists, previous file deleted.'.format( + self.fullname), + 'MADWriter') + os.remove(self.fullname) + + try: + log.success( + 'Creating file: {}'.format(self.fullname), + 'MADWriter') + self.fp = madrigal.cedar.MadrigalCedarFile(self.fullname, True) + except ValueError, e: + log.error( + 'Impossible to create a cedar object with "madrigal.cedar.MadrigalCedarFile"', + 'MADWriter') + return + + return 1 + + def writeBlock(self): + ''' + Add data records to cedar file taking data from oneDDict and twoDDict + attributes. + Allowed parameters in: parcodes.tab + ''' + + startTime = datetime.datetime.utcfromtimestamp(self.dataOut.utctime) + endTime = startTime + datetime.timedelta(seconds=self.dataOut.paramInterval) + heights = self.dataOut.heightList + + if self.ext == '.dat': + for key, value in self.twoDDict.items(): + if isinstance(value, str): + data = getattr(self.dataOut, value) + invalid = numpy.isnan(data) + data[invalid] = self.missing + elif isinstance(value, (tuple, list)): + attr, key = value + data = getattr(self.dataOut, attr) + invalid = numpy.isnan(data) + data[invalid] = self.missing + + out = {} + for key, value in self.twoDDict.items(): + key = key.lower() + if isinstance(value, str): + if 'db' in value.lower(): + tmp = getattr(self.dataOut, value.replace('_db', '')) + SNRavg = numpy.average(tmp, axis=0) + tmp = 10*numpy.log10(SNRavg) + else: + tmp = getattr(self.dataOut, value) + out[key] = tmp.flatten() + elif isinstance(value, (tuple, list)): + attr, x = value + data = getattr(self.dataOut, attr) + out[key] = data[int(x)] + + a = numpy.array([out[k] for k in self.keys]) + nrows = numpy.array([numpy.isnan(a[:, x]).all() for x in range(len(heights))]) + index = numpy.where(nrows == False)[0] + + rec = madrigal.cedar.MadrigalDataRecord( + self.kinst, + self.kindat, + startTime.year, + startTime.month, + startTime.day, + startTime.hour, + startTime.minute, + startTime.second, + startTime.microsecond/10000, + endTime.year, + endTime.month, + endTime.day, + endTime.hour, + endTime.minute, + endTime.second, + endTime.microsecond/10000, + self.oneDDict.keys(), + self.twoDDict.keys(), + len(index), + **self.extra_args + ) + + # Setting 1d values + for key in self.oneDDict: + rec.set1D(key, getattr(self.dataOut, self.oneDDict[key])) + + # Setting 2d values + nrec = 0 + for n in index: + for key in out: + rec.set2D(key, nrec, out[key][n]) + nrec += 1 + + self.fp.append(rec) + if self.ext == '.hdf5' and self.counter % 500 == 0 and self.counter > 0: + self.fp.dump() + if self.counter % 100 == 0 and self.counter > 0: + log.log( + 'Writing {} records'.format( + self.counter), + 'MADWriter') + + def setHeader(self): + ''' + Create an add catalog and header to cedar file + ''' + + log.success('Closing file {}'.format(self.fullname), 'MADWriter') + + if self.ext == '.dat': + self.fp.write() + else: + self.fp.dump() + self.fp.close() + + header = madrigal.cedar.CatalogHeaderCreator(self.fullname) + header.createCatalog(**self.catalog) + header.createHeader(**self.header) + header.write() + + def putData(self): + + if self.dataOut.flagNoData: + return 0 + + if self.dataOut.flagDiscontinuousBlock or self.counter == self.blocks: + if self.counter > 0: + self.setHeader() + self.counter = 0 + + if self.counter == 0: + self.setFile() + + self.writeBlock() + self.counter += 1 + + def close(self): + + if self.counter > 0: + self.setHeader() diff --git a/schainpy/model/io/jroIO_mira35c.py b/schainpy/model/io/jroIO_mira35c.py new file mode 100644 index 0000000..5ecc67a --- /dev/null +++ b/schainpy/model/io/jroIO_mira35c.py @@ -0,0 +1,800 @@ +import os +import sys +import glob +import fnmatch +import datetime +import time +import re +import h5py +import numpy + +from scipy.optimize import curve_fit +from scipy import asarray as ar, exp +from scipy import stats + +from numpy.ma.core import getdata + +SPEED_OF_LIGHT = 299792458 +SPEED_OF_LIGHT = 3e8 + +try: + from gevent import sleep +except: + from time import sleep + +from schainpy.model.data.jrodata import Spectra +#from schainpy.model.data.BLTRheaderIO import FileHeader, RecordHeader +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +#from schainpy.model.io.jroIO_bltr import BLTRReader +from numpy import imag, shape, NaN, empty + + +class Header(object): + + def __init__(self): + raise NotImplementedError + + def read(self): + + raise NotImplementedError + + def write(self): + + raise NotImplementedError + + def printInfo(self): + + message = "#" * 50 + "\n" + message += self.__class__.__name__.upper() + "\n" + message += "#" * 50 + "\n" + + keyList = self.__dict__.keys() + keyList.sort() + + for key in keyList: + message += "%s = %s" % (key, self.__dict__[key]) + "\n" + + if "size" not in keyList: + attr = getattr(self, "size") + + if attr: + message += "%s = %s" % ("size", attr) + "\n" + + # print message + + +FILE_HEADER = numpy.dtype([ # HEADER 1024bytes + ('Hname', 'a32'), # Original file name + # Date and time when the file was created + ('Htime', numpy.str_, 32), + # Name of operator who created the file + ('Hoper', numpy.str_, 64), + # Place where the measurements was carried out + ('Hplace', numpy.str_, 128), + # Description of measurements + ('Hdescr', numpy.str_, 256), + ('Hdummy', numpy.str_, 512), # Reserved space + # Main chunk 8bytes + # Main chunk signature FZKF or NUIG + ('Msign', numpy.str_, 4), + ('MsizeData', '=5 + ('SPARrawGate1', ' 1180: + self.fp.seek(self.PointerReader, os.SEEK_SET) + self.FirstPoint = self.PointerReader + + else: + self.FirstPoint = 1180 + + self.srviHeader = SRVIHeader() + + self.srviHeader.SRVIread(self.fp) # Se obtiene la cabecera del SRVI + + self.blocksize = self.srviHeader.SizeOfDataBlock1 # Se obtiene el tamao del bloque + + if self.blocksize == 148: + print 'blocksize == 148 bug' + jump = numpy.fromfile(self.fp, [('jump', numpy.str_, 140)], 1) + + # Se obtiene la cabecera del SRVI + self.srviHeader.SRVIread(self.fp) + + if not self.srviHeader.SizeOfSRVI1: + self.fileSelector += 1 + self.nextfileflag == True + self.FileHeaderFlag == True + + self.recordheader = RecordHeader() + self.recordheader.RHread(self.fp) + self.RadarConst = self.recordheader.RadarConst + dwell = self.recordheader.time_t + npw1 = self.recordheader.npw1 + npw2 = self.recordheader.npw2 + + self.dataOut.channelList = range(1) + self.dataOut.nIncohInt = self.Num_inCoh + self.dataOut.nProfiles = self.Num_Bins + self.dataOut.nCohInt = 1 + self.dataOut.windowOfFilter = 1 + self.dataOut.utctime = dwell + self.dataOut.timeZone = 0 + + self.dataOut.outputInterval = self.dataOut.getTimeInterval() + self.dataOut.heightList = self.SPARrawGate1 * self.__deltaHeigth + \ + numpy.array(range(self.Num_Hei)) * self.__deltaHeigth + + self.HSDVsign = numpy.fromfile(self.fp, [('HSDV', numpy.str_, 4)], 1) + self.SizeHSDV = numpy.fromfile(self.fp, [('SizeHSDV', ' 0., self.data_spc, 0) + + self.dataOut.COFA = numpy.array([self.COFA_Co, self.COFA_Cx]) + + print ' ' + print 'SPC', numpy.shape(self.dataOut.data_spc) + # print 'SPC',self.dataOut.data_spc + + noinor1 = 713031680 + noinor2 = 30 + + npw1 = 1 # 0**(npw1/10) * noinor1 * noinor2 + npw2 = 1 # 0**(npw2/10) * noinor1 * noinor2 + self.dataOut.NPW = numpy.array([npw1, npw2]) + + print ' ' + + self.data_spc = numpy.transpose(self.data_spc, (2, 1, 0)) + self.data_spc = numpy.fft.fftshift(self.data_spc, axes=1) + + self.data_spc = numpy.fliplr(self.data_spc) + + self.data_spc = numpy.where(self.data_spc > 0., self.data_spc, 0) + self.dataOut_spc = numpy.ones([1, self.Num_Bins, self.Num_Hei]) + self.dataOut_spc[0, :, :] = self.data_spc[0, :, :] + # print 'SHAPE', self.dataOut_spc.shape + # For nyquist correction: + # fix = 20 # ~3m/s + #shift = self.Num_Bins/2 + fix + #self.data_spc = numpy.array([ self.data_spc[: , self.Num_Bins-shift+1: , :] , self.data_spc[: , 0:self.Num_Bins-shift , :]]) + + '''Block Reading, the Block Data is received and Reshape is used to give it + shape. + ''' + + self.PointerReader = self.fp.tell() diff --git a/schainpy/model/io/jroIO_param.py b/schainpy/model/io/jroIO_param.py index 0a51199..fa4495c 100644 --- a/schainpy/model/io/jroIO_param.py +++ b/schainpy/model/io/jroIO_param.py @@ -15,71 +15,72 @@ import schainpy class ParamReader(ProcessingUnit): ''' Reads HDF5 format files - + path - + startDate - + endDate - + startTime - + endTime ''' - + ext = ".hdf5" - + optchar = "D" - + timezone = None - + startTime = None - + endTime = None - + fileIndex = None - + utcList = None #To select data in the utctime list - + blockList = None #List to blocks to be read from the file - - blocksPerFile = None #Number of blocks to be read - + + blocksPerFile = None #Number of blocks to be read + blockIndex = None - + path = None - + #List of Files - + filenameList = None - + datetimeList = None - + #Hdf5 File - + listMetaname = None - + listMeta = None - + listDataname = None - + listData = None - + listShapes = None - + fp = None - + #dataOut reconstruction - + dataOut = None - - - def __init__(self): + + + def __init__(self, **kwargs): + ProcessingUnit.__init__(self, **kwargs) self.dataOut = Parameters() return - - def setup(self, **kwargs): - + + def setup(self, **kwargs): + path = kwargs['path'] startDate = kwargs['startDate'] endDate = kwargs['endDate'] @@ -94,12 +95,12 @@ class ParamReader(ProcessingUnit): self.timezone = kwargs['timezone'] else: self.timezone = 'lt' - + print "[Reading] Searching files in offline mode ..." - pathList, filenameList = self.__searchFilesOffLine(path, startDate=startDate, endDate=endDate, + pathList, filenameList = self.searchFilesOffLine(path, startDate=startDate, endDate=endDate, startTime=startTime, endTime=endTime, - ext=ext, walk=walk) - + ext=ext, walk=walk) + if not(filenameList): print "There is no files into the folder: %s"%(path) sys.exit(-1) @@ -107,14 +108,14 @@ class ParamReader(ProcessingUnit): self.fileIndex = -1 self.startTime = startTime self.endTime = endTime - + self.__readMetadata() - + self.__setNextFileOffline() - + return - - def __searchFilesOffLine(self, + + def searchFilesOffLine(self, path, startDate=None, endDate=None, @@ -122,99 +123,99 @@ class ParamReader(ProcessingUnit): endTime=datetime.time(23,59,59), ext='.hdf5', walk=True): - + expLabel = '' self.filenameList = [] self.datetimeList = [] - + pathList = [] - + JRODataObj = JRODataReader() dateList, pathList = JRODataObj.findDatafiles(path, startDate, endDate, expLabel, ext, walk, include_path=True) - + if dateList == []: print "[Reading] No *%s files in %s from %s to %s)"%(ext, path, datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()) - + return None, None - + if len(dateList) > 1: print "[Reading] %d days were found in date range: %s - %s" %(len(dateList), startDate, endDate) else: print "[Reading] data was found for the date %s" %(dateList[0]) - + filenameList = [] datetimeList = [] - + #---------------------------------------------------------------------------------- - + for thisPath in pathList: # thisPath = pathList[pathDict[file]] - + fileList = glob.glob1(thisPath, "*%s" %ext) fileList.sort() - + for file in fileList: - + filename = os.path.join(thisPath,file) - + if not isFileInDateRange(filename, startDate, endDate): continue - + thisDatetime = self.__isFileInTimeRange(filename, startDate, endDate, startTime, endTime) - + if not(thisDatetime): continue - + filenameList.append(filename) datetimeList.append(thisDatetime) - + if not(filenameList): print "[Reading] Any file was found int time range %s - %s" %(datetime.datetime.combine(startDate,startTime).ctime(), datetime.datetime.combine(endDate,endTime).ctime()) return None, None - + print "[Reading] %d file(s) was(were) found in time range: %s - %s" %(len(filenameList), startTime, endTime) print - - for i in range(len(filenameList)): - print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) + +# for i in range(len(filenameList)): +# print "[Reading] %s -> [%s]" %(filenameList[i], datetimeList[i].ctime()) self.filenameList = filenameList self.datetimeList = datetimeList - + return pathList, filenameList - + def __isFileInTimeRange(self,filename, startDate, endDate, startTime, endTime): - + """ Retorna 1 si el archivo de datos se encuentra dentro del rango de horas especificado. - + Inputs: filename : nombre completo del archivo de datos en formato Jicamarca (.r) - + startDate : fecha inicial del rango seleccionado en formato datetime.date - + endDate : fecha final del rango seleccionado en formato datetime.date - + startTime : tiempo inicial del rango seleccionado en formato datetime.time - + endTime : tiempo final del rango seleccionado en formato datetime.time - + Return: Boolean : Retorna True si el archivo de datos contiene datos en el rango de fecha especificado, de lo contrario retorna False. - + Excepciones: Si el archivo no existe o no puede ser abierto Si la cabecera no puede ser leida. - + """ - + try: fp = h5py.File(filename,'r') grp1 = fp['Data'] - + except IOError: traceback.print_exc() raise IOError, "The file %s can't be opened" %(filename) @@ -225,50 +226,50 @@ class ParamReader(ProcessingUnit): thisUtcTime = grp2.value[0] fp.close() - + if self.timezone == 'lt': thisUtcTime -= 5*3600 - + thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600) # thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0]) thisDate = thisDatetime.date() thisTime = thisDatetime.time() - + startUtcTime = (datetime.datetime.combine(thisDate,startTime)- datetime.datetime(1970, 1, 1)).total_seconds() endUtcTime = (datetime.datetime.combine(thisDate,endTime)- datetime.datetime(1970, 1, 1)).total_seconds() - + #General case # o>>>>>>>>>>>>>><<<<<<<<<<<<<= startTime: - thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime) + thisUtcLog = numpy.logical_and(thisUtcTime > startUtcTime, thisUtcTime < endUtcTime) if numpy.any(thisUtcLog): #If there is one block between the hours mentioned return thisDatetime return None - - #If endTime < startTime then endTime belongs to the next day + + #If endTime < startTime then endTime belongs to the next day #<<<<<<<<<<>>>>>>>>>> #-----------o----------------------------o----------- # endTime startTime - + if (thisDate == startDate) and numpy.all(thisUtcTime < startUtcTime): return None - + if (thisDate == endDate) and numpy.all(thisUtcTime > endUtcTime): return None - + if numpy.all(thisUtcTime < startUtcTime) and numpy.all(thisUtcTime > endUtcTime): return None - + return thisDatetime - + def __setNextFileOffline(self): - + self.fileIndex += 1 idFile = self.fileIndex - + if not(idFile < len(self.filenameList)): print "No more Files" return 0 @@ -276,13 +277,13 @@ class ParamReader(ProcessingUnit): filename = self.filenameList[idFile] filePointer = h5py.File(filename,'r') - + self.filename = filename self.fp = filePointer print "Setting the file: %s"%self.filename - + # self.__readMetadata() self.__setBlockList() self.__readData() @@ -290,79 +291,79 @@ class ParamReader(ProcessingUnit): # self.nRecords = self.fp['Data'].attrs['nRecords'] self.blockIndex = 0 return 1 - + def __setBlockList(self): ''' Selects the data within the times defined - + self.fp self.startTime self.endTime - + self.blockList self.blocksPerFile - + ''' fp = self.fp startTime = self.startTime endTime = self.endTime - + grp = fp['Data'] thisUtcTime = grp['utctime'].value.astype(numpy.float)[0] - + #ERROOOOR if self.timezone == 'lt': thisUtcTime -= 5*3600 - + thisDatetime = datetime.datetime.fromtimestamp(thisUtcTime[0] + 5*3600) - + thisDate = thisDatetime.date() thisTime = thisDatetime.time() - + startUtcTime = (datetime.datetime.combine(thisDate,startTime) - datetime.datetime(1970, 1, 1)).total_seconds() endUtcTime = (datetime.datetime.combine(thisDate,endTime) - datetime.datetime(1970, 1, 1)).total_seconds() - + ind = numpy.where(numpy.logical_and(thisUtcTime >= startUtcTime, thisUtcTime < endUtcTime))[0] - + self.blockList = ind self.blocksPerFile = len(ind) - + return - + def __readMetadata(self): ''' Reads Metadata - - self.pathMeta - + + self.pathMeta + self.listShapes self.listMetaname self.listMeta - + ''' - + # grp = self.fp['Data'] # pathMeta = os.path.join(self.path, grp.attrs['metadata']) -# +# # if pathMeta == self.pathMeta: # return # else: # self.pathMeta = pathMeta -# +# # filePointer = h5py.File(self.pathMeta,'r') # groupPointer = filePointer['Metadata'] - + filename = self.filenameList[0] fp = h5py.File(filename,'r') - + gp = fp['Metadata'] - + listMetaname = [] listMetadata = [] for item in gp.items(): name = item[0] - + if name=='array dimensions': table = gp[name][:] listShapes = {} @@ -372,49 +373,49 @@ class ParamReader(ProcessingUnit): data = gp[name].value listMetaname.append(name) listMetadata.append(data) - + # if name=='type': # self.__initDataOut(data) - + self.listShapes = listShapes self.listMetaname = listMetaname self.listMeta = listMetadata - + fp.close() return - + def __readData(self): grp = self.fp['Data'] listdataname = [] listdata = [] - + for item in grp.items(): name = item[0] listdataname.append(name) - + array = self.__setDataArray(grp[name],self.listShapes[name]) listdata.append(array) - + self.listDataname = listdataname self.listData = listdata return - + def __setDataArray(self, dataset, shapes): - - nDims = shapes[0] - + + nDims = shapes[0] + nDim2 = shapes[1] #Dimension 0 - + nDim1 = shapes[2] #Dimension 1, number of Points or Parameters - + nDim0 = shapes[3] #Dimension 2, number of samples or ranges - + mode = shapes[4] #Mode of storing - + blockList = self.blockList - + blocksPerFile = self.blocksPerFile - + #Depending on what mode the data was stored if mode == 0: #Divided in channels arrayData = dataset.value.astype(numpy.float)[0][blockList] @@ -428,7 +429,7 @@ class ParamReader(ProcessingUnit): #Selecting part of the dataset utctime = arrayData[:,0] u, indices = numpy.unique(utctime, return_index=True) - + if blockList.size != indices.size: indMin = indices[blockList[0]] if blockList[1] + 1 >= indices.size: @@ -437,46 +438,46 @@ class ParamReader(ProcessingUnit): indMax = indices[blockList[1] + 1] arrayData = arrayData[indMin:indMax,:] return arrayData - - # One dimension + + # One dimension if nDims == 0: arrayData = dataset.value.astype(numpy.float)[0][blockList] - - # Two dimensions + + # Two dimensions elif nDims == 2: arrayData = numpy.zeros((blocksPerFile,nDim1,nDim0)) newShapes = (blocksPerFile,nDim0) - nDatas = nDim1 - - for i in range(nDatas): + nDatas = nDim1 + + for i in range(nDatas): data = dataset[strds + str(i)].value - arrayData[:,i,:] = data[blockList,:] - - # Three dimensions + arrayData[:,i,:] = data[blockList,:] + + # Three dimensions else: - arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0)) + arrayData = numpy.zeros((blocksPerFile,nDim2,nDim1,nDim0)) for i in range(nDatas): - + data = dataset[strds + str(i)].value - + for b in range(blockList.size): arrayData[b,:,i,:] = data[:,:,blockList[b]] - - return arrayData - + + return arrayData + def __setDataOut(self): listMeta = self.listMeta listMetaname = self.listMetaname listDataname = self.listDataname listData = self.listData listShapes = self.listShapes - + blockIndex = self.blockIndex # blockList = self.blockList - + for i in range(len(listMeta)): setattr(self.dataOut,listMetaname[i],listMeta[i]) - + for j in range(len(listData)): nShapes = listShapes[listDataname[j]][0] mode = listShapes[listDataname[j]][4] @@ -491,163 +492,152 @@ class ParamReader(ProcessingUnit): selectedData = self.__selectDataMode2(listData[j], blockIndex) setattr(self.dataOut, listDataname[j], selectedData) return - + def __selectDataMode2(self, data, blockIndex): utctime = data[:,0] aux, indices = numpy.unique(utctime, return_inverse=True) selInd = numpy.where(indices == blockIndex)[0] selData = data[selInd,:] - + return selData - + def getData(self): - + # if self.flagNoMoreFiles: # self.dataOut.flagNoData = True # print 'Process finished' # return 0 -# +# if self.blockIndex==self.blocksPerFile: if not( self.__setNextFileOffline() ): self.dataOut.flagNoData = True return 0 # if self.datablock == None: # setear esta condicion cuando no hayan datos por leers -# self.dataOut.flagNoData = True +# self.dataOut.flagNoData = True # return 0 # self.__readData() self.__setDataOut() self.dataOut.flagNoData = False - + self.blockIndex += 1 - + return - + def run(self, **kwargs): - + if not(self.isConfig): self.setup(**kwargs) # self.setObjProperties() self.isConfig = True - + self.getData() - + return class ParamWriter(Operation): ''' - HDF5 Writer, stores parameters data in HDF5 format files - + HDF5 Writer, stores parameters data in HDF5 format files + path: path where the files will be stored - + blocksPerFile: number of blocks that will be saved in per HDF5 format file - + mode: selects the data stacking mode: '0' channels, '1' parameters, '3' table (for meteors) - + metadataList: list of attributes that will be stored as metadata - + dataList: list of attributes that will be stores as data - + ''' - - + + ext = ".hdf5" - + optchar = "D" - + metaoptchar = "M" - + metaFile = None - + filename = None - + path = None - + setFile = None - + fp = None - + grp = None - + ds = None - + firsttime = True - + #Configurations - + blocksPerFile = None - + blockIndex = None - + dataOut = None - + #Data Arrays - + dataList = None - + metadataList = None - + # arrayDim = None dsList = None #List of dictionaries with dataset properties - + tableDim = None - + # dtype = [('arrayName', 'S20'),('nChannels', 'i'), ('nPoints', 'i'), ('nSamples', 'i'),('mode', 'b')] - + dtype = [('arrayName', 'S20'),('nDimensions', 'i'), ('dim2', 'i'), ('dim1', 'i'),('dim0', 'i'),('mode', 'b')] currentDay = None - + lastTime = None - - def __init__(self): - - Operation.__init__(self) + + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.isConfig = False return - - def setup(self, dataOut, **kwargs): - self.path = kwargs['path'] - - if kwargs.has_key('blocksPerFile'): - self.blocksPerFile = kwargs['blocksPerFile'] - else: - self.blocksPerFile = 10 - - self.metadataList = kwargs['metadataList'] - self.dataList = kwargs['dataList'] + def setup(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs): + self.path = path + self.blocksPerFile = blocksPerFile + self.metadataList = metadataList + self.dataList = dataList self.dataOut = dataOut - - if kwargs.has_key('mode'): - mode = kwargs['mode'] - - if type(mode) == int: - mode = numpy.zeros(len(self.dataList)) + mode - else: - mode = numpy.ones(len(self.dataList)) - self.mode = mode + if self.mode is not None: + self.mode = numpy.zeros(len(self.dataList)) + mode + else: + self.mode = numpy.ones(len(self.dataList)) + arrayDim = numpy.zeros((len(self.dataList),5)) - - #Table dimensions + + #Table dimensions dtype0 = self.dtype tableList = [] - + #Dictionary and list of tables dsList = [] - + for i in range(len(self.dataList)): dsDict = {} dataAux = getattr(self.dataOut, self.dataList[i]) dsDict['variable'] = self.dataList[i] #--------------------- Conditionals ------------------------ #There is no data - if dataAux is None: + if dataAux is None: return 0 - + #Not array, just a number #Mode 0 if type(dataAux)==float or type(dataAux)==int: @@ -658,27 +648,27 @@ class ParamWriter(Operation): #Mode 2: meteors elif mode[i] == 2: -# dsDict['nDim'] = 0 - dsDict['dsName'] = 'table0' +# dsDict['nDim'] = 0 + dsDict['dsName'] = 'table0' dsDict['mode'] = 2 # Mode meteors dsDict['shape'] = dataAux.shape[-1] dsDict['nDim'] = 0 dsDict['dsNumber'] = 1 - + arrayDim[i,3] = dataAux.shape[-1] arrayDim[i,4] = mode[i] #Mode the data was stored - + dsList.append(dsDict) - + #Mode 1 else: arrayDim0 = dataAux.shape #Data dimensions arrayDim[i,0] = len(arrayDim0) #Number of array dimensions arrayDim[i,4] = mode[i] #Mode the data was stored - + strtable = 'table' dsDict['mode'] = 1 # Mode parameters - + # Three-dimension arrays if len(arrayDim0) == 3: arrayDim[i,1:-1] = numpy.array(arrayDim0) @@ -686,12 +676,12 @@ class ParamWriter(Operation): dsDict['dsNumber'] = nTables dsDict['shape'] = arrayDim[i,2:4] dsDict['nDim'] = 3 - + for j in range(nTables): dsDict = dsDict.copy() dsDict['dsName'] = strtable + str(j) dsList.append(dsDict) - + # Two-dimension arrays elif len(arrayDim0) == 2: arrayDim[i,2:-1] = numpy.array(arrayDim0) @@ -699,12 +689,12 @@ class ParamWriter(Operation): dsDict['dsNumber'] = nTables dsDict['shape'] = arrayDim[i,3] dsDict['nDim'] = 2 - + for j in range(nTables): dsDict = dsDict.copy() dsDict['dsName'] = strtable + str(j) dsList.append(dsDict) - + # One-dimension arrays elif len(arrayDim0) == 1: arrayDim[i,3] = arrayDim0[0] @@ -713,46 +703,46 @@ class ParamWriter(Operation): dsDict['dsName'] = strtable + str(0) dsDict['nDim'] = 1 dsList.append(dsDict) - + table = numpy.array((self.dataList[i],) + tuple(arrayDim[i,:]),dtype = dtype0) tableList.append(table) - + # self.arrayDim = arrayDim - self.dsList = dsList - self.tableDim = numpy.array(tableList, dtype = dtype0) + self.dsList = dsList + self.tableDim = numpy.array(tableList, dtype = dtype0) self.blockIndex = 0 - + timeTuple = time.localtime(dataOut.utctime) self.currentDay = timeTuple.tm_yday return 1 def putMetadata(self): - + fp = self.createMetadataFile() - self.writeMetadata(fp) + self.writeMetadata(fp) fp.close() return - + def createMetadataFile(self): ext = self.ext path = self.path setFile = self.setFile - + timeTuple = time.localtime(self.dataOut.utctime) - - subfolder = '' + + subfolder = '' fullpath = os.path.join( path, subfolder ) - + if not( os.path.exists(fullpath) ): os.mkdir(fullpath) setFile = -1 #inicializo mi contador de seteo - - subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) + + subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) fullpath = os.path.join( path, subfolder ) - + if not( os.path.exists(fullpath) ): os.mkdir(fullpath) - setFile = -1 #inicializo mi contador de seteo + setFile = -1 #inicializo mi contador de seteo else: filesList = os.listdir( fullpath ) @@ -765,18 +755,25 @@ class ParamWriter(Operation): # x YYYY DDD SSS .ext if isNumber( filen[8:11] ): setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file - else: + else: setFile = -1 else: setFile = -1 #inicializo mi contador de seteo - setFile += 1 - - file = '%s%4.4d%3.3d%3.3d%s' % (self.metaoptchar, - timeTuple.tm_year, - timeTuple.tm_yday, - setFile, - ext ) + if self.setType is None: + setFile += 1 + file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar, + timeTuple.tm_year, + timeTuple.tm_yday, + setFile, + ext ) + else: + setFile = timeTuple.tm_hour*60+timeTuple.tm_min + file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar, + timeTuple.tm_year, + timeTuple.tm_yday, + setFile, + ext ) filename = os.path.join( path, subfolder, file ) self.metaFile = file @@ -784,29 +781,29 @@ class ParamWriter(Operation): fp = h5py.File(filename,'w') return fp - - def writeMetadata(self, fp): - + + def writeMetadata(self, fp): + grp = fp.create_group("Metadata") grp.create_dataset('array dimensions', data = self.tableDim, dtype = self.dtype) - + for i in range(len(self.metadataList)): grp.create_dataset(self.metadataList[i], data=getattr(self.dataOut, self.metadataList[i])) return - + def timeFlag(self): currentTime = self.dataOut.utctime - + if self.lastTime is None: self.lastTime = currentTime - + #Day timeTuple = time.localtime(currentTime) dataDay = timeTuple.tm_yday - + #Time timeDiff = currentTime - self.lastTime - + #Si el dia es diferente o si la diferencia entre un dato y otro supera la hora if dataDay != self.currentDay: self.currentDay = dataDay @@ -819,17 +816,17 @@ class ParamWriter(Operation): return False def setNextFile(self): - + ext = self.ext path = self.path setFile = self.setFile mode = self.mode - + timeTuple = time.localtime(self.dataOut.utctime) subfolder = 'd%4.4d%3.3d' % (timeTuple.tm_year,timeTuple.tm_yday) fullpath = os.path.join( path, subfolder ) - + if os.path.exists(fullpath): filesList = os.listdir( fullpath ) filesList = [k for k in filesList if 'D' in k] @@ -841,38 +838,45 @@ class ParamWriter(Operation): # x YYYY DDD SSS .ext if isNumber( filen[8:11] ): setFile = int( filen[8:11] ) #inicializo mi contador de seteo al seteo del ultimo file - else: + else: setFile = -1 else: setFile = -1 #inicializo mi contador de seteo else: - os.mkdir(fullpath) - setFile = -1 #inicializo mi contador de seteo - - setFile += 1 - - file = '%s%4.4d%3.3d%3.3d%s' % (self.optchar, - timeTuple.tm_year, - timeTuple.tm_yday, - setFile, - ext ) + os.makedirs(fullpath) + setFile = -1 #inicializo mi contador de seteo + + if self.setType is None: + setFile += 1 + file = '%s%4.4d%3.3d%03d%s' % (self.metaoptchar, + timeTuple.tm_year, + timeTuple.tm_yday, + setFile, + ext ) + else: + setFile = timeTuple.tm_hour*60+timeTuple.tm_min + file = '%s%4.4d%3.3d%04d%s' % (self.metaoptchar, + timeTuple.tm_year, + timeTuple.tm_yday, + setFile, + ext ) filename = os.path.join( path, subfolder, file ) #Setting HDF5 File fp = h5py.File(filename,'w') #write metadata - self.writeMetadata(fp) + self.writeMetadata(fp) #Write data grp = fp.create_group("Data") # grp.attrs['metadata'] = self.metaFile - + # grp.attrs['blocksPerFile'] = 0 ds = [] data = [] dsList = self.dsList i = 0 - while i < len(dsList): + while i < len(dsList): dsInfo = dsList[i] #One-dimension data if dsInfo['mode'] == 0: @@ -891,32 +895,32 @@ class ParamWriter(Operation): data.append([]) i += 1 continue - + elif dsInfo['mode'] == 1: grp0 = grp.create_group(dsInfo['variable']) - + for j in range(dsInfo['dsNumber']): dsInfo = dsList[i] tableName = dsInfo['dsName'] shape = int(dsInfo['shape']) - - if dsInfo['nDim'] == 3: + + if dsInfo['nDim'] == 3: ds0 = grp0.create_dataset(tableName, (shape[0],shape[1],1) , data = numpy.zeros((shape[0],shape[1],1)), maxshape = (None,shape[1],None), chunks=True) else: ds0 = grp0.create_dataset(tableName, (1,shape), data = numpy.zeros((1,shape)) , maxshape=(None,shape), chunks=True) - + ds.append(ds0) data.append([]) i += 1 # nDimsForDs.append(nDims[i]) - + fp.flush() fp.close() - + # self.nDatas = nDatas # self.nDims = nDims # self.nDimsForDs = nDimsForDs - #Saving variables + #Saving variables print 'Writing the file: %s'%filename self.filename = filename # self.fp = fp @@ -928,25 +932,25 @@ class ParamWriter(Operation): self.firsttime = True self.blockIndex = 0 return - + def putData(self): if self.blockIndex == self.blocksPerFile or self.timeFlag(): - self.setNextFile() - + self.setNextFile() + # if not self.firsttime: self.readBlock() self.setBlock() #Prepare data to be written self.writeBlock() #Write data - + return - + def readBlock(self): - + ''' data Array configured - - + + self.data ''' dsList = self.dsList @@ -955,53 +959,53 @@ class ParamWriter(Operation): fp = h5py.File(self.filename,'r+') grp = fp["Data"] ind = 0 - + # grp.attrs['blocksPerFile'] = 0 - while ind < len(dsList): + while ind < len(dsList): dsInfo = dsList[ind] - + if dsInfo['mode'] == 0: ds0 = grp[dsInfo['variable']] ds[ind] = ds0 ind += 1 else: - + grp0 = grp[dsInfo['variable']] - + for j in range(dsInfo['dsNumber']): dsInfo = dsList[ind] ds0 = grp0[dsInfo['dsName']] ds[ind] = ds0 ind += 1 - + self.fp = fp self.grp = grp self.ds = ds - + return def setBlock(self): ''' data Array configured - - + + self.data ''' #Creating Arrays dsList = self.dsList data = self.data ind = 0 - - while ind < len(dsList): + + while ind < len(dsList): dsInfo = dsList[ind] dataAux = getattr(self.dataOut, dsInfo['variable']) - + mode = dsInfo['mode'] nDim = dsInfo['nDim'] - + if mode == 0 or mode == 2 or nDim == 1: data[ind] = dataAux - ind += 1 + ind += 1 # elif nDim == 1: # data[ind] = numpy.reshape(dataAux,(numpy.size(dataAux),1)) # ind += 1 @@ -1016,38 +1020,38 @@ class ParamWriter(Operation): self.data = data return - + def writeBlock(self): ''' Saves the block in the HDF5 file ''' - dsList = self.dsList - + dsList = self.dsList + for i in range(len(self.ds)): - dsInfo = dsList[i] + dsInfo = dsList[i] nDim = dsInfo['nDim'] mode = dsInfo['mode'] - + # First time if self.firsttime: # self.ds[i].resize(self.data[i].shape) # self.ds[i][self.blockIndex,:] = self.data[i] if type(self.data[i]) == numpy.ndarray: - + if nDim == 3: self.data[i] = self.data[i].reshape((self.data[i].shape[0],self.data[i].shape[1],1)) self.ds[i].resize(self.data[i].shape) if mode == 2: self.ds[i].resize(self.data[i].shape) - self.ds[i][:] = self.data[i] - else: - + self.ds[i][:] = self.data[i] + else: + # From second time # Meteors! if mode == 2: dataShape = self.data[i].shape dsShape = self.ds[i].shape - self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1])) + self.ds[i].resize((self.ds[i].shape[0] + dataShape[0],self.ds[i].shape[1])) self.ds[i][dsShape[0]:,:] = self.data[i] # No dimension elif mode == 0: @@ -1056,37 +1060,36 @@ class ParamWriter(Operation): # One dimension elif nDim == 1: self.ds[i].resize((self.ds[i].shape[0] + 1, self.ds[i].shape[1])) - self.ds[i][-1,:] = self.data[i] + self.ds[i][-1,:] = self.data[i] # Two dimension elif nDim == 2: - self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1])) + self.ds[i].resize((self.ds[i].shape[0] + 1,self.ds[i].shape[1])) self.ds[i][self.blockIndex,:] = self.data[i] # Three dimensions elif nDim == 3: - self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1)) + self.ds[i].resize((self.ds[i].shape[0],self.ds[i].shape[1],self.ds[i].shape[2]+1)) self.ds[i][:,:,-1] = self.data[i] - - self.firsttime = False + + self.firsttime = False self.blockIndex += 1 - + #Close to save changes self.fp.flush() self.fp.close() return - - def run(self, dataOut, **kwargs): + + def run(self, dataOut, path=None, blocksPerFile=10, metadataList=None, dataList=None, mode=None, **kwargs): if not(self.isConfig): - flagdata = self.setup(dataOut, **kwargs) - + flagdata = self.setup(dataOut, path=path, blocksPerFile=blocksPerFile, + metadataList=metadataList, dataList=dataList, mode=mode, **kwargs) + if not(flagdata): return - + self.isConfig = True # self.putMetadata() self.setNextFile() - + self.putData() return - - diff --git a/schainpy/model/io/jroIO_spectra.py b/schainpy/model/io/jroIO_spectra.py index aba11f2..bebef63 100644 --- a/schainpy/model/io/jroIO_spectra.py +++ b/schainpy/model/io/jroIO_spectra.py @@ -11,174 +11,174 @@ from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, from schainpy.model.data.jrodata import Spectra class SpectraReader(JRODataReader, ProcessingUnit): - """ + """ Esta clase permite leer datos de espectros desde archivos procesados (.pdata). La lectura - de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones) + de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones) son almacenados en tres buffer's para el Self Spectra, el Cross Spectra y el DC Channel. paresCanalesIguales * alturas * perfiles (Self Spectra) paresCanalesDiferentes * alturas * perfiles (Cross Spectra) canales * alturas (DC Channels) - Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader, + Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader, RadarControllerHeader y Spectra. Los tres primeros se usan para almacenar informacion de la cabecera de datos (metadata), y el cuarto (Spectra) para obtener y almacenar un bloque de datos desde el "buffer" cada vez que se ejecute el metodo "getData". - - Example: + + Example: dpath = "/home/myuser/data" - + startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0) - + endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0) - + readerObj = SpectraReader() - + readerObj.setup(dpath, startTime, endTime) - + while(True): - + readerObj.getData() - + print readerObj.data_spc - + print readerObj.data_cspc - + print readerObj.data_dc - + if readerObj.flagNoMoreFiles: break - + """ pts2read_SelfSpectra = 0 - + pts2read_CrossSpectra = 0 - + pts2read_DCchannels = 0 - + ext = ".pdata" - + optchar = "P" - + dataOut = None - + nRdChannels = None - + nRdPairs = None - + rdPairList = [] - - def __init__(self): - """ + + def __init__(self, **kwargs): + """ Inicializador de la clase SpectraReader para la lectura de datos de espectros. - Inputs: + Inputs: dataOut : Objeto de la clase Spectra. Este objeto sera utilizado para almacenar un perfil de datos cada vez que se haga un requerimiento (getData). El perfil sera obtenido a partir del buffer de datos, si el buffer esta vacio se hara un nuevo proceso de lectura de un bloque de datos. Si este parametro no es pasado se creara uno internamente. - - Affected: + + Affected: self.dataOut Return : None """ - + #Eliminar de la base la herencia - ProcessingUnit.__init__(self) - + ProcessingUnit.__init__(self, **kwargs) + # self.isConfig = False - + self.pts2read_SelfSpectra = 0 - + self.pts2read_CrossSpectra = 0 - + self.pts2read_DCchannels = 0 - + self.datablock = None - + self.utc = None - + self.ext = ".pdata" - + self.optchar = "P" - + self.basicHeaderObj = BasicHeader(LOCALTIME) - + self.systemHeaderObj = SystemHeader() - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.processingHeaderObj = ProcessingHeader() - + self.online = 0 - + self.fp = None - + self.idFile = None - + self.dtype = None - + self.fileSizeByHeader = None - + self.filenameList = [] - + self.filename = None - + self.fileSize = None - + self.firstHeaderSize = 0 - + self.basicHeaderSize = 24 - + self.pathList = [] self.lastUTTime = 0 - + self.maxTimeStep = 30 - + self.flagNoMoreFiles = 0 - + self.set = 0 - + self.path = None self.delay = 60 #seconds - + self.nTries = 3 #quantity tries - + self.nFiles = 3 #number of files for searching - + self.nReadBlocks = 0 - + self.flagIsNewFile = 1 - + self.__isFirstTimeOnline = 1 - + # self.ippSeconds = 0 - - self.flagDiscontinuousBlock = 0 - + + self.flagDiscontinuousBlock = 0 + self.flagIsNewBlock = 0 - + self.nTotalBlocks = 0 - + self.blocksize = 0 - + self.dataOut = self.createObjByDefault() - + self.profileIndex = 1 #Always def createObjByDefault(self): - + dataObj = Spectra() - + return dataObj - + def __hasNotDataInBuffer(self): return 1 @@ -186,7 +186,7 @@ class SpectraReader(JRODataReader, ProcessingUnit): def getBlockDimension(self): """ Obtiene la cantidad de puntos a leer por cada bloque de datos - + Affected: self.nRdChannels self.nRdPairs @@ -203,10 +203,10 @@ class SpectraReader(JRODataReader, ProcessingUnit): self.nRdChannels = 0 self.nRdPairs = 0 self.rdPairList = [] - + for i in range(0, self.processingHeaderObj.totalSpectra*2, 2): if self.processingHeaderObj.spectraComb[i] == self.processingHeaderObj.spectraComb[i+1]: - self.nRdChannels = self.nRdChannels + 1 #par de canales iguales + self.nRdChannels = self.nRdChannels + 1 #par de canales iguales else: self.nRdPairs = self.nRdPairs + 1 #par de canales diferentes self.rdPairList.append((self.processingHeaderObj.spectraComb[i], self.processingHeaderObj.spectraComb[i+1])) @@ -215,29 +215,29 @@ class SpectraReader(JRODataReader, ProcessingUnit): self.pts2read_SelfSpectra = int(self.nRdChannels * pts2read) self.blocksize = self.pts2read_SelfSpectra - + if self.processingHeaderObj.flag_cspc: self.pts2read_CrossSpectra = int(self.nRdPairs * pts2read) self.blocksize += self.pts2read_CrossSpectra - + if self.processingHeaderObj.flag_dc: self.pts2read_DCchannels = int(self.systemHeaderObj.nChannels * self.processingHeaderObj.nHeights) self.blocksize += self.pts2read_DCchannels - + # self.blocksize = self.pts2read_SelfSpectra + self.pts2read_CrossSpectra + self.pts2read_DCchannels - + def readBlock(self): """ Lee el bloque de datos desde la posicion actual del puntero del archivo (self.fp) y actualiza todos los parametros relacionados al bloque de datos (metadata + data). La data leida es almacenada en el buffer y el contador del buffer es seteado a 0 - + Return: None - + Variables afectadas: - + self.flagIsNewFile self.flagIsNewBlock self.nTotalBlocks @@ -245,7 +245,7 @@ class SpectraReader(JRODataReader, ProcessingUnit): self.data_cspc self.data_dc - Exceptions: + Exceptions: Si un bloque leido no es un bloque valido """ blockOk_flag = False @@ -253,35 +253,35 @@ class SpectraReader(JRODataReader, ProcessingUnit): spc = numpy.fromfile( self.fp, self.dtype[0], self.pts2read_SelfSpectra ) spc = spc.reshape( (self.nRdChannels, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D - + if self.processingHeaderObj.flag_cspc: cspc = numpy.fromfile( self.fp, self.dtype, self.pts2read_CrossSpectra ) cspc = cspc.reshape( (self.nRdPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) ) #transforma a un arreglo 3D - + if self.processingHeaderObj.flag_dc: dc = numpy.fromfile( self.fp, self.dtype, self.pts2read_DCchannels ) #int(self.processingHeaderObj.nHeights*self.systemHeaderObj.nChannels) ) dc = dc.reshape( (self.systemHeaderObj.nChannels, self.processingHeaderObj.nHeights) ) #transforma a un arreglo 2D - - - if not(self.processingHeaderObj.shif_fft): + + + if self.processingHeaderObj.shif_fft: #desplaza a la derecha en el eje 2 determinadas posiciones shift = int(self.processingHeaderObj.profilesPerBlock/2) spc = numpy.roll( spc, shift , axis=2 ) - + if self.processingHeaderObj.flag_cspc: #desplaza a la derecha en el eje 2 determinadas posiciones cspc = numpy.roll( cspc, shift, axis=2 ) - + #Dimensions : nChannels, nProfiles, nSamples spc = numpy.transpose( spc, (0,2,1) ) self.data_spc = spc - - if self.processingHeaderObj.flag_cspc: + + if self.processingHeaderObj.flag_cspc: cspc = numpy.transpose( cspc, (0,2,1) ) self.data_cspc = cspc['real'] + cspc['imag']*1j else: self.data_cspc = None - + if self.processingHeaderObj.flag_dc: self.data_dc = dc['real'] + dc['imag']*1j else: @@ -294,60 +294,60 @@ class SpectraReader(JRODataReader, ProcessingUnit): self.nReadBlocks += 1 return 1 - + def getFirstHeader(self): - + self.getBasicHeader() - + self.dataOut.systemHeaderObj = self.systemHeaderObj.copy() - + self.dataOut.radarControllerHeaderObj = self.radarControllerHeaderObj.copy() - + # self.dataOut.ippSeconds = self.ippSeconds - + # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt * self.processingHeaderObj.nIncohInt * self.processingHeaderObj.profilesPerBlock self.dataOut.dtype = self.dtype - + # self.dataOut.nPairs = self.nPairs - + self.dataOut.pairsList = self.rdPairList - + self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock - + self.dataOut.nFFTPoints = self.processingHeaderObj.profilesPerBlock - + self.dataOut.nCohInt = self.processingHeaderObj.nCohInt - + self.dataOut.nIncohInt = self.processingHeaderObj.nIncohInt - + xf = self.processingHeaderObj.firstHeight + self.processingHeaderObj.nHeights*self.processingHeaderObj.deltaHeight - self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight) - + self.dataOut.heightList = numpy.arange(self.processingHeaderObj.firstHeight, xf, self.processingHeaderObj.deltaHeight) + self.dataOut.channelList = range(self.systemHeaderObj.nChannels) - + self.dataOut.flagShiftFFT = True #Data is always shifted - + self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode #asumo q la data no esta decodificada - - self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data esta sin flip - + + self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data esta sin flip + def getData(self): """ First method to execute before "RUN" is called. - + Copia el buffer de lectura a la clase "Spectra", con todos los parametros asociados a este (metadata). cuando no hay datos en el buffer de lectura es necesario hacer una nueva lectura de los bloques de datos usando "readNextBlock" - + Return: 0 : Si no hay mas archivos disponibles 1 : Si hizo una buena copia del buffer - + Affected: self.dataOut - + self.flagDiscontinuousBlock self.flagIsNewBlock """ @@ -356,68 +356,68 @@ class SpectraReader(JRODataReader, ProcessingUnit): self.dataOut.flagNoData = True print 'Process finished' return 0 - + self.flagDiscontinuousBlock = 0 self.flagIsNewBlock = 0 - - if self.__hasNotDataInBuffer(): + + if self.__hasNotDataInBuffer(): if not( self.readNextBlock() ): self.dataOut.flagNoData = True return 0 - + #data es un numpy array de 3 dmensiones (perfiles, alturas y canales) if self.data_spc is None: self.dataOut.flagNoData = True return 0 - + self.getBasicHeader() - + self.getFirstHeader() self.dataOut.data_spc = self.data_spc - + self.dataOut.data_cspc = self.data_cspc - + self.dataOut.data_dc = self.data_dc - + self.dataOut.flagNoData = False - + self.dataOut.realtime = self.online - + return self.dataOut.data_spc class SpectraWriter(JRODataWriter, Operation): - - """ + + """ Esta clase permite escribir datos de espectros a archivos procesados (.pdata). La escritura - de los datos siempre se realiza por bloques. + de los datos siempre se realiza por bloques. """ - + ext = ".pdata" - + optchar = "P" - + shape_spc_Buffer = None - + shape_cspc_Buffer = None - + shape_dc_Buffer = None - + data_spc = None - + data_cspc = None - + data_dc = None - + # dataOut = None - - def __init__(self): - """ + + def __init__(self, **kwargs): + """ Inicializador de la clase SpectraWriter para la escritura de datos de espectros. - - Affected: + + Affected: self.dataOut self.basicHeaderObj self.systemHeaderObj @@ -426,50 +426,50 @@ class SpectraWriter(JRODataWriter, Operation): Return: None """ - - Operation.__init__(self) - + + Operation.__init__(self, **kwargs) + self.isConfig = False - + self.nTotalBlocks = 0 - + self.data_spc = None - + self.data_cspc = None - + self.data_dc = None self.fp = None self.flagIsNewFile = 1 - - self.nTotalBlocks = 0 - + + self.nTotalBlocks = 0 + self.flagIsNewBlock = 0 self.setFile = None - + self.dtype = None - + self.path = None - + self.noMoreFiles = 0 - + self.filename = None - + self.basicHeaderObj = BasicHeader(LOCALTIME) - + self.systemHeaderObj = SystemHeader() - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.processingHeaderObj = ProcessingHeader() - + def hasAllDataInBuffer(self): return 1 - + def setBlockDimension(self): """ Obtiene las formas dimensionales del los subbloques de datos que componen un bloque @@ -488,15 +488,15 @@ class SpectraWriter(JRODataWriter, Operation): self.shape_cspc_Buffer = (self.dataOut.nPairs, self.processingHeaderObj.nHeights, self.processingHeaderObj.profilesPerBlock) - + self.shape_dc_Buffer = (self.dataOut.nChannels, self.processingHeaderObj.nHeights) - + def writeBlock(self): """ Escribe el buffer en el file designado - + Affected: self.data_spc self.data_cspc @@ -504,13 +504,13 @@ class SpectraWriter(JRODataWriter, Operation): self.flagIsNewFile self.flagIsNewBlock self.nTotalBlocks - self.nWriteBlocks - + self.nWriteBlocks + Return: None """ - + spc = numpy.transpose( self.data_spc, (0,2,1) ) - if not( self.processingHeaderObj.shif_fft ): + if self.processingHeaderObj.shif_fft: spc = numpy.roll( spc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones data = spc.reshape((-1)) data = data.astype(self.dtype[0]) @@ -519,13 +519,13 @@ class SpectraWriter(JRODataWriter, Operation): if self.data_cspc is not None: data = numpy.zeros( self.shape_cspc_Buffer, self.dtype ) cspc = numpy.transpose( self.data_cspc, (0,2,1) ) - if not( self.processingHeaderObj.shif_fft ): + if self.processingHeaderObj.shif_fft: cspc = numpy.roll( cspc, self.processingHeaderObj.profilesPerBlock/2, axis=2 ) #desplaza a la derecha en el eje 2 determinadas posiciones data['real'] = cspc.real data['imag'] = cspc.imag data = data.reshape((-1)) data.tofile(self.fp) - + if self.data_dc is not None: data = numpy.zeros( self.shape_dc_Buffer, self.dtype ) dc = self.data_dc @@ -535,40 +535,40 @@ class SpectraWriter(JRODataWriter, Operation): data.tofile(self.fp) # self.data_spc.fill(0) -# +# # if self.data_dc is not None: # self.data_dc.fill(0) -# +# # if self.data_cspc is not None: # self.data_cspc.fill(0) - + self.flagIsNewFile = 0 self.flagIsNewBlock = 1 self.nTotalBlocks += 1 self.nWriteBlocks += 1 self.blockIndex += 1 - + # print "[Writing] Block = %d04" %self.blockIndex - + def putData(self): """ - Setea un bloque de datos y luego los escribe en un file - + Setea un bloque de datos y luego los escribe en un file + Affected: self.data_spc self.data_cspc self.data_dc - Return: - 0 : Si no hay data o no hay mas files que puedan escribirse + Return: + 0 : Si no hay data o no hay mas files que puedan escribirse 1 : Si se escribio la data de un bloque en un file """ - + if self.dataOut.flagNoData: return 0 - + self.flagIsNewBlock = 0 - + if self.dataOut.flagDiscontinuousBlock: self.data_spc.fill(0) if self.dataOut.data_cspc is not None: @@ -576,104 +576,104 @@ class SpectraWriter(JRODataWriter, Operation): if self.dataOut.data_dc is not None: self.data_dc.fill(0) self.setNextFile() - + if self.flagIsNewFile == 0: self.setBasicHeader() - + self.data_spc = self.dataOut.data_spc.copy() - + if self.dataOut.data_cspc is not None: self.data_cspc = self.dataOut.data_cspc.copy() - + if self.dataOut.data_dc is not None: self.data_dc = self.dataOut.data_dc.copy() - + # #self.processingHeaderObj.dataBlocksPerFile) if self.hasAllDataInBuffer(): # self.setFirstHeader() self.writeNextBlock() - + return 1 - + def __getBlockSize(self): ''' Este metodos determina el cantidad de bytes para un bloque de datos de tipo Spectra ''' - + dtype_width = self.getDtypeWidth() - + pts2write = self.dataOut.nHeights * self.dataOut.nFFTPoints - + pts2write_SelfSpectra = int(self.dataOut.nChannels * pts2write) blocksize = (pts2write_SelfSpectra*dtype_width) - + if self.dataOut.data_cspc is not None: pts2write_CrossSpectra = int(self.dataOut.nPairs * pts2write) blocksize += (pts2write_CrossSpectra*dtype_width*2) - + if self.dataOut.data_dc is not None: pts2write_DCchannels = int(self.dataOut.nChannels * self.dataOut.nHeights) blocksize += (pts2write_DCchannels*dtype_width*2) - + # blocksize = blocksize #* datatypeValue * 2 #CORREGIR ESTO return blocksize - + def setFirstHeader(self): - + """ Obtiene una copia del First Header - + Affected: self.systemHeaderObj self.radarControllerHeaderObj self.dtype - Return: + Return: None """ - + self.systemHeaderObj = self.dataOut.systemHeaderObj.copy() self.systemHeaderObj.nChannels = self.dataOut.nChannels self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy() - + self.processingHeaderObj.dtype = 1 # Spectra self.processingHeaderObj.blockSize = self.__getBlockSize() self.processingHeaderObj.profilesPerBlock = self.dataOut.nFFTPoints self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows self.processingHeaderObj.nCohInt = self.dataOut.nCohInt# Se requiere para determinar el valor de timeInterval - self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt + self.processingHeaderObj.nIncohInt = self.dataOut.nIncohInt self.processingHeaderObj.totalSpectra = self.dataOut.nPairs + self.dataOut.nChannels self.processingHeaderObj.shif_fft = self.dataOut.flagShiftFFT - + if self.processingHeaderObj.totalSpectra > 0: channelList = [] for channel in range(self.dataOut.nChannels): channelList.append(channel) channelList.append(channel) - + pairsList = [] if self.dataOut.nPairs > 0: for pair in self.dataOut.pairsList: pairsList.append(pair[0]) pairsList.append(pair[1]) - + spectraComb = channelList + pairsList spectraComb = numpy.array(spectraComb, dtype="u1") self.processingHeaderObj.spectraComb = spectraComb - + if self.dataOut.code is not None: self.processingHeaderObj.code = self.dataOut.code self.processingHeaderObj.nCode = self.dataOut.nCode self.processingHeaderObj.nBaud = self.dataOut.nBaud - + if self.processingHeaderObj.nWindows != 0: self.processingHeaderObj.firstHeight = self.dataOut.heightList[0] self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0] self.processingHeaderObj.nHeights = self.dataOut.nHeights self.processingHeaderObj.samplesWin = self.dataOut.nHeights - + self.processingHeaderObj.processFlags = self.getProcessFlags() - + self.setBasicHeader() diff --git a/schainpy/model/io/jroIO_usrp.py b/schainpy/model/io/jroIO_usrp.py index 5aae517..71bf270 100644 --- a/schainpy/model/io/jroIO_usrp.py +++ b/schainpy/model/io/jroIO_usrp.py @@ -20,44 +20,44 @@ try: import digital_rf_hdf5 except: print 'You should install "digital_rf_hdf5" module if you want to read USRP data' - + class USRPReader(ProcessingUnit): ''' classdocs ''' - def __init__(self): + def __init__(self, **kwargs): ''' Constructor ''' - - ProcessingUnit.__init__(self) - + + ProcessingUnit.__init__(self, **kwargs) + self.dataOut = Voltage() self.__printInfo = True self.__flagDiscontinuousBlock = False self.__bufferIndex = 9999999 - + self.__ippKm = None self.__codeType = 0 self.__nCode = None self.__nBaud = None self.__code = None - + def __getCurrentSecond(self): - + return self.__thisUnixSample/self.__sample_rate - + thisSecond = property(__getCurrentSecond, "I'm the 'thisSecond' property.") - + def __setFileHeader(self): ''' In this method will be initialized every parameter of dataOut object (header, no data) ''' ippSeconds = 1.0*self.__nSamples/self.__sample_rate - + nProfiles = 1.0/ippSeconds #Number of profiles in one second - + self.dataOut.radarControllerHeaderObj = RadarControllerHeader(ippKm=self.__ippKm, txA=0, txB=0, @@ -68,125 +68,125 @@ class USRPReader(ProcessingUnit): codeType=self.__codeType, nCode=self.__nCode, nBaud=self.__nBaud, code = self.__code) - + self.dataOut.systemHeaderObj = SystemHeader(nSamples=self.__nSamples, nProfiles=nProfiles, nChannels=len(self.__channelList), adcResolution=14) - + self.dataOut.type = "Voltage" - + self.dataOut.data = None - + self.dataOut.dtype = numpy.dtype([('real',' endDate: break - + dateList.append(thisDate) thisDatetime += datetime.timedelta(1) - + return dateList - + def setup(self, path = None, - startDate = None, - endDate = None, - startTime = datetime.time(0,0,0), - endTime = datetime.time(23,59,59), - channelList = None, - nSamples = None, + startDate = None, + endDate = None, + startTime = datetime.time(0,0,0), + endTime = datetime.time(23,59,59), + channelList = None, + nSamples = None, ippKm = 60, online = False, delay = 60, @@ -194,7 +194,7 @@ class USRPReader(ProcessingUnit): **kwargs): ''' In this method we should set all initial parameters. - + Inputs: path startDate @@ -207,120 +207,120 @@ class USRPReader(ProcessingUnit): online delay ''' - + if not os.path.isdir(path): - raise ValueError, "[Reading] Directory %s does not exist" %path - + raise ValueError, "[Reading] Directory %s does not exist" %path + try: self.digitalReadObj = digital_rf_hdf5.read_hdf5(path, load_all_metadata=True) except: self.digitalReadObj = digital_rf_hdf5.read_hdf5(path) - + channelNameList = self.digitalReadObj.get_channels() - + if not channelNameList: raise ValueError, "[Reading] Directory %s does not have any files" %path - + if not channelList: channelList = range(len(channelNameList)) - + ########## Reading metadata ###################### - + metadata_dict = self.digitalReadObj.get_rf_file_metadata(channelNameList[channelList[0]]) - + self.__sample_rate = metadata_dict['sample_rate'][0] # self.__samples_per_file = metadata_dict['samples_per_file'][0] self.__deltaHeigth = 1e6*0.15/self.__sample_rate - + this_metadata_file = self.digitalReadObj.get_metadata(channelNameList[channelList[0]]) - + self.__frequency = None try: self.__frequency = this_metadata_file['center_frequencies'].value except: self.__frequency = this_metadata_file['fc'].value - + if not self.__frequency: raise ValueError, "Center Frequency is not defined in metadata file" - + try: self.__timezone = this_metadata_file['timezone'].value except: self.__timezone = 0 - + self.__firstHeigth = 0 - + try: codeType = this_metadata_file['codeType'].value except: codeType = 0 - + nCode = 1 nBaud = 1 code = numpy.ones((nCode, nBaud), dtype=numpy.int) - + if codeType: nCode = this_metadata_file['nCode'].value nBaud = this_metadata_file['nBaud'].value code = this_metadata_file['code'].value - + if not ippKm: try: #seconds to km ippKm = 1e6*0.15*this_metadata_file['ipp'].value except: ippKm = None - + #################################################### startUTCSecond = None endUTCSecond = None - + if startDate: startDatetime = datetime.datetime.combine(startDate, startTime) startUTCSecond = (startDatetime-datetime.datetime(1970,1,1)).total_seconds() + self.__timezone - + if endDate: endDatetime = datetime.datetime.combine(endDate, endTime) endUTCSecond = (endDatetime-datetime.datetime(1970,1,1)).total_seconds() + self.__timezone - + start_index, end_index = self.digitalReadObj.get_bounds(channelNameList[channelList[0]]) - + if not startUTCSecond: startUTCSecond = start_index/self.__sample_rate - + if start_index > startUTCSecond*self.__sample_rate: startUTCSecond = start_index/self.__sample_rate - + if not endUTCSecond: endUTCSecond = end_index/self.__sample_rate - + if end_index < endUTCSecond*self.__sample_rate: endUTCSecond = end_index/self.__sample_rate - + if not nSamples: if not ippKm: raise ValueError, "[Reading] nSamples or ippKm should be defined" - + nSamples = int(ippKm / (1e6*0.15/self.__sample_rate)) - + channelBoundList = [] channelNameListFiltered = [] - + for thisIndexChannel in channelList: thisChannelName = channelNameList[thisIndexChannel] start_index, end_index = self.digitalReadObj.get_bounds(thisChannelName) channelBoundList.append((start_index, end_index)) channelNameListFiltered.append(thisChannelName) - + self.profileIndex = 0 - + self.__delay = delay self.__ippKm = ippKm self.__codeType = codeType self.__nCode = nCode self.__nBaud = nBaud self.__code = code - + self.__datapath = path self.__online = online self.__channelList = channelList @@ -329,37 +329,37 @@ class USRPReader(ProcessingUnit): self.__nSamples = nSamples self.__samples_to_read = int(buffer_size*nSamples) self.__nChannels = len(self.__channelList) - + self.__startUTCSecond = startUTCSecond self.__endUTCSecond = endUTCSecond - + self.__timeInterval = 1.0 * self.__samples_to_read/self.__sample_rate #Time interval - + if online: # self.__thisUnixSample = int(endUTCSecond*self.__sample_rate - 4*self.__samples_to_read) startUTCSecond = numpy.floor(endUTCSecond) - + self.__thisUnixSample = int(startUTCSecond*self.__sample_rate) - self.__samples_to_read - + self.__data_buffer = numpy.zeros((self.__nChannels, self.__samples_to_read), dtype = numpy.complex) - + self.__setFileHeader() self.isConfig = True - + print "[Reading] USRP Data was found from %s to %s " %( datetime.datetime.utcfromtimestamp(self.__startUTCSecond - self.__timezone), datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone) ) - + print "[Reading] Starting process from %s to %s" %(datetime.datetime.utcfromtimestamp(startUTCSecond - self.__timezone), datetime.datetime.utcfromtimestamp(endUTCSecond - self.__timezone) ) - + def __reload(self): - + if not self.__online: return - + # print # print "%s not in range [%s, %s]" %( # datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), @@ -367,17 +367,17 @@ class USRPReader(ProcessingUnit): # datetime.datetime.utcfromtimestamp(self.__endUTCSecond - self.__timezone) # ) print "[Reading] reloading metadata ..." - + try: self.digitalReadObj.reload(complete_update=True) except: self.digitalReadObj.reload() - + start_index, end_index = self.digitalReadObj.get_bounds(self.__channelNameList[self.__channelList[0]]) - + if start_index > self.__startUTCSecond*self.__sample_rate: self.__startUTCSecond = 1.0*start_index/self.__sample_rate - + if end_index > self.__endUTCSecond*self.__sample_rate: self.__endUTCSecond = 1.0*end_index/self.__sample_rate print @@ -387,215 +387,214 @@ class USRPReader(ProcessingUnit): ) return True - + return False - + def __readNextBlock(self, seconds=30, volt_scale = 218776): ''' ''' - + #Set the next data self.__flagDiscontinuousBlock = False self.__thisUnixSample += self.__samples_to_read - + if self.__thisUnixSample + 2*self.__samples_to_read > self.__endUTCSecond*self.__sample_rate: print "[Reading] There are no more data into selected time-range" - + self.__reload() - + if self.__thisUnixSample + 2*self.__samples_to_read > self.__endUTCSecond*self.__sample_rate: self.__thisUnixSample -= self.__samples_to_read return False - + indexChannel = 0 - + dataOk = False - + for thisChannelName in self.__channelNameList: - + try: result = self.digitalReadObj.read_vector_c81d(self.__thisUnixSample, self.__samples_to_read, thisChannelName) - + except IOError, e: #read next profile self.__flagDiscontinuousBlock = True print "[Reading] %s" %datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), e break - + if result.shape[0] != self.__samples_to_read: self.__flagDiscontinuousBlock = True print "[Reading] %s: Too few samples were found, just %d/%d samples" %(datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), result.shape[0], self.__samples_to_read) break - + self.__data_buffer[indexChannel,:] = result*volt_scale - + indexChannel += 1 - + dataOk = True - + self.__utctime = self.__thisUnixSample/self.__sample_rate - + if not dataOk: return False - + print "[Reading] %s: %d samples <> %f sec" %(datetime.datetime.utcfromtimestamp(self.thisSecond - self.__timezone), self.__samples_to_read, self.__timeInterval) - + self.__bufferIndex = 0 - + return True - + def __isBufferEmpty(self): - + if self.__bufferIndex <= self.__samples_to_read - self.__nSamples: return False - + return True - + def getData(self, seconds=30, nTries=5): - + ''' This method gets the data from files and put the data into the dataOut object - + In addition, increase el the buffer counter in one. - + Return: data : retorna un perfil de voltages (alturas * canales) copiados desde el buffer. Si no hay mas archivos a leer retorna None. - + Affected: self.dataOut self.profileIndex self.flagDiscontinuousBlock self.flagIsNewBlock ''' - + err_counter = 0 self.dataOut.flagNoData = True - + if self.__isBufferEmpty(): - + self.__flagDiscontinuousBlock = False - + while True: if self.__readNextBlock(): break - + if self.__thisUnixSample > self.__endUTCSecond*self.__sample_rate: return False - + if self.__flagDiscontinuousBlock: print '[Reading] discontinuous block found ... continue with the next block' continue - + if not self.__online: return False - + err_counter += 1 if err_counter > nTries: return False - + print '[Reading] waiting %d seconds to read a new block' %seconds sleep(seconds) - + self.dataOut.data = self.__data_buffer[:,self.__bufferIndex:self.__bufferIndex+self.__nSamples] self.dataOut.utctime = (self.__thisUnixSample + self.__bufferIndex)/self.__sample_rate self.dataOut.flagNoData = False self.dataOut.flagDiscontinuousBlock = self.__flagDiscontinuousBlock self.dataOut.profileIndex = self.profileIndex - - self.__bufferIndex += self.__nSamples + + self.__bufferIndex += self.__nSamples self.profileIndex += 1 - + if self.profileIndex == self.dataOut.nProfiles: self.profileIndex = 0 - + return True - + def printInfo(self): ''' ''' if self.__printInfo == False: return - + # self.systemHeaderObj.printInfo() # self.radarControllerHeaderObj.printInfo() - + self.__printInfo = False - + def printNumberOfBlock(self): ''' ''' - + print self.profileIndex - + def run(self, **kwargs): ''' This method will be called many times so here you should put all your code ''' - + if not self.isConfig: self.setup(**kwargs) - + self.getData(seconds=self.__delay) - + return - + class USRPWriter(Operation): ''' classdocs ''' - - def __init__(self): + + def __init__(self, **kwargs): ''' Constructor ''' + Operation.__init__(self, **kwargs) self.dataOut = None - + def setup(self, dataIn, path, blocksPerFile, set=0, ext=None): ''' In this method we should set all initial parameters. - + Input: dataIn : Input data will also be outputa data - + ''' self.dataOut = dataIn - - - - - + + + + + self.isConfig = True - + return - + def run(self, dataIn, **kwargs): ''' This method will be called many times so here you should put all your code - + Inputs: - + dataIn : object with the data - + ''' - + if not self.isConfig: self.setup(dataIn, **kwargs) if __name__ == '__main__': - + readObj = USRPReader() - + while True: readObj.run(path='/Volumes/DATA/haystack/passive_radar/') # readObj.printInfo() readObj.printNumberOfBlock() - - \ No newline at end of file diff --git a/schainpy/model/io/jroIO_voltage.py b/schainpy/model/io/jroIO_voltage.py index 74e3a9d..95a897f 100644 --- a/schainpy/model/io/jroIO_voltage.py +++ b/schainpy/model/io/jroIO_voltage.py @@ -10,58 +10,62 @@ from jroIO_base import LOCALTIME, JRODataReader, JRODataWriter from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jroheaderIO import PROCFLAG, BasicHeader, SystemHeader, RadarControllerHeader, ProcessingHeader from schainpy.model.data.jrodata import Voltage +import zmq +import tempfile +from StringIO import StringIO # from _sha import blocksize + class VoltageReader(JRODataReader, ProcessingUnit): """ Esta clase permite leer datos de voltage desde archivos en formato rawdata (.r). La lectura - de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones: + de los datos siempre se realiza por bloques. Los datos leidos (array de 3 dimensiones: perfiles*alturas*canales) son almacenados en la variable "buffer". - - perfiles * alturas * canales - Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader, + perfiles * alturas * canales + + Esta clase contiene instancias (objetos) de las clases BasicHeader, SystemHeader, RadarControllerHeader y Voltage. Los tres primeros se usan para almacenar informacion de la cabecera de datos (metadata), y el cuarto (Voltage) para obtener y almacenar un perfil de datos desde el "buffer" cada vez que se ejecute el metodo "getData". - + Example: - + dpath = "/home/myuser/data" - + startTime = datetime.datetime(2010,1,20,0,0,0,0,0,0) - + endTime = datetime.datetime(2010,1,21,23,59,59,0,0,0) - + readerObj = VoltageReader() - + readerObj.setup(dpath, startTime, endTime) - + while(True): - - #to get one profile + + #to get one profile profile = readerObj.getData() - + #print the profile print profile - + #If you want to see all datablock print readerObj.datablock - + if readerObj.flagNoMoreFiles: break - + """ ext = ".r" - + optchar = "D" dataOut = None - - def __init__(self): + + def __init__(self, **kwargs): """ Inicializador de la clase VoltageReader para la lectura de datos de voltage. - + Input: dataOut : Objeto de la clase Voltage. Este objeto sera utilizado para almacenar un perfil de datos cada vez que se haga un requerimiento @@ -69,421 +73,541 @@ class VoltageReader(JRODataReader, ProcessingUnit): si el buffer esta vacio se hara un nuevo proceso de lectura de un bloque de datos. Si este parametro no es pasado se creara uno internamente. - + Variables afectadas: self.dataOut - + Return: None """ - - ProcessingUnit.__init__(self) - + + ProcessingUnit.__init__(self, **kwargs) + self.isConfig = False - + self.datablock = None - + self.utc = 0 - + self.ext = ".r" - + self.optchar = "D" self.basicHeaderObj = BasicHeader(LOCALTIME) - + self.systemHeaderObj = SystemHeader() - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.processingHeaderObj = ProcessingHeader() - + self.online = 0 - + self.fp = None - + self.idFile = None - + self.dtype = None - + self.fileSizeByHeader = None - + self.filenameList = [] - + self.filename = None - + self.fileSize = None - + self.firstHeaderSize = 0 - + self.basicHeaderSize = 24 - + self.pathList = [] - + self.filenameList = [] - + self.lastUTTime = 0 - + self.maxTimeStep = 30 - + self.flagNoMoreFiles = 0 - + self.set = 0 - + self.path = None - - self.profileIndex = 2**32-1 - - self.delay = 3 #seconds - - self.nTries = 3 #quantity tries - - self.nFiles = 3 #number of files for searching - + + self.profileIndex = 2**32 - 1 + + self.delay = 3 # seconds + + self.nTries = 3 # quantity tries + + self.nFiles = 3 # number of files for searching + self.nReadBlocks = 0 - + self.flagIsNewFile = 1 - + self.__isFirstTimeOnline = 1 - + # self.ippSeconds = 0 - - self.flagDiscontinuousBlock = 0 - + + self.flagDiscontinuousBlock = 0 + self.flagIsNewBlock = 0 - + self.nTotalBlocks = 0 - + self.blocksize = 0 - + self.dataOut = self.createObjByDefault() - + self.nTxs = 1 - + self.txIndex = 0 - + def createObjByDefault(self): - + dataObj = Voltage() - + return dataObj - + def __hasNotDataInBuffer(self): - - if self.profileIndex >= self.processingHeaderObj.profilesPerBlock*self.nTxs: + + if self.profileIndex >= self.processingHeaderObj.profilesPerBlock * self.nTxs: return 1 - - return 0 + return 0 def getBlockDimension(self): """ - Obtiene la cantidad de puntos a leer por cada bloque de datos - - Affected: - self.blocksize + Obtiene la cantidad de puntos a leer por cada bloque de datos - Return: - None + Affected: + self.blocksize + + Return: + None """ - pts2read = self.processingHeaderObj.profilesPerBlock * self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels + pts2read = self.processingHeaderObj.profilesPerBlock * \ + self.processingHeaderObj.nHeights * self.systemHeaderObj.nChannels self.blocksize = pts2read - def readBlock(self): """ - readBlock lee el bloque de datos desde la posicion actual del puntero del archivo - (self.fp) y actualiza todos los parametros relacionados al bloque de datos - (metadata + data). La data leida es almacenada en el buffer y el contador del buffer - es seteado a 0 - - Inputs: - None - - Return: - None - - Affected: - self.profileIndex - self.datablock - self.flagIsNewFile - self.flagIsNewBlock - self.nTotalBlocks - - Exceptions: - Si un bloque leido no es un bloque valido + readBlock lee el bloque de datos desde la posicion actual del puntero del archivo + (self.fp) y actualiza todos los parametros relacionados al bloque de datos + (metadata + data). La data leida es almacenada en el buffer y el contador del buffer + es seteado a 0 + + Inputs: + None + + Return: + None + + Affected: + self.profileIndex + self.datablock + self.flagIsNewFile + self.flagIsNewBlock + self.nTotalBlocks + + Exceptions: + Si un bloque leido no es un bloque valido """ + + # if self.server is not None: + # self.zBlock = self.receiver.recv() + # self.zHeader = self.zBlock[:24] + # self.zDataBlock = self.zBlock[24:] + # junk = numpy.fromstring(self.zDataBlock, numpy.dtype([('real',' 1: - self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds/self.nTxs - - #Time interval and code are propierties of dataOut. Its value depends of radarControllerHeaderObj. - -# self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt -# -# if self.radarControllerHeaderObj.code is not None: -# -# self.dataOut.nCode = self.radarControllerHeaderObj.nCode -# -# self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud -# -# self.dataOut.code = self.radarControllerHeaderObj.code - + self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs + # Time interval and code are propierties of dataOut. Its value depends of radarControllerHeaderObj. + + # self.dataOut.timeInterval = self.radarControllerHeaderObj.ippSeconds * self.processingHeaderObj.nCohInt + # + # if self.radarControllerHeaderObj.code is not None: + # + # self.dataOut.nCode = self.radarControllerHeaderObj.nCode + # + # self.dataOut.nBaud = self.radarControllerHeaderObj.nBaud + # + # self.dataOut.code = self.radarControllerHeaderObj.code + self.dataOut.dtype = self.dtype - + self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock - - self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights) *self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight - + + self.dataOut.heightList = numpy.arange( + self.processingHeaderObj.nHeights) * self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight + self.dataOut.channelList = range(self.systemHeaderObj.nChannels) - + self.dataOut.nCohInt = self.processingHeaderObj.nCohInt - - self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode #asumo q la data no esta decodificada - self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip #asumo q la data no esta sin flip - + # asumo q la data no esta decodificada + self.dataOut.flagDecodeData = self.processingHeaderObj.flag_decode + + # asumo q la data no esta sin flip + self.dataOut.flagDeflipData = self.processingHeaderObj.flag_deflip + self.dataOut.flagShiftFFT = self.processingHeaderObj.shif_fft - + def reshapeData(self): - + if self.nTxs < 0: return - + if self.nTxs == 1: return - - if self.nTxs < 1 and self.processingHeaderObj.profilesPerBlock % (1./self.nTxs) != 0: - raise ValueError, "1./nTxs (=%f), should be a multiple of nProfiles (=%d)" %(1./self.nTxs, self.processingHeaderObj.profilesPerBlock) - + + if self.nTxs < 1 and self.processingHeaderObj.profilesPerBlock % (1. / self.nTxs) != 0: + raise ValueError, "1./nTxs (=%f), should be a multiple of nProfiles (=%d)" % ( + 1. / self.nTxs, self.processingHeaderObj.profilesPerBlock) + if self.nTxs > 1 and self.processingHeaderObj.nHeights % self.nTxs != 0: - raise ValueError, "nTxs (=%d), should be a multiple of nHeights (=%d)" %(self.nTxs, self.processingHeaderObj.nHeights) - - self.datablock = self.datablock.reshape((self.systemHeaderObj.nChannels, self.processingHeaderObj.profilesPerBlock*self.nTxs, self.processingHeaderObj.nHeights/self.nTxs)) - - self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock*self.nTxs - self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights/self.nTxs) *self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight - self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds/self.nTxs - + raise ValueError, "nTxs (=%d), should be a multiple of nHeights (=%d)" % ( + self.nTxs, self.processingHeaderObj.nHeights) + + self.datablock = self.datablock.reshape( + (self.systemHeaderObj.nChannels, self.processingHeaderObj.profilesPerBlock * self.nTxs, self.processingHeaderObj.nHeights / self.nTxs)) + + self.dataOut.nProfiles = self.processingHeaderObj.profilesPerBlock * self.nTxs + self.dataOut.heightList = numpy.arange(self.processingHeaderObj.nHeights / self.nTxs) * \ + self.processingHeaderObj.deltaHeight + self.processingHeaderObj.firstHeight + self.dataOut.radarControllerHeaderObj.ippSeconds = self.radarControllerHeaderObj.ippSeconds / self.nTxs + return - + + def readFirstHeaderFromServer(self): + + self.getFirstHeader() + + self.firstHeaderSize = self.basicHeaderObj.size + + datatype = int(numpy.log2((self.processingHeaderObj.processFlags & + PROCFLAG.DATATYPE_MASK)) - numpy.log2(PROCFLAG.DATATYPE_CHAR)) + if datatype == 0: + datatype_str = numpy.dtype([('real', ' 1 then one profile is divided by nTxs and number of total - blocks is increased by nTxs (nProfiles *= nTxs) + Return profile by profile + + If nTxs > 1 then one profile is divided by nTxs and number of total + blocks is increased by nTxs (nProfiles *= nTxs) """ self.dataOut.flagDataAsBlock = False - self.dataOut.data = self.datablock[:,self.profileIndex,:] + self.dataOut.data = self.datablock[:, self.profileIndex, :] self.dataOut.profileIndex = self.profileIndex - + self.profileIndex += 1 - -# elif self.selBlocksize==None or self.selBlocksize==self.dataOut.nProfiles: -# """ -# Return all block -# """ -# self.dataOut.flagDataAsBlock = True -# self.dataOut.data = self.datablock -# self.dataOut.profileIndex = self.dataOut.nProfiles - 1 -# -# self.profileIndex = self.dataOut.nProfiles - + + # elif self.selBlocksize==None or self.selBlocksize==self.dataOut.nProfiles: + # """ + # Return all block + # """ + # self.dataOut.flagDataAsBlock = True + # self.dataOut.data = self.datablock + # self.dataOut.profileIndex = self.dataOut.nProfiles - 1 + # + # self.profileIndex = self.dataOut.nProfiles + else: """ - Return a block + Return a block """ - if self.selBlocksize == None: self.selBlocksize = self.dataOut.nProfiles + if self.selBlocksize == None: + self.selBlocksize = self.dataOut.nProfiles if self.selBlocktime != None: if self.dataOut.nCohInt is not None: nCohInt = self.dataOut.nCohInt else: - nCohInt = 1 - self.selBlocksize = int(self.dataOut.nProfiles*round(self.selBlocktime/(nCohInt*self.dataOut.ippSeconds*self.dataOut.nProfiles))) - - self.dataOut.data = self.datablock[:,self.profileIndex:self.profileIndex+self.selBlocksize,:] + nCohInt = 1 + self.selBlocksize = int(self.dataOut.nProfiles * round(self.selBlocktime / ( + nCohInt * self.dataOut.ippSeconds * self.dataOut.nProfiles))) + + self.dataOut.data = self.datablock[:, + self.profileIndex:self.profileIndex + self.selBlocksize, :] self.profileIndex += self.selBlocksize datasize = self.dataOut.data.shape[1] - - if datasize < self.selBlocksize: - buffer = numpy.zeros((self.dataOut.data.shape[0],self.selBlocksize,self.dataOut.data.shape[2]), dtype = 'complex') - buffer[:,:datasize,:] = self.dataOut.data - - while datasize < self.selBlocksize: #Not enough profiles to fill the block - if not( self.readNextBlock() ): - return 0 + + if datasize < self.selBlocksize: + buffer = numpy.zeros( + (self.dataOut.data.shape[0], self.selBlocksize, self.dataOut.data.shape[2]), dtype='complex') + buffer[:, :datasize, :] = self.dataOut.data + + while datasize < self.selBlocksize: # Not enough profiles to fill the block + if not(self.readNextBlock()): + return 0 self.getFirstHeader() self.reshapeData() if self.datablock is None: self.dataOut.flagNoData = True return 0 - #stack data + # stack data blockIndex = self.selBlocksize - datasize - datablock1 = self.datablock[:,:blockIndex,:] - - buffer[:,datasize:datasize+datablock1.shape[1],:] = datablock1 + datablock1 = self.datablock[:, :blockIndex, :] + + buffer[:, datasize:datasize + + datablock1.shape[1], :] = datablock1 datasize += datablock1.shape[1] - + self.dataOut.data = buffer self.profileIndex = blockIndex self.dataOut.flagDataAsBlock = True self.dataOut.nProfiles = self.dataOut.data.shape[1] - + self.dataOut.flagNoData = False - + self.getBasicHeader() - + self.dataOut.realtime = self.online - + return self.dataOut.data + class VoltageWriter(JRODataWriter, Operation): - """ + """ Esta clase permite escribir datos de voltajes a archivos procesados (.r). La escritura - de los datos siempre se realiza por bloques. + de los datos siempre se realiza por bloques. """ - + ext = ".r" - + optchar = "D" - + shapeBuffer = None - - def __init__(self): - """ + def __init__(self, **kwargs): + """ Inicializador de la clase VoltageWriter para la escritura de datos de espectros. - - Affected: + + Affected: self.dataOut Return: None """ - Operation.__init__(self) - + Operation.__init__(self, **kwargs) + self.nTotalBlocks = 0 self.profileIndex = 0 - + self.isConfig = False - + self.fp = None self.flagIsNewFile = 1 - - self.blockIndex = 0 - + + self.blockIndex = 0 + self.flagIsNewBlock = 0 self.setFile = None - + self.dtype = None - + self.path = None - + self.filename = None - + self.basicHeaderObj = BasicHeader(LOCALTIME) - + self.systemHeaderObj = SystemHeader() - + self.radarControllerHeaderObj = RadarControllerHeader() - + self.processingHeaderObj = ProcessingHeader() def hasAllDataInBuffer(self): @@ -491,7 +615,6 @@ class VoltageWriter(JRODataWriter, Operation): return 1 return 0 - def setBlockDimension(self): """ Obtiene las formas dimensionales del los subbloques de datos que componen un bloque @@ -506,132 +629,136 @@ class VoltageWriter(JRODataWriter, Operation): self.shapeBuffer = (self.processingHeaderObj.profilesPerBlock, self.processingHeaderObj.nHeights, self.systemHeaderObj.nChannels) - + self.datablock = numpy.zeros((self.systemHeaderObj.nChannels, - self.processingHeaderObj.profilesPerBlock, - self.processingHeaderObj.nHeights), + self.processingHeaderObj.profilesPerBlock, + self.processingHeaderObj.nHeights), dtype=numpy.dtype('complex64')) - + def writeBlock(self): """ Escribe el buffer en el file designado - + Affected: - self.profileIndex + self.profileIndex self.flagIsNewFile self.flagIsNewBlock self.nTotalBlocks - self.blockIndex - + self.blockIndex + Return: None """ - data = numpy.zeros( self.shapeBuffer, self.dtype ) - - junk = numpy.transpose(self.datablock, (1,2,0)) - + data = numpy.zeros(self.shapeBuffer, self.dtype) + + junk = numpy.transpose(self.datablock, (1, 2, 0)) + data['real'] = junk.real data['imag'] = junk.imag - - data = data.reshape( (-1) ) - - data.tofile( self.fp ) - + + data = data.reshape((-1)) + + data.tofile(self.fp) + self.datablock.fill(0) - - self.profileIndex = 0 + + self.profileIndex = 0 self.flagIsNewFile = 0 self.flagIsNewBlock = 1 - + self.blockIndex += 1 self.nTotalBlocks += 1 - + # print "[Writing] Block = %04d" %self.blockIndex - + def putData(self): """ - Setea un bloque de datos y luego los escribe en un file - + Setea un bloque de datos y luego los escribe en un file + Affected: self.flagIsNewBlock self.profileIndex - Return: - 0 : Si no hay data o no hay mas files que puedan escribirse + Return: + 0 : Si no hay data o no hay mas files que puedan escribirse 1 : Si se escribio la data de un bloque en un file """ if self.dataOut.flagNoData: return 0 - + self.flagIsNewBlock = 0 - + if self.dataOut.flagDiscontinuousBlock: self.datablock.fill(0) self.profileIndex = 0 self.setNextFile() - + if self.profileIndex == 0: self.setBasicHeader() - - self.datablock[:,self.profileIndex,:] = self.dataOut.data - + + self.datablock[:, self.profileIndex, :] = self.dataOut.data + self.profileIndex += 1 - + if self.hasAllDataInBuffer(): - #if self.flagIsNewFile: + # if self.flagIsNewFile: self.writeNextBlock() # self.setFirstHeader() - + return 1 - + def __getBlockSize(self): ''' Este metodos determina el cantidad de bytes para un bloque de datos de tipo Voltage ''' - + dtype_width = self.getDtypeWidth() - - blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * self.profilesPerBlock * dtype_width * 2) - + + blocksize = int(self.dataOut.nHeights * self.dataOut.nChannels * + self.profilesPerBlock * dtype_width * 2) + return blocksize - + def setFirstHeader(self): - """ Obtiene una copia del First Header - + Affected: self.systemHeaderObj self.radarControllerHeaderObj self.dtype - Return: + Return: None """ - + self.systemHeaderObj = self.dataOut.systemHeaderObj.copy() self.systemHeaderObj.nChannels = self.dataOut.nChannels self.radarControllerHeaderObj = self.dataOut.radarControllerHeaderObj.copy() - - self.processingHeaderObj.dtype = 0 # Voltage + + self.processingHeaderObj.dtype = 0 # Voltage self.processingHeaderObj.blockSize = self.__getBlockSize() self.processingHeaderObj.profilesPerBlock = self.profilesPerBlock self.processingHeaderObj.dataBlocksPerFile = self.blocksPerFile - self.processingHeaderObj.nWindows = 1 #podria ser 1 o self.dataOut.processingHeaderObj.nWindows + # podria ser 1 o self.dataOut.processingHeaderObj.nWindows + self.processingHeaderObj.nWindows = 1 self.processingHeaderObj.nCohInt = self.dataOut.nCohInt - self.processingHeaderObj.nIncohInt = 1 # Cuando la data de origen es de tipo Voltage - self.processingHeaderObj.totalSpectra = 0 # Cuando la data de origen es de tipo Voltage - + # Cuando la data de origen es de tipo Voltage + self.processingHeaderObj.nIncohInt = 1 + # Cuando la data de origen es de tipo Voltage + self.processingHeaderObj.totalSpectra = 0 + if self.dataOut.code is not None: self.processingHeaderObj.code = self.dataOut.code self.processingHeaderObj.nCode = self.dataOut.nCode self.processingHeaderObj.nBaud = self.dataOut.nBaud - + if self.processingHeaderObj.nWindows != 0: self.processingHeaderObj.firstHeight = self.dataOut.heightList[0] - self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0] + self.processingHeaderObj.deltaHeight = self.dataOut.heightList[1] - \ + self.dataOut.heightList[0] self.processingHeaderObj.nHeights = self.dataOut.nHeights self.processingHeaderObj.samplesWin = self.dataOut.nHeights - + self.processingHeaderObj.processFlags = self.getProcessFlags() - - self.setBasicHeader() \ No newline at end of file + + self.setBasicHeader() diff --git a/schainpy/model/io/julIO_param.py b/schainpy/model/io/julIO_param.py new file mode 100644 index 0000000..208c0ba --- /dev/null +++ b/schainpy/model/io/julIO_param.py @@ -0,0 +1,343 @@ +''' +Created on Set 10, 2017 + +@author: Juan C. Espinoza +''' + + +import os +import sys +import time +import glob +import datetime + +import numpy + +from schainpy.model.proc.jroproc_base import ProcessingUnit +from schainpy.model.data.jrodata import Parameters +from schainpy.model.io.jroIO_base import JRODataReader, isNumber +from schainpy.utils import log + +FILE_HEADER_STRUCTURE = numpy.dtype([ + ('year', 'f'), + ('doy', 'f'), + ('nint', 'f'), + ('navg', 'f'), + ('fh', 'f'), + ('dh', 'f'), + ('nheights', 'f'), + ('ipp', 'f') +]) + +REC_HEADER_STRUCTURE = numpy.dtype([ + ('magic', 'f'), + ('hours', 'f'), + ('interval', 'f'), + ('h0', 'f'), + ('nheights', 'f'), + ('snr1', 'f'), + ('snr2', 'f'), + ('snr', 'f'), +]) + +DATA_STRUCTURE = numpy.dtype([ + ('range', ' dateFile) or (endDate < dateFile): + continue + + self.fileList.append(thisFile) + self.dateFileList.append(dateFile) + + return + + def setNextFile(self): + + file_id = self.fileIndex + + if file_id == len(self.fileList): + log.success('No more files in the folder', self.name) + self.flagNoMoreFiles = 1 + return 0 + + log.success('Opening {}'.format(self.fileList[file_id]), self.name) + filename = os.path.join(self.path, self.fileList[file_id]) + + dirname, name = os.path.split(filename) + self.siteFile = name.split('.')[0] + if self.filename is not None: + self.fp.close() + self.filename = filename + self.fp = open(self.filename, 'rb') + + self.header_file = numpy.fromfile(self.fp, FILE_HEADER_STRUCTURE, 1) + yy = self.header_file['year'] - 1900 * (self.header_file['year'] > 3000) + self.year = int(yy + 1900 * (yy < 1000)) + self.doy = int(self.header_file['doy']) + self.dH = round(self.header_file['dh'], 2) + self.ipp = round(self.header_file['ipp'], 2) + self.sizeOfFile = os.path.getsize(self.filename) + self.counter_records = 0 + self.flagIsNewFile = 0 + self.fileIndex += 1 + + return 1 + + def readNextBlock(self): + + while True: + if not self.readBlock(): + self.flagIsNewFile = 1 + if not self.setNextFile(): + return 0 + + if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \ + (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)): + log.warning( + 'Reading Record No. {} -> {} [Skipping]'.format( + self.counter_records, + self.datatime.ctime()), + self.name) + continue + break + + log.log('Reading Record No. {} -> {}'.format( + self.counter_records, + self.datatime.ctime()), self.name) + + return 1 + + def readBlock(self): + + pointer = self.fp.tell() + heights, dt = self.readHeader() + self.fp.seek(pointer) + buffer_h = [] + buffer_d = [] + while True: + pointer = self.fp.tell() + if pointer == self.sizeOfFile: + return 0 + heights, datatime = self.readHeader() + if dt == datatime: + buffer_h.append(heights) + buffer_d.append(self.readData(len(heights))) + continue + self.fp.seek(pointer) + break + + if dt.date() > self.datatime.date(): + self.flagDiscontinuousBlock = 1 + self.datatime = dt + self.time = (dt - datetime.datetime(1970, 1, 1)).total_seconds() + time.timezone + self.heights = numpy.concatenate(buffer_h) + self.buffer = numpy.zeros((5, len(self.heights))) + numpy.nan + self.buffer[0, :] = numpy.concatenate([buf[0] for buf in buffer_d]) + self.buffer[1, :] = numpy.concatenate([buf[1] for buf in buffer_d]) + self.buffer[2, :] = numpy.concatenate([buf[2] for buf in buffer_d]) + self.buffer[3, :] = numpy.concatenate([buf[3] for buf in buffer_d]) + self.buffer[4, :] = numpy.concatenate([buf[4] for buf in buffer_d]) + + self.counter_records += 1 + + return 1 + + def readHeader(self): + ''' + Parse recordHeader + ''' + + self.header_rec = numpy.fromfile(self.fp, REC_HEADER_STRUCTURE, 1) + self.interval = self.header_rec['interval'] + if self.header_rec['magic'] == 888.: + self.header_rec['h0'] = round(self.header_rec['h0'], 2) + nheights = int(self.header_rec['nheights']) + hours = float(self.header_rec['hours'][0]) + heights = numpy.arange(nheights) * self.dH + self.header_rec['h0'] + datatime = datetime.datetime(self.year, 1, 1) + datetime.timedelta(days=self.doy-1, hours=hours) + return heights, datatime + else: + return False + + def readData(self, N): + ''' + Parse data + ''' + + buffer = numpy.fromfile(self.fp, 'f', 8*N).reshape(N, 8) + + pow0 = buffer[:, 0] + pow1 = buffer[:, 1] + acf0 = (buffer[:,2] + buffer[:,3]*1j) / pow0 + acf1 = (buffer[:,4] + buffer[:,5]*1j) / pow1 + dccf = (buffer[:,6] + buffer[:,7]*1j) / (pow0*pow1) + + ### SNR + sno = (pow0 + pow1 - self.header_rec['snr']) / self.header_rec['snr'] + sno10 = numpy.log10(sno) + # dsno = 1.0 / numpy.sqrt(self.header_file['nint'] * self.header_file['navg']) * (1 + (1 / sno)) + + ### Vertical Drift + sp = numpy.sqrt(numpy.abs(acf0)*numpy.abs(acf1)) + sp[numpy.where(numpy.abs(sp) >= 1.0)] = numpy.sqrt(0.9999) + + vzo = -numpy.arctan2(acf0.imag + acf1.imag,acf0.real + acf1.real)*1.5E5*1.5/(self.ipp*numpy.pi) + dvzo = numpy.sqrt(1.0 - sp*sp)*0.338*1.5E5/(numpy.sqrt(self.header_file['nint']*self.header_file['navg'])*sp*self.ipp) + err = numpy.where(dvzo <= 0.1) + dvzo[err] = 0.1 + + #Zonal Drifts + dt = self.header_file['nint']*self.ipp / 1.5E5 + coh = numpy.sqrt(numpy.abs(dccf)) + err = numpy.where(coh >= 1.0) + coh[err] = numpy.sqrt(0.99999) + + err = numpy.where(coh <= 0.1) + coh[err] = numpy.sqrt(0.1) + + vxo = numpy.arctan2(dccf.imag, dccf.real)*self.header_rec['h0']*1.0E3/(self.kd*dt) + dvxo = numpy.sqrt(1.0 - coh*coh)*self.header_rec['h0']*1.0E3/(numpy.sqrt(self.header_file['nint']*self.header_file['navg'])*coh*self.kd*dt) + + err = numpy.where(dvxo <= 0.1) + dvxo[err] = 0.1 + + return vzo, dvzo, vxo, dvxo, sno10 + + def set_output(self): + ''' + Storing data from databuffer to dataOut object + ''' + + self.dataOut.data_SNR = self.buffer[4].reshape(1, -1) + self.dataOut.heightList = self.heights + self.dataOut.data_param = self.buffer[0:4,] + self.dataOut.utctimeInit = self.time + self.dataOut.utctime = self.time + self.dataOut.useLocalTime = True + self.dataOut.paramInterval = self.interval + self.dataOut.timezone = self.timezone + self.dataOut.sizeOfFile = self.sizeOfFile + self.dataOut.flagNoData = False + self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock + + def getData(self): + ''' + Storing data from databuffer to dataOut object + ''' + if self.flagNoMoreFiles: + self.dataOut.flagNoData = True + log.success('No file left to process', self.name) + return 0 + + if not self.readNextBlock(): + self.dataOut.flagNoData = True + return 0 + + self.set_output() + + return 1 diff --git a/schainpy/model/io/pxIO_param.py b/schainpy/model/io/pxIO_param.py new file mode 100644 index 0000000..d7d4223 --- /dev/null +++ b/schainpy/model/io/pxIO_param.py @@ -0,0 +1,350 @@ +''' +Created on Jan 15, 2018 + +@author: Juan C. Espinoza +''' + +import os +import sys +import time +import glob +import datetime +import tarfile + +import numpy +try: + from netCDF4 import Dataset +except: + log.warning( + 'You should install "netCDF4" module if you want to read/write NCDF files' + ) + +from utils import folder_in_range + +from schainpy.model.io.jroIO_base import JRODataReader +from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation +from schainpy.model.data.jrodata import Parameters +from schainpy.utils import log + +UT1970 = datetime.datetime(1970, 1, 1) - datetime.timedelta(seconds=time.timezone) + + +class PXReader(JRODataReader, ProcessingUnit): + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + + self.dataOut = Parameters() + self.counter_records = 0 + self.nrecords = None + self.flagNoMoreFiles = 0 + self.isConfig = False + self.filename = None + self.intervals = set() + self.ext = ('.nc', '.tgz') + self.online_mode = False + + def setup(self, + path=None, + startDate=None, + endDate=None, + format=None, + startTime=datetime.time(0, 0, 0), + endTime=datetime.time(23, 59, 59), + walk=False, + **kwargs): + + self.path = path + self.startDate = startDate + self.endDate = endDate + self.startTime = startTime + self.endTime = endTime + self.datatime = datetime.datetime(1900,1,1) + self.walk = walk + self.nTries = kwargs.get('nTries', 10) + self.online = kwargs.get('online', False) + self.delay = kwargs.get('delay', 60) + self.ele = kwargs.get('ext', '') + + if self.path is None: + raise ValueError, 'The path is not valid' + + self.search_files(path, startDate, endDate, startTime, endTime, walk) + self.cursor = 0 + self.counter_records = 0 + + if not self.files: + raise Warning, 'There is no files matching these date in the folder: {}. \n Check startDate and endDate'.format(path) + + def search_files(self, path, startDate, endDate, startTime, endTime, walk): + ''' + Searching for NCDF files in path + Creating a list of files to procces included in [startDate,endDate] + + Input: + path - Path to find files + ''' + + log.log('Searching files {} in {} '.format(self.ext, path), 'PXReader') + if walk: + paths = [os.path.join(path, p) for p in os.listdir(path) if os.path.isdir(os.path.join(path, p))] + paths.sort() + else: + paths = [path] + + fileList0 = [] + + for subpath in paths: + if not folder_in_range(subpath.split('/')[-1], startDate, endDate, '%Y%m%d'): + continue + fileList0 += [os.path.join(subpath, s) for s in glob.glob1(subpath, '*') if os.path.splitext(s)[-1] in self.ext and '{}'.format(self.ele) in s] + + fileList0.sort() + if self.online: + fileList0 = fileList0[-1:] + + self.files = {} + + startDate = startDate - datetime.timedelta(1) + endDate = endDate + datetime.timedelta(1) + + for fullname in fileList0: + thisFile = fullname.split('/')[-1] + year = thisFile[3:7] + if not year.isdigit(): + continue + + month = thisFile[7:9] + if not month.isdigit(): + continue + + day = thisFile[9:11] + if not day.isdigit(): + continue + + year, month, day = int(year), int(month), int(day) + dateFile = datetime.date(year, month, day) + timeFile = datetime.time(int(thisFile[12:14]), int(thisFile[14:16]), int(thisFile[16:18])) + + if (startDate > dateFile) or (endDate < dateFile): + continue + + dt = datetime.datetime.combine(dateFile, timeFile) + if dt not in self.files: + self.files[dt] = [] + self.files[dt].append(fullname) + + self.dates = self.files.keys() + self.dates.sort() + + return + + def search_files_online(self): + ''' + Searching for NCDF files in online mode path + Creating a list of files to procces included in [startDate,endDate] + + Input: + path - Path to find files + ''' + + self.files = {} + + for n in range(self.nTries): + + if self.walk: + paths = [os.path.join(self.path, p) for p in os.listdir(self.path) if os.path.isdir(os.path.join(self.path, p))] + paths.sort() + path = paths[-1] + else: + path = self.path + + new_files = [os.path.join(path, s) for s in glob.glob1(path, '*') if os.path.splitext(s)[-1] in self.ext and '{}'.format(self.ele) in s] + new_files.sort() + + for fullname in new_files: + thisFile = fullname.split('/')[-1] + year = thisFile[3:7] + if not year.isdigit(): + continue + + month = thisFile[7:9] + if not month.isdigit(): + continue + + day = thisFile[9:11] + if not day.isdigit(): + continue + + year, month, day = int(year), int(month), int(day) + dateFile = datetime.date(year, month, day) + timeFile = datetime.time(int(thisFile[12:14]), int(thisFile[14:16]), int(thisFile[16:18])) + + dt = datetime.datetime.combine(dateFile, timeFile) + + if self.dt >= dt: + continue + + if dt not in self.files: + self.dt = dt + self.files[dt] = [] + + self.files[dt].append(fullname) + break + + if self.files: + break + else: + log.warning('Waiting {} seconds for the next file, try {} ...'.format(self.delay, n + 1), 'PXReader') + time.sleep(self.delay) + + if not self.files: + return 0 + + self.dates = self.files.keys() + self.dates.sort() + self.cursor = 0 + + return 1 + + def parseFile(self): + ''' + ''' + + header = {} + + for attr in self.fp.ncattrs(): + header[str(attr)] = getattr(self.fp, attr) + + self.header.append(header) + + self.data[header['TypeName']] = numpy.array(self.fp.variables[header['TypeName']]) + + def setNextFile(self): + ''' + Open next files for the current datetime + ''' + + cursor = self.cursor + if not self.online_mode: + if cursor == len(self.dates): + if self.online: + cursor = 0 + self.dt = self.dates[cursor] + self.online_mode = True + if not self.search_files_online(): + log.success('No more files', 'PXReader') + return 0 + else: + log.success('No more files', 'PXReader') + self.flagNoMoreFiles = 1 + return 0 + else: + if not self.search_files_online(): + return 0 + cursor = self.cursor + + self.data = {} + self.header = [] + + for fullname in self.files[self.dates[cursor]]: + + log.log('Opening: {}'.format(fullname), 'PXReader') + + if os.path.splitext(fullname)[-1] == '.tgz': + tar = tarfile.open(fullname, 'r:gz') + tar.extractall('/tmp') + files = [os.path.join('/tmp', member.name) for member in tar.getmembers()] + else: + files = [fullname] + + for filename in files: + if self.filename is not None: + self.fp.close() + + self.filename = filename + self.filedate = self.dates[cursor] + self.fp = Dataset(self.filename, 'r') + self.parseFile() + + self.counter_records += 1 + self.cursor += 1 + return 1 + + def readNextFile(self): + + while True: + self.flagDiscontinuousBlock = 0 + if not self.setNextFile(): + return 0 + + self.datatime = datetime.datetime.utcfromtimestamp(self.header[0]['Time']) + + if self.online: + break + + if (self.datatime < datetime.datetime.combine(self.startDate, self.startTime)) or \ + (self.datatime > datetime.datetime.combine(self.endDate, self.endTime)): + log.warning( + 'Reading Record No. {}/{} -> {} [Skipping]'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), + 'PXReader') + continue + break + + log.log( + 'Reading Record No. {}/{} -> {}'.format( + self.counter_records, + self.nrecords, + self.datatime.ctime()), + 'PXReader') + + return 1 + + + def set_output(self): + ''' + Storing data from buffer to dataOut object + ''' + + self.data['Elevation'] = numpy.array(self.fp.variables['Elevation']) + self.data['Azimuth'] = numpy.array(self.fp.variables['Azimuth']) + self.dataOut.range = numpy.array(self.fp.variables['GateWidth']) + self.dataOut.data = self.data + self.dataOut.units = [h['Unit-value'] for h in self.header] + self.dataOut.parameters = [h['TypeName'] for h in self.header] + self.dataOut.missing = self.header[0]['MissingData'] + self.dataOut.max_range = self.header[0]['MaximumRange-value'] + self.dataOut.elevation = self.header[0]['Elevation'] + self.dataOut.azimuth = self.header[0]['Azimuth'] + self.dataOut.latitude = self.header[0]['Latitude'] + self.dataOut.longitude = self.header[0]['Longitude'] + self.dataOut.utctime = self.header[0]['Time'] + self.dataOut.utctimeInit = self.dataOut.utctime + self.dataOut.useLocalTime = True + self.dataOut.flagNoData = False + self.dataOut.flagDiscontinuousBlock = self.flagDiscontinuousBlock + + log.log('Parameters found: {}'.format(','.join(self.dataOut.parameters)), + 'PXReader') + + def getData(self): + ''' + Storing data from databuffer to dataOut object + ''' + if self.flagNoMoreFiles: + self.dataOut.flagNoData = True + log.error('No file left to process', 'PXReader') + return 0 + + if not self.readNextFile(): + self.dataOut.flagNoData = True + return 0 + + self.set_output() + + return 1 + diff --git a/schainpy/model/io/testDigitalRf.txt b/schainpy/model/io/testDigitalRf.txt new file mode 100644 index 0000000..b3e280b --- /dev/null +++ b/schainpy/model/io/testDigitalRf.txt @@ -0,0 +1,15 @@ +Lectura +200samples -> 0.47m HDD 1000'' +200samples -> 6 HDD 100ms file 100s folder +200samples -> 0.48ms HDD 100ms file 1000s folder +200samples -> 116ms HDD 5000ms file 100s folder +200samples -> 182 HDD 10000ms file 100s folder +200samples -> 143 HDD 10000ms file 100s folder SSD + +Escritura +200samples -> 0.78m HDD 100ms file 1000s folder +200samples -> 0.066m HDD 100ms file 1000s folder +200samples -> 0.30 HDD 100ms file 100s folder +200samples -> 0.23 HDD 5000ms file 100s folder +200samples -> 0.176 HDD 10000ms file 100s folder + diff --git a/schainpy/model/io/utils.py b/schainpy/model/io/utils.py new file mode 100644 index 0000000..2660a31 --- /dev/null +++ b/schainpy/model/io/utils.py @@ -0,0 +1,24 @@ +""" +Utilities for IO modules +""" + +import os +from datetime import datetime + +def folder_in_range(folder, start_date, end_date, pattern): + """ + Check whether folder is bettwen start_date and end_date + + Args: + folder (str): Folder to check + start_date (date): Initial date + end_date (date): Final date + pattern (str): Datetime format of the folder + Returns: + bool: True for success, False otherwise + """ + try: + dt = datetime.strptime(folder, pattern) + except: + raise ValueError('Folder {} does not match {} format'.format(folder, pattern)) + return start_date <= dt.date() <= end_date diff --git a/schainpy/model/proc/__init__.py b/schainpy/model/proc/__init__.py index a17c2ba..2f1588c 100644 --- a/schainpy/model/proc/__init__.py +++ b/schainpy/model/proc/__init__.py @@ -11,4 +11,6 @@ from jroproc_amisr import * from jroproc_correlation import * from jroproc_parameters import * from jroproc_spectra_lags import * -from jroproc_spectra_acf import * \ No newline at end of file +from jroproc_spectra_acf import * +from bltrproc_parameters import * +from pxproc_parameters import * diff --git a/schainpy/model/proc/bltrproc_parameters.py b/schainpy/model/proc/bltrproc_parameters.py new file mode 100644 index 0000000..03b44b7 --- /dev/null +++ b/schainpy/model/proc/bltrproc_parameters.py @@ -0,0 +1,403 @@ +''' +Created on Oct 24, 2016 + +@author: roj- LouVD +''' + +import numpy +import copy +import datetime +import time +from time import gmtime + +from numpy import transpose + +from jroproc_base import ProcessingUnit, Operation +from schainpy.model.data.jrodata import Parameters + + +class BLTRParametersProc(ProcessingUnit): + ''' + Processing unit for BLTR parameters data (winds) + + Inputs: + self.dataOut.nmodes - Number of operation modes + self.dataOut.nchannels - Number of channels + self.dataOut.nranges - Number of ranges + + self.dataOut.data_SNR - SNR array + self.dataOut.data_output - Zonal, Vertical and Meridional velocity array + self.dataOut.height - Height array (km) + self.dataOut.time - Time array (seconds) + + self.dataOut.fileIndex -Index of the file currently read + self.dataOut.lat - Latitude coordinate of BLTR location + + self.dataOut.doy - Experiment doy (number of the day in the current year) + self.dataOut.month - Experiment month + self.dataOut.day - Experiment day + self.dataOut.year - Experiment year + ''' + + def __init__(self, **kwargs): + ''' + Inputs: None + ''' + ProcessingUnit.__init__(self, **kwargs) + self.dataOut = Parameters() + self.isConfig = False + + def setup(self, mode): + ''' + ''' + self.dataOut.mode = mode + + def run(self, mode, snr_threshold=None): + ''' + Inputs: + mode = High resolution (0) or Low resolution (1) data + snr_threshold = snr filter value + ''' + + if not self.isConfig: + self.setup(mode) + self.isConfig = True + + if self.dataIn.type == 'Parameters': + self.dataOut.copy(self.dataIn) + + self.dataOut.data_param = self.dataOut.data[mode] + self.dataOut.heightList = self.dataOut.height[0] + self.dataOut.data_SNR = self.dataOut.data_SNR[mode] + + if snr_threshold is not None: + SNRavg = numpy.average(self.dataOut.data_SNR, axis=0) + SNRavgdB = 10*numpy.log10(SNRavg) + for i in range(3): + self.dataOut.data_param[i][SNRavgdB <= snr_threshold] = numpy.nan + +# TODO +class OutliersFilter(Operation): + + def __init__(self, **kwargs): + ''' + ''' + Operation.__init__(self, **kwargs) + + def run(self, svalue2, method, factor, filter, npoints=9): + ''' + Inputs: + svalue - string to select array velocity + svalue2 - string to choose axis filtering + method - 0 for SMOOTH or 1 for MEDIAN + factor - number used to set threshold + filter - 1 for data filtering using the standard deviation criteria else 0 + npoints - number of points for mask filter + ''' + + print ' Outliers Filter {} {} / threshold = {}'.format(svalue, svalue, factor) + + + yaxis = self.dataOut.heightList + xaxis = numpy.array([[self.dataOut.utctime]]) + + # Zonal + value_temp = self.dataOut.data_output[0] + + # Zonal + value_temp = self.dataOut.data_output[1] + + # Vertical + value_temp = numpy.transpose(self.dataOut.data_output[2]) + + htemp = yaxis + std = value_temp + for h in range(len(htemp)): + nvalues_valid = len(numpy.where(numpy.isfinite(value_temp[h]))[0]) + minvalid = npoints + + #only if valid values greater than the minimum required (10%) + if nvalues_valid > minvalid: + + if method == 0: + #SMOOTH + w = value_temp[h] - self.Smooth(input=value_temp[h], width=npoints, edge_truncate=1) + + + if method == 1: + #MEDIAN + w = value_temp[h] - self.Median(input=value_temp[h], width = npoints) + + dw = numpy.std(w[numpy.where(numpy.isfinite(w))],ddof = 1) + + threshold = dw*factor + value_temp[numpy.where(w > threshold),h] = numpy.nan + value_temp[numpy.where(w < -1*threshold),h] = numpy.nan + + + #At the end + if svalue2 == 'inHeight': + value_temp = numpy.transpose(value_temp) + output_array[:,m] = value_temp + + if svalue == 'zonal': + self.dataOut.data_output[0] = output_array + + elif svalue == 'meridional': + self.dataOut.data_output[1] = output_array + + elif svalue == 'vertical': + self.dataOut.data_output[2] = output_array + + return self.dataOut.data_output + + + def Median(self,input,width): + ''' + Inputs: + input - Velocity array + width - Number of points for mask filter + + ''' + + if numpy.mod(width,2) == 1: + pc = int((width - 1) / 2) + cont = 0 + output = [] + + for i in range(len(input)): + if i >= pc and i < len(input) - pc: + new2 = input[i-pc:i+pc+1] + temp = numpy.where(numpy.isfinite(new2)) + new = new2[temp] + value = numpy.median(new) + output.append(value) + + output = numpy.array(output) + output = numpy.hstack((input[0:pc],output)) + output = numpy.hstack((output,input[-pc:len(input)])) + + return output + + def Smooth(self,input,width,edge_truncate = None): + ''' + Inputs: + input - Velocity array + width - Number of points for mask filter + edge_truncate - 1 for truncate the convolution product else + + ''' + + if numpy.mod(width,2) == 0: + real_width = width + 1 + nzeros = width / 2 + else: + real_width = width + nzeros = (width - 1) / 2 + + half_width = int(real_width)/2 + length = len(input) + + gate = numpy.ones(real_width,dtype='float') + norm_of_gate = numpy.sum(gate) + + nan_process = 0 + nan_id = numpy.where(numpy.isnan(input)) + if len(nan_id[0]) > 0: + nan_process = 1 + pb = numpy.zeros(len(input)) + pb[nan_id] = 1. + input[nan_id] = 0. + + if edge_truncate == True: + output = numpy.convolve(input/norm_of_gate,gate,mode='same') + elif edge_truncate == False or edge_truncate == None: + output = numpy.convolve(input/norm_of_gate,gate,mode='valid') + output = numpy.hstack((input[0:half_width],output)) + output = numpy.hstack((output,input[len(input)-half_width:len(input)])) + + if nan_process: + pb = numpy.convolve(pb/norm_of_gate,gate,mode='valid') + pb = numpy.hstack((numpy.zeros(half_width),pb)) + pb = numpy.hstack((pb,numpy.zeros(half_width))) + output[numpy.where(pb > 0.9999)] = numpy.nan + input[nan_id] = numpy.nan + return output + + def Average(self,aver=0,nhaver=1): + ''' + Inputs: + aver - Indicates the time period over which is averaged or consensus data + nhaver - Indicates the decimation factor in heights + + ''' + nhpoints = 48 + + lat_piura = -5.17 + lat_huancayo = -12.04 + lat_porcuya = -5.8 + + if '%2.2f'%self.dataOut.lat == '%2.2f'%lat_piura: + hcm = 3. + if self.dataOut.year == 2003 : + if self.dataOut.doy >= 25 and self.dataOut.doy < 64: + nhpoints = 12 + + elif '%2.2f'%self.dataOut.lat == '%2.2f'%lat_huancayo: + hcm = 3. + if self.dataOut.year == 2003 : + if self.dataOut.doy >= 25 and self.dataOut.doy < 64: + nhpoints = 12 + + + elif '%2.2f'%self.dataOut.lat == '%2.2f'%lat_porcuya: + hcm = 5.#2 + + pdata = 0.2 + taver = [1,2,3,4,6,8,12,24] + t0 = 0 + tf = 24 + ntime =(tf-t0)/taver[aver] + ti = numpy.arange(ntime) + tf = numpy.arange(ntime) + taver[aver] + + + old_height = self.dataOut.heightList + + if nhaver > 1: + num_hei = len(self.dataOut.heightList)/nhaver/self.dataOut.nmodes + deltha = 0.05*nhaver + minhvalid = pdata*nhaver + for im in range(self.dataOut.nmodes): + new_height = numpy.arange(num_hei)*deltha + self.dataOut.height[im,0] + deltha/2. + + + data_fHeigths_List = [] + data_fZonal_List = [] + data_fMeridional_List = [] + data_fVertical_List = [] + startDTList = [] + + + for i in range(ntime): + height = old_height + + start = datetime.datetime(self.dataOut.year,self.dataOut.month,self.dataOut.day) + datetime.timedelta(hours = int(ti[i])) - datetime.timedelta(hours = 5) + stop = datetime.datetime(self.dataOut.year,self.dataOut.month,self.dataOut.day) + datetime.timedelta(hours = int(tf[i])) - datetime.timedelta(hours = 5) + + + limit_sec1 = time.mktime(start.timetuple()) + limit_sec2 = time.mktime(stop.timetuple()) + + t1 = numpy.where(self.f_timesec >= limit_sec1) + t2 = numpy.where(self.f_timesec < limit_sec2) + time_select = [] + for val_sec in t1[0]: + if val_sec in t2[0]: + time_select.append(val_sec) + + + time_select = numpy.array(time_select,dtype = 'int') + minvalid = numpy.ceil(pdata*nhpoints) + + zon_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan + mer_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan + ver_aver = numpy.zeros([self.dataOut.nranges,self.dataOut.nmodes],dtype='f4') + numpy.nan + + if nhaver > 1: + new_zon_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan + new_mer_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan + new_ver_aver = numpy.zeros([num_hei,self.dataOut.nmodes],dtype='f4') + numpy.nan + + if len(time_select) > minvalid: + time_average = self.f_timesec[time_select] + + for im in range(self.dataOut.nmodes): + + for ih in range(self.dataOut.nranges): + if numpy.sum(numpy.isfinite(self.f_zon[time_select,ih,im])) >= minvalid: + zon_aver[ih,im] = numpy.nansum(self.f_zon[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_zon[time_select,ih,im])) + + if numpy.sum(numpy.isfinite(self.f_mer[time_select,ih,im])) >= minvalid: + mer_aver[ih,im] = numpy.nansum(self.f_mer[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_mer[time_select,ih,im])) + + if numpy.sum(numpy.isfinite(self.f_ver[time_select,ih,im])) >= minvalid: + ver_aver[ih,im] = numpy.nansum(self.f_ver[time_select,ih,im]) / numpy.sum(numpy.isfinite(self.f_ver[time_select,ih,im])) + + if nhaver > 1: + for ih in range(num_hei): + hvalid = numpy.arange(nhaver) + nhaver*ih + + if numpy.sum(numpy.isfinite(zon_aver[hvalid,im])) >= minvalid: + new_zon_aver[ih,im] = numpy.nansum(zon_aver[hvalid,im]) / numpy.sum(numpy.isfinite(zon_aver[hvalid,im])) + + if numpy.sum(numpy.isfinite(mer_aver[hvalid,im])) >= minvalid: + new_mer_aver[ih,im] = numpy.nansum(mer_aver[hvalid,im]) / numpy.sum(numpy.isfinite(mer_aver[hvalid,im])) + + if numpy.sum(numpy.isfinite(ver_aver[hvalid,im])) >= minvalid: + new_ver_aver[ih,im] = numpy.nansum(ver_aver[hvalid,im]) / numpy.sum(numpy.isfinite(ver_aver[hvalid,im])) + if nhaver > 1: + zon_aver = new_zon_aver + mer_aver = new_mer_aver + ver_aver = new_ver_aver + height = new_height + + + tstart = time_average[0] + tend = time_average[-1] + startTime = time.gmtime(tstart) + + year = startTime.tm_year + month = startTime.tm_mon + day = startTime.tm_mday + hour = startTime.tm_hour + minute = startTime.tm_min + second = startTime.tm_sec + + startDTList.append(datetime.datetime(year,month,day,hour,minute,second)) + + + o_height = numpy.array([]) + o_zon_aver = numpy.array([]) + o_mer_aver = numpy.array([]) + o_ver_aver = numpy.array([]) + if self.dataOut.nmodes > 1: + for im in range(self.dataOut.nmodes): + + if im == 0: + h_select = numpy.where(numpy.bitwise_and(height[0,:] >=0,height[0,:] <= hcm,numpy.isfinite(height[0,:]))) + else: + h_select = numpy.where(numpy.bitwise_and(height[1,:] > hcm,height[1,:] < 20,numpy.isfinite(height[1,:]))) + + + ht = h_select[0] + + o_height = numpy.hstack((o_height,height[im,ht])) + o_zon_aver = numpy.hstack((o_zon_aver,zon_aver[ht,im])) + o_mer_aver = numpy.hstack((o_mer_aver,mer_aver[ht,im])) + o_ver_aver = numpy.hstack((o_ver_aver,ver_aver[ht,im])) + + data_fHeigths_List.append(o_height) + data_fZonal_List.append(o_zon_aver) + data_fMeridional_List.append(o_mer_aver) + data_fVertical_List.append(o_ver_aver) + + + else: + h_select = numpy.where(numpy.bitwise_and(height[0,:] <= hcm,numpy.isfinite(height[0,:]))) + ht = h_select[0] + o_height = numpy.hstack((o_height,height[im,ht])) + o_zon_aver = numpy.hstack((o_zon_aver,zon_aver[ht,im])) + o_mer_aver = numpy.hstack((o_mer_aver,mer_aver[ht,im])) + o_ver_aver = numpy.hstack((o_ver_aver,ver_aver[ht,im])) + + data_fHeigths_List.append(o_height) + data_fZonal_List.append(o_zon_aver) + data_fMeridional_List.append(o_mer_aver) + data_fVertical_List.append(o_ver_aver) + + + return startDTList, data_fHeigths_List, data_fZonal_List, data_fMeridional_List, data_fVertical_List + + + \ No newline at end of file diff --git a/schainpy/model/proc/extensions.c b/schainpy/model/proc/extensions.c index 27f0c9d..8f74614 100644 --- a/schainpy/model/proc/extensions.c +++ b/schainpy/model/proc/extensions.c @@ -1,12 +1,22 @@ +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#define NUM_CPY_THREADS 8 #include #include #include +#include +#include +// void printArr(int *array); static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args); +static PyObject *correlateByBlock(PyObject *self, PyObject *args); +#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ +#define PyMODINIT_FUNC void +#endif static PyMethodDef extensionsMethods[] = { - { "hildebrand_sekhon", (PyCFunction)hildebrand_sekhon, METH_VARARGS, "get noise with" }, - { NULL, NULL, 0, NULL } + { "correlateByBlock", (PyCFunction)correlateByBlock, METH_VARARGS, "get correlation by block" }, + { "hildebrand_sekhon", (PyCFunction)hildebrand_sekhon, METH_VARARGS, "get noise with hildebrand_sekhon" }, + { NULL, NULL, 0, NULL } }; PyMODINIT_FUNC initcSchain() { @@ -14,13 +24,83 @@ PyMODINIT_FUNC initcSchain() { import_array(); } +static PyObject *correlateByBlock(PyObject *self, PyObject *args) { + + // int *x = (int*) malloc(4000000 * 216 * sizeof(int));; + // int a = 5; + // x = &a; + // int b = 6; + // x = &b; + // printf("Antes de imprimir x \n"); + // printf("%d \n", x[0]); + + PyObject *data_obj1, *data_obj2; + PyArrayObject *data_array1, *data_array2, *correlateRow, *out, *dataRow, *codeRow; //, , + int mode; + + if (!PyArg_ParseTuple(args, "OOi", &data_obj1, &data_obj2, &mode)) return NULL; + + data_array1 = (PyArrayObject *) PyArray_FROM_OTF(data_obj1, NPY_COMPLEX128, NPY_ARRAY_DEFAULT); + data_array2 = (PyArrayObject *) PyArray_FROM_OTF(data_obj2, NPY_FLOAT64, NPY_ARRAY_DEFAULT); + + npy_intp dims[1]; + dims[0] = 200; + npy_intp dims_code[1]; + dims_code[0] = 16; + + double complex * dataRaw; + double * codeRaw; + dataRaw = (double complex*) PyArray_DATA(data_array1); + codeRaw = (double *) PyArray_DATA(data_array2); + double complex ** outC = malloc(40000*200*sizeof(double complex)); + int i; + + clock_t start = clock(); + for(i=0; i<40000; i++){ + // codeRow = PyArray_SimpleNewFromData(1, dims_code, NPY_FLOAT64, codeRaw + 16 * i); + // dataRow = PyArray_SimpleNewFromData(1, dims, NPY_COMPLEX128, dataRaw + 200 * i); + // Py_INCREF(codeRow); + // Py_INCREF(dataRow); + // PyArray_ENABLEFLAGS(codeRow, NPY_ARRAY_OWNDATA); + // PyArray_ENABLEFLAGS(dataRow, NPY_ARRAY_OWNDATA); + correlateRow = (PyArrayObject *) PyArray_Correlate2(PyArray_SimpleNewFromData(1, dims_code, NPY_FLOAT64, codeRaw + 16 * i), PyArray_SimpleNewFromData(1, dims, NPY_COMPLEX128, dataRaw + 200 * i), (npy_intp) 2); + //Py_INCREF(correlateRow); + // PyArray_ENABLEFLAGS(correlateRow, NPY_ARRAY_OWNDATA); + memcpy(outC + 200*i, (double complex*) PyArray_DATA(correlateRow), 200 * sizeof(double complex)); + + Py_DECREF(correlateRow); + // Py_DECREF(codeRow); + // Py_DECREF(dataRow); + } + clock_t end = clock(); + float seconds = (float)(end - start) / CLOCKS_PER_SEC; + printf("%f", seconds); + // + npy_intp dimsret[2]; + dimsret[0] = 40000; + dimsret[1] = 200; + out = PyArray_SimpleNewFromData(2, dimsret, NPY_COMPLEX128, outC); + PyArray_ENABLEFLAGS(out, NPY_ARRAY_OWNDATA); + //Py_INCREF(out); + Py_DECREF(data_array1); + Py_DECREF(data_array2); + // PyArray_DebugPrint(out); + // Py_DECREF(data_obj2); + // Py_DECREF(data_obj1); + // Py_DECREF(codeRow); + // Py_DECREF(dataRow); + // free(dataRaw); + // free(codeRaw); + + return PyArray_Return(out); +} + static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args) { - /* Do your stuff here. */ double navg; PyObject *data_obj, *data_array; if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) return NULL; - data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY); + data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_ARRAY_DEFAULT); if (data_array == NULL) { Py_XDECREF(data_array); Py_XDECREF(data_obj); @@ -56,3 +136,4 @@ static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args) { return Py_BuildValue("d", lnoise); } + diff --git a/schainpy/model/proc/jroproc_amisr.py b/schainpy/model/proc/jroproc_amisr.py index f7b235c..13e571d 100644 --- a/schainpy/model/proc/jroproc_amisr.py +++ b/schainpy/model/proc/jroproc_amisr.py @@ -6,8 +6,8 @@ from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jroamisr import AMISR class AMISRProc(ProcessingUnit): - def __init__(self): - ProcessingUnit.__init__(self) + def __init__(self, **kwargs): + ProcessingUnit.__init__(self, **kwargs) self.objectDict = {} self.dataOut = AMISR() @@ -17,7 +17,8 @@ class AMISRProc(ProcessingUnit): class PrintInfo(Operation): - def __init__(self): + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.__isPrinted = False def run(self, dataOut): @@ -42,8 +43,8 @@ class BeamSelector(Operation): profileIndex = None nProfiles = None - def __init__(self): - + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.profileIndex = 0 self.__isConfig = False @@ -98,7 +99,8 @@ class BeamSelector(Operation): class ProfileToChannels(Operation): - def __init__(self): + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.__isConfig = False self.__counter_chan = 0 self.buffer = None diff --git a/schainpy/model/proc/jroproc_base.py b/schainpy/model/proc/jroproc_base.py index a9b3cb0..31873d6 100644 --- a/schainpy/model/proc/jroproc_base.py +++ b/schainpy/model/proc/jroproc_base.py @@ -3,6 +3,29 @@ $Author: murco $ $Id: jroproc_base.py 1 2012-11-12 18:56:07Z murco $ ''' +import inspect +from fuzzywuzzy import process + +def checkKwargs(method, kwargs): + currentKwargs = kwargs + choices = inspect.getargspec(method).args + try: + choices.remove('self') + except Exception as e: + pass + + try: + choices.remove('dataOut') + except Exception as e: + pass + + for kwarg in kwargs: + fuzz = process.extractOne(kwarg, choices) + if fuzz is None: + continue + if fuzz[1] < 100: + raise Exception('\x1b[0;32;40mDid you mean {} instead of {} in {}? \x1b[0m'. + format(fuzz[0], kwarg, method.__self__.__class__.__name__)) class ProcessingUnit(object): @@ -27,7 +50,7 @@ class ProcessingUnit(object): isConfig = False - def __init__(self): + def __init__(self, *args, **kwargs): self.dataIn = None self.dataInList = [] @@ -35,9 +58,31 @@ class ProcessingUnit(object): self.dataOut = None self.operations2RunDict = {} + self.operationKwargs = {} self.isConfig = False + self.args = args + self.kwargs = kwargs + + if not hasattr(self, 'name'): + self.name = self.__class__.__name__ + + checkKwargs(self.run, kwargs) + + def getAllowedArgs(self): + if hasattr(self, '__attrs__'): + return self.__attrs__ + else: + return inspect.getargspec(self.run).args + + def addOperationKwargs(self, objId, **kwargs): + ''' + ''' + + self.operationKwargs[objId] = kwargs + + def addOperation(self, opObj, objId): """ @@ -77,7 +122,7 @@ class ProcessingUnit(object): raise NotImplementedError - def callMethod(self, name, **kwargs): + def callMethod(self, name, opId): """ Ejecuta el metodo con el nombre "name" y con argumentos **kwargs de la propia clase. @@ -97,24 +142,27 @@ class ProcessingUnit(object): return False else: #Si no es un metodo RUN la entrada es la misma dataOut (interna) - if self.dataOut.isEmpty(): + if self.dataOut is not None and self.dataOut.isEmpty(): return False #Getting the pointer to method methodToCall = getattr(self, name) #Executing the self method - methodToCall(**kwargs) - - #Checkin the outputs -# if name == 'run': -# pass -# else: -# pass -# -# if name != 'run': -# return True + if hasattr(self, 'mp'): + if name=='run': + if self.mp is False: + self.mp = True + self.start() + else: + self.operationKwargs[opId]['parent'] = self.kwargs + methodToCall(**self.operationKwargs[opId]) + else: + if name=='run': + methodToCall(**self.kwargs) + else: + methodToCall(**self.operationKwargs[opId]) if self.dataOut is None: return False @@ -124,7 +172,7 @@ class ProcessingUnit(object): return True - def callObject(self, objId, **kwargs): + def callObject(self, objId): """ Ejecuta la operacion asociada al identificador del objeto "objId" @@ -140,17 +188,25 @@ class ProcessingUnit(object): None """ - if self.dataOut.isEmpty(): + if self.dataOut is not None and self.dataOut.isEmpty(): return False externalProcObj = self.operations2RunDict[objId] - externalProcObj.run(self.dataOut, **kwargs) + if hasattr(externalProcObj, 'mp'): + if externalProcObj.mp is False: + externalProcObj.kwargs['parent'] = self.kwargs + self.operationKwargs[objId] = externalProcObj.kwargs + externalProcObj.mp = True + externalProcObj.start() + else: + externalProcObj.run(self.dataOut, **externalProcObj.kwargs) + self.operationKwargs[objId] = externalProcObj.kwargs - return True - def call(self, opType, opName=None, opId=None, **kwargs): + return True + def call(self, opType, opName=None, opId=None): """ Return True si ejecuta la operacion interna nombrada "opName" o la operacion externa identificada con el id "opId"; con los argumentos "**kwargs". @@ -194,7 +250,7 @@ class ProcessingUnit(object): if not opName: raise ValueError, "opName parameter should be defined" - sts = self.callMethod(opName, **kwargs) + sts = self.callMethod(opName, opId) elif opType == 'other' or opType == 'external' or opType == 'plotter': @@ -204,7 +260,7 @@ class ProcessingUnit(object): if opId not in self.operations2RunDict.keys(): raise ValueError, "Any operation with id=%s has been added" %str(opId) - sts = self.callObject(opId, **kwargs) + sts = self.callObject(opId) else: raise ValueError, "opType should be 'self', 'external' or 'plotter'; and not '%s'" %opType @@ -221,7 +277,7 @@ class ProcessingUnit(object): return self.dataOut def checkInputs(self): - + for thisDataIn in self.dataInList: if thisDataIn.isEmpty(): @@ -255,10 +311,20 @@ class Operation(object): __buffer = None isConfig = False - def __init__(self): + def __init__(self, **kwargs): self.__buffer = None self.isConfig = False + self.kwargs = kwargs + if not hasattr(self, 'name'): + self.name = self.__class__.__name__ + checkKwargs(self.run, kwargs) + + def getAllowedArgs(self): + if hasattr(self, '__attrs__'): + return self.__attrs__ + else: + return inspect.getargspec(self.run).args def setup(self): diff --git a/schainpy/model/proc/jroproc_correlation.py b/schainpy/model/proc/jroproc_correlation.py index 20be2a1..67c72d3 100644 --- a/schainpy/model/proc/jroproc_correlation.py +++ b/schainpy/model/proc/jroproc_correlation.py @@ -4,28 +4,28 @@ from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jrodata import Correlation, hildebrand_sekhon class CorrelationProc(ProcessingUnit): - + pairsList = None - + data_cf = None - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + self.objectDict = {} self.buffer = None self.firstdatatime = None self.profIndex = 0 self.dataOut = Correlation() - + def __updateObjFromVoltage(self): - + self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy() self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy() self.dataOut.channelList = self.dataIn.channelList @@ -47,80 +47,80 @@ class CorrelationProc(ProcessingUnit): self.dataOut.nProfiles = self.dataIn.nProfiles self.dataOut.utctime = self.dataIn.utctime # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter - + # self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nPoints - - + + def removeDC(self, jspectra): - + nChannel = jspectra.shape[0] - + for i in range(nChannel): jspectra_tmp = jspectra[i,:,:] jspectra_DC = numpy.mean(jspectra_tmp,axis = 0) - + jspectra_tmp = jspectra_tmp - jspectra_DC jspectra[i,:,:] = jspectra_tmp - + return jspectra - - + + def removeNoise(self, mode = 2): indR = numpy.where(self.dataOut.lagR == 0)[0][0] indT = numpy.where(self.dataOut.lagT == 0)[0][0] - + jspectra = self.dataOut.data_corr[:,:,indR,:] - + num_chan = jspectra.shape[0] num_hei = jspectra.shape[2] - + freq_dc = indT ind_vel = numpy.array([-2,-1,1,2]) + freq_dc - + NPot = self.dataOut.getNoise(mode) - jspectra[:,freq_dc,:] = jspectra[:,freq_dc,:] - NPot + jspectra[:,freq_dc,:] = jspectra[:,freq_dc,:] - NPot SPot = jspectra[:,freq_dc,:] pairsAutoCorr = self.dataOut.getPairsAutoCorr() # self.dataOut.signalPotency = SPot self.dataOut.noise = NPot self.dataOut.SNR = (SPot/NPot)[pairsAutoCorr] - self.dataOut.data_corr[:,:,indR,:] = jspectra - - return 1 - + self.dataOut.data_corr[:,:,indR,:] = jspectra + + return 1 + def run(self, lags=None, mode = 'time', pairsList=None, fullBuffer=False, nAvg = 1, removeDC = False, splitCF=False): - + self.dataOut.flagNoData = True - + if self.dataIn.type == "Correlation": - + self.dataOut.copy(self.dataIn) - + return - + if self.dataIn.type == "Voltage": - + nChannels = self.dataIn.nChannels - nProfiles = self.dataIn.nProfiles + nProfiles = self.dataIn.nProfiles nHeights = self.dataIn.nHeights data_pre = self.dataIn.data - + #--------------- Remover DC ------------ if removeDC: data_pre = self.removeDC(data_pre) - + #--------------------------------------------- # pairsList = list(ccfList) # for i in acfList: # pairsList.append((i,i)) -# +# # ccf_pairs = numpy.arange(len(ccfList)) # acf_pairs = numpy.arange(len(ccfList),len(pairsList)) self.__updateObjFromVoltage() #---------------------------------------------------------------------- #Creating temporal buffers if fullBuffer: - tmp = numpy.zeros((len(pairsList), len(lags), nProfiles, nHeights), dtype = 'complex')*numpy.nan + tmp = numpy.zeros((len(pairsList), len(lags), nProfiles, nHeights), dtype = 'complex')*numpy.nan elif mode == 'time': if lags == None: lags = numpy.arange(-nProfiles+1, nProfiles) @@ -129,16 +129,16 @@ class CorrelationProc(ProcessingUnit): if lags == None: lags = numpy.arange(-nHeights+1, nHeights) tmp = numpy.zeros(len(pairsList), (len(lags), nProfiles),dtype='complex') - + #For loop for l in range(len(pairsList)): - + ch0 = pairsList[l][0] - ch1 = pairsList[l][1] - + ch1 = pairsList[l][1] + for i in range(len(lags)): idx = lags[i] - + if idx >= 0: if mode == 'time': ccf0 = data_pre[ch0,:nProfiles-idx,:]*numpy.conj(data_pre[ch1,idx:,:]) #time @@ -149,30 +149,30 @@ class CorrelationProc(ProcessingUnit): ccf0 = data_pre[ch0,-idx:,:]*numpy.conj(data_pre[ch1,:nProfiles+idx,:]) #time else: ccf0 = data_pre[ch0,:,-idx:]*numpy.conj(data_pre[ch1,:,:nHeights+idx]) #heights - + if fullBuffer: tmp[l,i,:ccf0.shape[0],:] = ccf0 else: tmp[l,i,:] = numpy.sum(ccf0, axis=0) - + #----------------------------------------------------------------- if fullBuffer: tmp = numpy.sum(numpy.reshape(tmp,(tmp.shape[0],tmp.shape[1],tmp.shape[2]/nAvg,nAvg,tmp.shape[3])),axis=3) self.dataOut.nAvg = nAvg - + self.dataOut.data_cf = tmp self.dataOut.mode = mode self.dataOut.nLags = len(lags) self.dataOut.pairsList = pairsList self.dataOut.nPairs = len(pairsList) - + #Se Calcula los factores de Normalizacion if mode == 'time': delta = self.dataIn.ippSeconds*self.dataIn.nCohInt else: delta = self.dataIn.heightList[1] - self.dataIn.heightList[0] self.dataOut.lagRange = numpy.array(lags)*delta -# self.dataOut.nCohInt = self.dataIn.nCohInt*nAvg +# self.dataOut.nCohInt = self.dataIn.nCohInt*nAvg self.dataOut.flagNoData = False - a = self.dataOut.normFactor - return \ No newline at end of file +# a = self.dataOut.normFactor + return diff --git a/schainpy/model/proc/jroproc_heispectra.py b/schainpy/model/proc/jroproc_heispectra.py index 2564309..1c6976f 100644 --- a/schainpy/model/proc/jroproc_heispectra.py +++ b/schainpy/model/proc/jroproc_heispectra.py @@ -4,23 +4,23 @@ from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jrodata import SpectraHeis class SpectraHeisProc(ProcessingUnit): - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + # self.buffer = None # self.firstdatatime = None # self.profIndex = 0 self.dataOut = SpectraHeis() def __updateObjFromVoltage(self): - + self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy()# self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy()# self.dataOut.channelList = self.dataIn.channelList @@ -49,17 +49,17 @@ class SpectraHeisProc(ProcessingUnit): self.dataOut.nIncohInt = 1 # self.dataOut.ippSeconds= self.dataIn.ippSeconds self.dataOut.windowOfFilter = self.dataIn.windowOfFilter - + # self.dataOut.timeInterval = self.dataIn.timeInterval*self.dataOut.nIncohInt # self.dataOut.set=self.dataIn.set # self.dataOut.deltaHeight=self.dataIn.deltaHeight def __updateObjFromFits(self): - + self.dataOut.utctime = self.dataIn.utctime # self.dataOut.channelIndexList = self.dataIn.channelIndexList - + self.dataOut.channelList = self.dataIn.channelList self.dataOut.heightList = self.dataIn.heightList self.dataOut.data_spc = self.dataIn.data @@ -73,7 +73,7 @@ class SpectraHeisProc(ProcessingUnit): # self.dataOut. def __getFft(self): - + fft_volt = numpy.fft.fft(self.dataIn.data, axis=1) fft_volt = numpy.fft.fftshift(fft_volt,axes=(1,)) spc = numpy.abs(fft_volt * numpy.conjugate(fft_volt))/(self.dataOut.nFFTPoints) @@ -82,43 +82,43 @@ class SpectraHeisProc(ProcessingUnit): def run(self): self.dataOut.flagNoData = True - + if self.dataIn.type == "Fits": self.__updateObjFromFits() self.dataOut.flagNoData = False return - + if self.dataIn.type == "SpectraHeis": self.dataOut.copy(self.dataIn) return - + if self.dataIn.type == "Voltage": self.__updateObjFromVoltage() self.__getFft() self.dataOut.flagNoData = False - + return - + raise ValueError, "The type object %s is not valid"%(self.dataIn.type) - - + + def selectChannels(self, channelList): - + channelIndexList = [] - + for channel in channelList: index = self.dataOut.channelList.index(channel) channelIndexList.append(index) - + self.selectChannelsByIndex(channelIndexList) - + def selectChannelsByIndex(self, channelIndexList): """ - Selecciona un bloque de datos en base a canales segun el channelIndexList - + Selecciona un bloque de datos en base a canales segun el channelIndexList + Input: - channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7] - + channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7] + Affected: self.dataOut.data self.dataOut.channelIndexList @@ -126,70 +126,69 @@ class SpectraHeisProc(ProcessingUnit): self.dataOut.m_ProcessingHeader.totalSpectra self.dataOut.systemHeaderObj.numChannels self.dataOut.m_ProcessingHeader.blockSize - + Return: None """ - + for channelIndex in channelIndexList: if channelIndex not in self.dataOut.channelIndexList: print channelIndexList raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex - + # nChannels = len(channelIndexList) - + data_spc = self.dataOut.data_spc[channelIndexList,:] - + self.dataOut.data_spc = data_spc self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList] - + return 1 class IncohInt4SpectraHeis(Operation): - + isConfig = False - + __profIndex = 0 __withOverapping = False - + __byTime = False __initime = None __lastdatatime = None __integrationtime = None - + __buffer = None - + __dataReady = False - + n = None - - - def __init__(self): - - Operation.__init__(self) + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) # self.isConfig = False - + def setup(self, n=None, timeInterval=None, overlapping=False): """ Set the parameters of the integration class. - + Inputs: - + n : Number of coherent integrations timeInterval : Time of integration. If the parameter "n" is selected this one does not work - overlapping : - + overlapping : + """ - + self.__initime = None self.__lastdatatime = 0 self.__buffer = None self.__dataReady = False - - + + if n == None and timeInterval == None: - raise ValueError, "n or timeInterval should be specified ..." - + raise ValueError, "n or timeInterval should be specified ..." + if n != None: self.n = n self.__byTime = False @@ -197,144 +196,144 @@ class IncohInt4SpectraHeis(Operation): self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line self.n = 9999 self.__byTime = True - + if overlapping: self.__withOverapping = True self.__buffer = None else: self.__withOverapping = False self.__buffer = 0 - + self.__profIndex = 0 - + def putData(self, data): - + """ Add a profile to the __buffer and increase in one the __profileIndex - + """ - + if not self.__withOverapping: self.__buffer += data.copy() - self.__profIndex += 1 + self.__profIndex += 1 return - + #Overlapping data nChannels, nHeis = data.shape data = numpy.reshape(data, (1, nChannels, nHeis)) - + #If the buffer is empty then it takes the data value if self.__buffer is None: self.__buffer = data self.__profIndex += 1 return - + #If the buffer length is lower than n then stakcing the data value if self.__profIndex < self.n: self.__buffer = numpy.vstack((self.__buffer, data)) self.__profIndex += 1 return - - #If the buffer length is equal to n then replacing the last buffer value with the data value + + #If the buffer length is equal to n then replacing the last buffer value with the data value self.__buffer = numpy.roll(self.__buffer, -1, axis=0) self.__buffer[self.n-1] = data self.__profIndex = self.n return - - + + def pushData(self): """ Return the sum of the last profiles and the profiles used in the sum. - + Affected: - + self.__profileIndex - + """ - + if not self.__withOverapping: data = self.__buffer n = self.__profIndex - + self.__buffer = 0 self.__profIndex = 0 - + return data, n - + #Integration with Overlapping data = numpy.sum(self.__buffer, axis=0) n = self.__profIndex - + return data, n - + def byProfiles(self, data): - + self.__dataReady = False avgdata = None # n = None - + self.putData(data) - + if self.__profIndex == self.n: - + avgdata, n = self.pushData() self.__dataReady = True - + return avgdata - + def byTime(self, data, datatime): - + self.__dataReady = False avgdata = None n = None - + self.putData(data) - + if (datatime - self.__initime) >= self.__integrationtime: avgdata, n = self.pushData() self.n = n self.__dataReady = True - + return avgdata - + def integrate(self, data, datatime=None): - + if self.__initime == None: self.__initime = datatime - + if self.__byTime: avgdata = self.byTime(data, datatime) else: avgdata = self.byProfiles(data) - - + + self.__lastdatatime = datatime - + if avgdata is None: return None, None - + avgdatatime = self.__initime - + deltatime = datatime -self.__lastdatatime - + if not self.__withOverapping: self.__initime = datatime else: self.__initime += deltatime - + return avgdata, avgdatatime - - def run(self, dataOut, **kwargs): - + + def run(self, dataOut, n=None, timeInterval=None, overlapping=False, **kwargs): + if not self.isConfig: - self.setup(**kwargs) + self.setup(n=n, timeInterval=timeInterval, overlapping=overlapping) self.isConfig = True - + avgdata, avgdatatime = self.integrate(dataOut.data_spc, dataOut.utctime) - + # dataOut.timeInterval *= n dataOut.flagNoData = True - + if self.__dataReady: dataOut.data_spc = avgdata dataOut.nIncohInt *= self.n @@ -342,4 +341,4 @@ class IncohInt4SpectraHeis(Operation): dataOut.utctime = avgdatatime # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nIncohInt # dataOut.timeInterval = self.__timeInterval*self.n - dataOut.flagNoData = False \ No newline at end of file + dataOut.flagNoData = False diff --git a/schainpy/model/proc/jroproc_parameters.py b/schainpy/model/proc/jroproc_parameters.py index 694d283..113190d 100644 --- a/schainpy/model/proc/jroproc_parameters.py +++ b/schainpy/model/proc/jroproc_parameters.py @@ -1,16 +1,55 @@ import numpy import math from scipy import optimize, interpolate, signal, stats, ndimage +import scipy import re import datetime import copy import sys import importlib import itertools +from multiprocessing import Pool, TimeoutError +from multiprocessing.pool import ThreadPool +import copy_reg +import cPickle +import types +from functools import partial +import time +#from sklearn.cluster import KMeans + +from scipy.optimize import fmin_l_bfgs_b #optimize with bounds on state papameters from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jrodata import Parameters, hildebrand_sekhon +from scipy import asarray as ar,exp +from scipy.optimize import curve_fit + +import warnings +from numpy import NaN +from scipy.optimize.optimize import OptimizeWarning +warnings.filterwarnings('ignore') + + +SPEED_OF_LIGHT = 299792458 + +'''solving pickling issue''' + +def _pickle_method(method): + func_name = method.im_func.__name__ + obj = method.im_self + cls = method.im_class + return _unpickle_method, (func_name, obj, cls) + +def _unpickle_method(func_name, obj, cls): + for cls in cls.mro(): + try: + func = cls.__dict__[func_name] + except KeyError: + pass + else: + break + return func.__get__(obj, cls) class ParametersProc(ProcessingUnit): @@ -54,10 +93,10 @@ class ParametersProc(ProcessingUnit): # self.dataOut.nIncohInt = 1 self.dataOut.ippSeconds = self.dataIn.ippSeconds # self.dataOut.windowOfFilter = self.dataIn.windowOfFilter - self.dataOut.timeInterval = self.dataIn.timeInterval + self.dataOut.timeInterval1 = self.dataIn.timeInterval self.dataOut.heightList = self.dataIn.getHeiRange() self.dataOut.frequency = self.dataIn.frequency - self.dataOut.noise = self.dataIn.noise + # self.dataOut.noise = self.dataIn.noise def run(self): @@ -76,13 +115,39 @@ class ParametersProc(ProcessingUnit): if self.dataIn.type == "Spectra": - self.dataOut.data_pre = (self.dataIn.data_spc,self.dataIn.data_cspc) + self.dataOut.data_pre = (self.dataIn.data_spc, self.dataIn.data_cspc) + self.dataOut.data_spc = self.dataIn.data_spc + self.dataOut.data_cspc = self.dataIn.data_cspc + self.dataOut.nProfiles = self.dataIn.nProfiles + self.dataOut.nIncohInt = self.dataIn.nIncohInt + self.dataOut.nFFTPoints = self.dataIn.nFFTPoints + self.dataOut.ippFactor = self.dataIn.ippFactor self.dataOut.abscissaList = self.dataIn.getVelRange(1) - # self.dataOut.noise = self.dataIn.getNoise() - self.dataOut.normFactor = self.dataIn.normFactor + self.dataOut.spc_noise = self.dataIn.getNoise() + self.dataOut.spc_range = (self.dataIn.getFreqRange(1)/1000. , self.dataIn.getAcfRange(1) , self.dataIn.getVelRange(1)) + self.dataOut.pairsList = self.dataIn.pairsList self.dataOut.groupList = self.dataIn.pairsList self.dataOut.flagNoData = False - + + if hasattr(self.dataIn, 'ChanDist'): #Distances of receiver channels + self.dataOut.ChanDist = self.dataIn.ChanDist + else: self.dataOut.ChanDist = None + + if hasattr(self.dataIn, 'VelRange'): #Velocities range + self.dataOut.VelRange = self.dataIn.VelRange + else: self.dataOut.VelRange = None + + if hasattr(self.dataIn, 'RadarConst'): #Radar Constant + self.dataOut.RadarConst = self.dataIn.RadarConst + + if hasattr(self.dataIn, 'NPW'): #NPW + self.dataOut.NPW = self.dataIn.NPW + + if hasattr(self.dataIn, 'COFA'): #COFA + self.dataOut.COFA = self.dataIn.COFA + + + #---------------------- Correlation Data --------------------------- if self.dataIn.type == "Correlation": @@ -102,7 +167,6 @@ class ParametersProc(ProcessingUnit): if self.dataIn.type == "Parameters": self.dataOut.copy(self.dataIn) - self.dataOut.utctimeInit = self.dataIn.utctime self.dataOut.flagNoData = False return True @@ -112,6 +176,1186 @@ class ParametersProc(ProcessingUnit): self.dataOut.paramInterval = self.dataIn.timeInterval return + + +def target(tups): + + obj, args = tups + #print 'TARGETTT', obj, args + return obj.FitGau(args) + +class GaussianFit(Operation): + + ''' + Function that fit of one and two generalized gaussians (gg) based + on the PSD shape across an "power band" identified from a cumsum of + the measured spectrum - noise. + + Input: + self.dataOut.data_pre : SelfSpectra + + Output: + self.dataOut.GauSPC : SPC_ch1, SPC_ch2 + + ''' + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) + self.i=0 + + + def run(self, dataOut, num_intg=7, pnoise=1., vel_arr=None, SNRlimit=-9): #num_intg: Incoherent integrations, pnoise: Noise, vel_arr: range of velocities, similar to the ftt points + """This routine will find a couple of generalized Gaussians to a power spectrum + input: spc + output: + Amplitude0,shift0,width0,p0,Amplitude1,shift1,width1,p1,noise + """ + + self.spc = dataOut.data_pre[0].copy() + + + print 'SelfSpectra Shape', numpy.asarray(self.spc).shape + + + #plt.figure(50) + #plt.subplot(121) + #plt.plot(self.spc,'k',label='spc(66)') + #plt.plot(xFrec,ySamples[1],'g',label='Ch1') + #plt.plot(xFrec,ySamples[2],'r',label='Ch2') + #plt.plot(xFrec,FitGauss,'yo:',label='fit') + #plt.legend() + #plt.title('DATOS A ALTURA DE 7500 METROS') + #plt.show() + + self.Num_Hei = self.spc.shape[2] + #self.Num_Bin = len(self.spc) + self.Num_Bin = self.spc.shape[1] + self.Num_Chn = self.spc.shape[0] + + Vrange = dataOut.abscissaList + + #print 'self.spc2', numpy.asarray(self.spc).shape + + GauSPC = numpy.empty([2,self.Num_Bin,self.Num_Hei]) + SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei]) + SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei]) + SPC_ch1[:] = numpy.NaN + SPC_ch2[:] = numpy.NaN + + + start_time = time.time() + + noise_ = dataOut.spc_noise[0].copy() + + + + pool = Pool(processes=self.Num_Chn) + args = [(Vrange, Ch, pnoise, noise_, num_intg, SNRlimit) for Ch in range(self.Num_Chn)] + objs = [self for __ in range(self.Num_Chn)] + attrs = zip(objs, args) + gauSPC = pool.map(target, attrs) + dataOut.GauSPC = numpy.asarray(gauSPC) +# ret = [] +# for n in range(self.Num_Chn): +# self.FitGau(args[n]) +# dataOut.GauSPC = ret + + + +# for ch in range(self.Num_Chn): +# +# for ht in range(self.Num_Hei): +# #print (numpy.asarray(self.spc).shape) +# spc = numpy.asarray(self.spc)[ch,:,ht] +# +# ############################################# +# # normalizing spc and noise +# # This part differs from gg1 +# spc_norm_max = max(spc) +# spc = spc / spc_norm_max +# pnoise = pnoise / spc_norm_max +# ############################################# +# +# if abs(vel_arr[0])<15.0: # this switch is for spectra collected with different length IPP's +# fatspectra=1.0 +# else: +# fatspectra=0.5 +# +# wnoise = noise_ / spc_norm_max +# #print 'wnoise', noise_, dataOut.spc_noise[0], wnoise +# #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used +# #if wnoise>1.1*pnoise: # to be tested later +# # wnoise=pnoise +# noisebl=wnoise*0.9; noisebh=wnoise*1.1 +# spc=spc-wnoise +# +# minx=numpy.argmin(spc) +# spcs=numpy.roll(spc,-minx) +# cum=numpy.cumsum(spcs) +# tot_noise=wnoise * self.Num_Bin #64; +# #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? ''' +# #snr=tot_signal/tot_noise +# #snr=cum[-1]/tot_noise +# +# #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise +# +# snr = sum(spcs)/tot_noise +# snrdB=10.*numpy.log10(snr) +# +# #if snrdB < -9 : +# # snrdB = numpy.NaN +# # continue +# +# #print 'snr',snrdB # , sum(spcs) , tot_noise +# +# +# #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4: +# # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None +# +# cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region +# cumlo=cummax*epsi; +# cumhi=cummax*(1-epsi) +# powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum-9: # when SNR is strong pick the peak with least shift (LOS velocity) error +# if oneG: +# choice=0 +# else: +# w1=lsq2[0][1]; w2=lsq2[0][5] +# a1=lsq2[0][2]; a2=lsq2[0][6] +# p1=lsq2[0][3]; p2=lsq2[0][7] +# s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2; +# gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling +# +# if gp1>gp2: +# if a1>0.7*a2: +# choice=1 +# else: +# choice=2 +# elif gp2>gp1: +# if a2>0.7*a1: +# choice=2 +# else: +# choice=1 +# else: +# choice=numpy.argmax([a1,a2])+1 +# #else: +# #choice=argmin([std2a,std2b])+1 +# +# else: # with low SNR go to the most energetic peak +# choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]]) +# +# #print 'choice',choice +# +# if choice==0: # pick the single gaussian fit +# Amplitude0=lsq1[0][2] +# shift0=lsq1[0][0] +# width0=lsq1[0][1] +# p0=lsq1[0][3] +# Amplitude1=0. +# shift1=0. +# width1=0. +# p1=0. +# noise=lsq1[0][4] +# elif choice==1: # take the first one of the 2 gaussians fitted +# Amplitude0 = lsq2[0][2] +# shift0 = lsq2[0][0] +# width0 = lsq2[0][1] +# p0 = lsq2[0][3] +# Amplitude1 = lsq2[0][6] # This is 0 in gg1 +# shift1 = lsq2[0][4] # This is 0 in gg1 +# width1 = lsq2[0][5] # This is 0 in gg1 +# p1 = lsq2[0][7] # This is 0 in gg1 +# noise = lsq2[0][8] +# else: # the second one +# Amplitude0 = lsq2[0][6] +# shift0 = lsq2[0][4] +# width0 = lsq2[0][5] +# p0 = lsq2[0][7] +# Amplitude1 = lsq2[0][2] # This is 0 in gg1 +# shift1 = lsq2[0][0] # This is 0 in gg1 +# width1 = lsq2[0][1] # This is 0 in gg1 +# p1 = lsq2[0][3] # This is 0 in gg1 +# noise = lsq2[0][8] +# +# #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0) +# SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0 +# SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1 +# #print 'SPC_ch1.shape',SPC_ch1.shape +# #print 'SPC_ch2.shape',SPC_ch2.shape +# #dataOut.data_param = SPC_ch1 +# GauSPC[0] = SPC_ch1 +# GauSPC[1] = SPC_ch2 + +# #plt.gcf().clear() +# plt.figure(50+self.i) +# self.i=self.i+1 +# #plt.subplot(121) +# plt.plot(self.spc,'k')#,label='spc(66)') +# plt.plot(SPC_ch1[ch,ht],'b')#,label='gg1') +# #plt.plot(SPC_ch2,'r')#,label='gg2') +# #plt.plot(xFrec,ySamples[1],'g',label='Ch1') +# #plt.plot(xFrec,ySamples[2],'r',label='Ch2') +# #plt.plot(xFrec,FitGauss,'yo:',label='fit') +# plt.legend() +# plt.title('DATOS A ALTURA DE 7500 METROS') +# plt.show() +# print 'shift0', shift0 +# print 'Amplitude0', Amplitude0 +# print 'width0', width0 +# print 'p0', p0 +# print '========================' +# print 'shift1', shift1 +# print 'Amplitude1', Amplitude1 +# print 'width1', width1 +# print 'p1', p1 +# print 'noise', noise +# print 's_noise', wnoise + + print '========================================================' + print 'total_time: ', time.time()-start_time + + # re-normalizing spc and noise + # This part differs from gg1 + + + + ''' Parameters: + 1. Amplitude + 2. Shift + 3. Width + 4. Power + ''' + + + ############################################################################### + def FitGau(self, X): + + Vrange, ch, pnoise, noise_, num_intg, SNRlimit = X + #print 'VARSSSS', ch, pnoise, noise, num_intg + + #print 'HEIGHTS', self.Num_Hei + + GauSPC = [] + SPC_ch1 = numpy.empty([self.Num_Bin,self.Num_Hei]) + SPC_ch2 = numpy.empty([self.Num_Bin,self.Num_Hei]) + SPC_ch1[:] = 0#numpy.NaN + SPC_ch2[:] = 0#numpy.NaN + + + + for ht in range(self.Num_Hei): + #print (numpy.asarray(self.spc).shape) + + #print 'TTTTT', ch , ht + #print self.spc.shape + + + spc = numpy.asarray(self.spc)[ch,:,ht] + + ############################################# + # normalizing spc and noise + # This part differs from gg1 + spc_norm_max = max(spc) + spc = spc / spc_norm_max + pnoise = pnoise / spc_norm_max + ############################################# + + fatspectra=1.0 + + wnoise = noise_ / spc_norm_max + #wnoise,stdv,i_max,index =enoise(spc,num_intg) #noise estimate using Hildebrand Sekhon, only wnoise is used + #if wnoise>1.1*pnoise: # to be tested later + # wnoise=pnoise + noisebl=wnoise*0.9; noisebh=wnoise*1.1 + spc=spc-wnoise + # print 'wnoise', noise_[0], spc_norm_max, wnoise + minx=numpy.argmin(spc) + spcs=numpy.roll(spc,-minx) + cum=numpy.cumsum(spcs) + tot_noise=wnoise * self.Num_Bin #64; + #print 'spc' , spcs[5:8] , 'tot_noise', tot_noise + #tot_signal=sum(cum[-5:])/5.; ''' How does this line work? ''' + #snr=tot_signal/tot_noise + #snr=cum[-1]/tot_noise + snr = sum(spcs)/tot_noise + snrdB=10.*numpy.log10(snr) + + if snrdB < SNRlimit : + snr = numpy.NaN + SPC_ch1[:,ht] = 0#numpy.NaN + SPC_ch1[:,ht] = 0#numpy.NaN + GauSPC = (SPC_ch1,SPC_ch2) + continue + #print 'snr',snrdB #, sum(spcs) , tot_noise + + + + #if snrdB<-18 or numpy.isnan(snrdB) or num_intg<4: + # return [None,]*4,[None,]*4,None,snrdB,None,None,[None,]*5,[None,]*9,None + + cummax=max(cum); epsi=0.08*fatspectra # cumsum to narrow down the energy region + cumlo=cummax*epsi; + cumhi=cummax*(1-epsi) + powerindex=numpy.array(numpy.where(numpy.logical_and(cum>cumlo, cum-6: # when SNR is strong pick the peak with least shift (LOS velocity) error + if oneG: + choice=0 + else: + w1=lsq2[0][1]; w2=lsq2[0][5] + a1=lsq2[0][2]; a2=lsq2[0][6] + p1=lsq2[0][3]; p2=lsq2[0][7] + s1=(2**(1+1./p1))*scipy.special.gamma(1./p1)/p1; + s2=(2**(1+1./p2))*scipy.special.gamma(1./p2)/p2; + gp1=a1*w1*s1; gp2=a2*w2*s2 # power content of each ggaussian with proper p scaling + + if gp1>gp2: + if a1>0.7*a2: + choice=1 + else: + choice=2 + elif gp2>gp1: + if a2>0.7*a1: + choice=2 + else: + choice=1 + else: + choice=numpy.argmax([a1,a2])+1 + #else: + #choice=argmin([std2a,std2b])+1 + + else: # with low SNR go to the most energetic peak + choice=numpy.argmax([lsq1[0][2]*lsq1[0][1],lsq2[0][2]*lsq2[0][1],lsq2[0][6]*lsq2[0][5]]) + + + shift0=lsq2[0][0]; vel0=Vrange[0] + shift0*(Vrange[1]-Vrange[0]) + shift1=lsq2[0][4]; vel1=Vrange[0] + shift1*(Vrange[1]-Vrange[0]) + + max_vel = 20 + + #first peak will be 0, second peak will be 1 + if vel0 > 0 and vel0 < max_vel : #first peak is in the correct range + shift0=lsq2[0][0] + width0=lsq2[0][1] + Amplitude0=lsq2[0][2] + p0=lsq2[0][3] + + shift1=lsq2[0][4] + width1=lsq2[0][5] + Amplitude1=lsq2[0][6] + p1=lsq2[0][7] + noise=lsq2[0][8] + else: + shift1=lsq2[0][0] + width1=lsq2[0][1] + Amplitude1=lsq2[0][2] + p1=lsq2[0][3] + + shift0=lsq2[0][4] + width0=lsq2[0][5] + Amplitude0=lsq2[0][6] + p0=lsq2[0][7] + noise=lsq2[0][8] + + if Amplitude0<0.1: # in case the peak is noise + shift0,width0,Amplitude0,p0 = 4*[numpy.NaN] + if Amplitude1<0.1: + shift1,width1,Amplitude1,p1 = 4*[numpy.NaN] + + +# if choice==0: # pick the single gaussian fit +# Amplitude0=lsq1[0][2] +# shift0=lsq1[0][0] +# width0=lsq1[0][1] +# p0=lsq1[0][3] +# Amplitude1=0. +# shift1=0. +# width1=0. +# p1=0. +# noise=lsq1[0][4] +# elif choice==1: # take the first one of the 2 gaussians fitted +# Amplitude0 = lsq2[0][2] +# shift0 = lsq2[0][0] +# width0 = lsq2[0][1] +# p0 = lsq2[0][3] +# Amplitude1 = lsq2[0][6] # This is 0 in gg1 +# shift1 = lsq2[0][4] # This is 0 in gg1 +# width1 = lsq2[0][5] # This is 0 in gg1 +# p1 = lsq2[0][7] # This is 0 in gg1 +# noise = lsq2[0][8] +# else: # the second one +# Amplitude0 = lsq2[0][6] +# shift0 = lsq2[0][4] +# width0 = lsq2[0][5] +# p0 = lsq2[0][7] +# Amplitude1 = lsq2[0][2] # This is 0 in gg1 +# shift1 = lsq2[0][0] # This is 0 in gg1 +# width1 = lsq2[0][1] # This is 0 in gg1 +# p1 = lsq2[0][3] # This is 0 in gg1 +# noise = lsq2[0][8] + + #print len(noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0) + SPC_ch1[:,ht] = noise + Amplitude0*numpy.exp(-0.5*(abs(x-shift0))/width0)**p0 + SPC_ch2[:,ht] = noise + Amplitude1*numpy.exp(-0.5*(abs(x-shift1))/width1)**p1 + #print 'SPC_ch1.shape',SPC_ch1.shape + #print 'SPC_ch2.shape',SPC_ch2.shape + #dataOut.data_param = SPC_ch1 + GauSPC = (SPC_ch1,SPC_ch2) + #GauSPC[1] = SPC_ch2 + +# print 'shift0', shift0 +# print 'Amplitude0', Amplitude0 +# print 'width0', width0 +# print 'p0', p0 +# print '========================' +# print 'shift1', shift1 +# print 'Amplitude1', Amplitude1 +# print 'width1', width1 +# print 'p1', p1 +# print 'noise', noise +# print 's_noise', wnoise + + return GauSPC + + + def y_jacobian1(self,x,state): # This function is for further analysis of generalized Gaussians, it is not too importan for the signal discrimination. + y_model=self.y_model1(x,state) + s0,w0,a0,p0,n=state + e0=((x-s0)/w0)**2; + + e0u=((x-s0-self.Num_Bin)/w0)**2; + + e0d=((x-s0+self.Num_Bin)/w0)**2 + m0=numpy.exp(-0.5*e0**(p0/2.)); + m0u=numpy.exp(-0.5*e0u**(p0/2.)); + m0d=numpy.exp(-0.5*e0d**(p0/2.)) + JA=m0+m0u+m0d + JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d) + + JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0) + + JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2 + jack1=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,1./y_model]) + return jack1.T + + def y_jacobian2(self,x,state): + y_model=self.y_model2(x,state) + s0,w0,a0,p0,s1,w1,a1,p1,n=state + e0=((x-s0)/w0)**2; + + e0u=((x-s0- self.Num_Bin )/w0)**2; + + e0d=((x-s0+ self.Num_Bin )/w0)**2 + e1=((x-s1)/w1)**2; + + e1u=((x-s1- self.Num_Bin )/w1)**2; + + e1d=((x-s1+ self.Num_Bin )/w1)**2 + m0=numpy.exp(-0.5*e0**(p0/2.)); + m0u=numpy.exp(-0.5*e0u**(p0/2.)); + m0d=numpy.exp(-0.5*e0d**(p0/2.)) + m1=numpy.exp(-0.5*e1**(p1/2.)); + m1u=numpy.exp(-0.5*e1u**(p1/2.)); + m1d=numpy.exp(-0.5*e1d**(p1/2.)) + JA=m0+m0u+m0d + JA1=m1+m1u+m1d + JP=(-1/4.)*a0*m0*e0**(p0/2.)*numpy.log(e0)+(-1/4.)*a0*m0u*e0u**(p0/2.)*numpy.log(e0u)+(-1/4.)*a0*m0d*e0d**(p0/2.)*numpy.log(e0d) + JP1=(-1/4.)*a1*m1*e1**(p1/2.)*numpy.log(e1)+(-1/4.)*a1*m1u*e1u**(p1/2.)*numpy.log(e1u)+(-1/4.)*a1*m1d*e1d**(p1/2.)*numpy.log(e1d) + + JS=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0) + + JS1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1) + + JW=(p0/w0/2.)*a0*m0*e0**(p0/2.-1)*((x-s0)/w0)**2+(p0/w0/2.)*a0*m0u*e0u**(p0/2.-1)*((x-s0- self.Num_Bin )/w0)**2+(p0/w0/2.)*a0*m0d*e0d**(p0/2.-1)*((x-s0+ self.Num_Bin )/w0)**2 + + JW1=(p1/w1/2.)*a1*m1*e1**(p1/2.-1)*((x-s1)/w1)**2+(p1/w1/2.)*a1*m1u*e1u**(p1/2.-1)*((x-s1- self.Num_Bin )/w1)**2+(p1/w1/2.)*a1*m1d*e1d**(p1/2.-1)*((x-s1+ self.Num_Bin )/w1)**2 + jack2=numpy.sqrt(7)*numpy.array([JS/y_model,JW/y_model,JA/y_model,JP/y_model,JS1/y_model,JW1/y_model,JA1/y_model,JP1/y_model,1./y_model]) + return jack2.T + + def y_model1(self,x,state): + shift0,width0,amplitude0,power0,noise=state + model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0) + + model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0) + + model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0) + return model0+model0u+model0d+noise + + def y_model2(self,x,state): #Equation for two generalized Gaussians with Nyquist + shift0,width0,amplitude0,power0,shift1,width1,amplitude1,power1,noise=state + model0=amplitude0*numpy.exp(-0.5*abs((x-shift0)/width0)**power0) + + model0u=amplitude0*numpy.exp(-0.5*abs((x-shift0- self.Num_Bin )/width0)**power0) + + model0d=amplitude0*numpy.exp(-0.5*abs((x-shift0+ self.Num_Bin )/width0)**power0) + model1=amplitude1*numpy.exp(-0.5*abs((x-shift1)/width1)**power1) + + model1u=amplitude1*numpy.exp(-0.5*abs((x-shift1- self.Num_Bin )/width1)**power1) + + model1d=amplitude1*numpy.exp(-0.5*abs((x-shift1+ self.Num_Bin )/width1)**power1) + return model0+model0u+model0d+model1+model1u+model1d+noise + + def misfit1(self,state,y_data,x,num_intg): # This function compares how close real data is with the model data, the close it is, the better it is. + + return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model1(x,state)))**2)#/(64-5.) # /(64-5.) can be commented + + def misfit2(self,state,y_data,x,num_intg): + return num_intg*sum((numpy.log(y_data)-numpy.log(self.y_model2(x,state)))**2)#/(64-9.) + + +class PrecipitationProc(Operation): + + ''' + Operator that estimates Reflectivity factor (Z), and estimates rainfall Rate (R) + + Input: + self.dataOut.data_pre : SelfSpectra + + Output: + + self.dataOut.data_output : Reflectivity factor, rainfall Rate + + + Parameters affected: + ''' + + + def run(self, dataOut, radar=None, Pt=None, Gt=None, Gr=None, Lambda=None, aL=None, + tauW=None, ThetaT=None, ThetaR=None, Km = 0.93, Altitude=None): + + self.spc = dataOut.data_pre[0].copy() + self.Num_Hei = self.spc.shape[2] + self.Num_Bin = self.spc.shape[1] + self.Num_Chn = self.spc.shape[0] + + Velrange = dataOut.abscissaList + + if radar == "MIRA35C" : + + Ze = self.dBZeMODE2(dataOut) + + else: + + self.Pt = Pt + self.Gt = Gt + self.Gr = Gr + self.Lambda = Lambda + self.aL = aL + self.tauW = tauW + self.ThetaT = ThetaT + self.ThetaR = ThetaR + + RadarConstant = GetRadarConstant() + SPCmean = numpy.mean(self.spc,0) + ETA = numpy.zeros(self.Num_Hei) + Pr = numpy.sum(SPCmean,0) + + #for R in range(self.Num_Hei): + # ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA) + + D_range = numpy.zeros(self.Num_Hei) + EqSec = numpy.zeros(self.Num_Hei) + del_V = numpy.zeros(self.Num_Hei) + + for R in range(self.Num_Hei): + ETA[R] = RadarConstant * Pr[R] * R**2 #Reflectivity (ETA) + + h = R + Altitude #Range from ground to radar pulse altitude + del_V[R] = 1 + 3.68 * 10**-5 * h + 1.71 * 10**-9 * h**2 #Density change correction for velocity + + D_range[R] = numpy.log( (9.65 - (Velrange[R]/del_V[R])) / 10.3 ) / -0.6 #Range of Diameter of drops related to velocity + SIGMA[R] = numpy.pi**5 / Lambda**4 * Km * D_range[R]**6 #Equivalent Section of drops (sigma) + + N_dist[R] = ETA[R] / SIGMA[R] + + Ze = (ETA * Lambda**4) / (numpy.pi * Km) + Z = numpy.sum( N_dist * D_range**6 ) + RR = 6*10**-4*numpy.pi * numpy.sum( D_range**3 * N_dist * Velrange ) #Rainfall rate + + + RR = (Ze/200)**(1/1.6) + dBRR = 10*numpy.log10(RR) + + dBZe = 10*numpy.log10(Ze) + dataOut.data_output = Ze + dataOut.data_param = numpy.ones([2,self.Num_Hei]) + dataOut.channelList = [0,1] + print 'channelList', dataOut.channelList + dataOut.data_param[0]=dBZe + dataOut.data_param[1]=dBRR + print 'RR SHAPE', dBRR.shape + print 'Ze SHAPE', dBZe.shape + print 'dataOut.data_param SHAPE', dataOut.data_param.shape + + + def dBZeMODE2(self, dataOut): # Processing for MIRA35C + + NPW = dataOut.NPW + COFA = dataOut.COFA + + SNR = numpy.array([self.spc[0,:,:] / NPW[0]]) #, self.spc[1,:,:] / NPW[1]]) + RadarConst = dataOut.RadarConst + #frequency = 34.85*10**9 + + ETA = numpy.zeros(([self.Num_Chn ,self.Num_Hei])) + data_output = numpy.ones([self.Num_Chn , self.Num_Hei])*numpy.NaN + + ETA = numpy.sum(SNR,1) + print 'ETA' , ETA + ETA = numpy.where(ETA is not 0. , ETA, numpy.NaN) + + Ze = numpy.ones([self.Num_Chn, self.Num_Hei] ) + + for r in range(self.Num_Hei): + + Ze[0,r] = ( ETA[0,r] ) * COFA[0,r][0] * RadarConst * ((r/5000.)**2) + #Ze[1,r] = ( ETA[1,r] ) * COFA[1,r][0] * RadarConst * ((r/5000.)**2) + + return Ze + + def GetRadarConstant(self): + + """ + Constants: + + Pt: Transmission Power dB + Gt: Transmission Gain dB + Gr: Reception Gain dB + Lambda: Wavelenght m + aL: Attenuation loses dB + tauW: Width of transmission pulse s + ThetaT: Transmission antenna bean angle rad + ThetaR: Reception antenna beam angle rad + + """ + Numerator = ( (4*numpy.pi)**3 * aL**2 * 16 * numpy.log(2) ) + Denominator = ( Pt * Gt * Gr * Lambda**2 * SPEED_OF_LIGHT * TauW * numpy.pi * ThetaT * TheraR) + RadarConstant = Numerator / Denominator + + return RadarConstant + + + +class FullSpectralAnalysis(Operation): + + """ + Function that implements Full Spectral Analisys technique. + + Input: + self.dataOut.data_pre : SelfSpectra and CrossSPectra data + self.dataOut.groupList : Pairlist of channels + self.dataOut.ChanDist : Physical distance between receivers + + + Output: + + self.dataOut.data_output : Zonal wind, Meridional wind and Vertical wind + + + Parameters affected: Winds, height range, SNR + + """ + def run(self, dataOut, E01=None, E02=None, E12=None, N01=None, N02=None, N12=None, SNRlimit=7): + + spc = dataOut.data_pre[0].copy() + cspc = dataOut.data_pre[1].copy() + + nChannel = spc.shape[0] + nProfiles = spc.shape[1] + nHeights = spc.shape[2] + + pairsList = dataOut.groupList + if dataOut.ChanDist is not None : + ChanDist = dataOut.ChanDist + else: + ChanDist = numpy.array([[E01, N01],[E02,N02],[E12,N12]]) + + #print 'ChanDist', ChanDist + + if dataOut.VelRange is not None: + VelRange= dataOut.VelRange + else: + VelRange= dataOut.abscissaList + + ySamples=numpy.ones([nChannel,nProfiles]) + phase=numpy.ones([nChannel,nProfiles]) + CSPCSamples=numpy.ones([nChannel,nProfiles],dtype=numpy.complex_) + coherence=numpy.ones([nChannel,nProfiles]) + PhaseSlope=numpy.ones(nChannel) + PhaseInter=numpy.ones(nChannel) + dataSNR = dataOut.data_SNR + + + + data = dataOut.data_pre + noise = dataOut.noise + print 'noise',noise + #SNRdB = 10*numpy.log10(dataOut.data_SNR) + + FirstMoment = numpy.average(dataOut.data_param[:,1,:],0) + #SNRdBMean = [] + + + #for j in range(nHeights): + # FirstMoment = numpy.append(FirstMoment,numpy.mean([dataOut.data_param[0,1,j],dataOut.data_param[1,1,j],dataOut.data_param[2,1,j]])) + # SNRdBMean = numpy.append(SNRdBMean,numpy.mean([SNRdB[0,j],SNRdB[1,j],SNRdB[2,j]])) + + data_output=numpy.ones([3,spc.shape[2]])*numpy.NaN + + velocityX=[] + velocityY=[] + velocityV=[] + + dbSNR = 10*numpy.log10(dataSNR) + dbSNR = numpy.average(dbSNR,0) + for Height in range(nHeights): + + [Vzon,Vmer,Vver, GaussCenter]= self.WindEstimation(spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR[Height], SNRlimit) + + if abs(Vzon)<100. and abs(Vzon)> 0.: + velocityX=numpy.append(velocityX, Vzon)#Vmag + + else: + print 'Vzon',Vzon + velocityX=numpy.append(velocityX, numpy.NaN) + + if abs(Vmer)<100. and abs(Vmer) > 0.: + velocityY=numpy.append(velocityY, Vmer)#Vang + + else: + print 'Vmer',Vmer + velocityY=numpy.append(velocityY, numpy.NaN) + + if dbSNR[Height] > SNRlimit: + velocityV=numpy.append(velocityV, FirstMoment[Height]) + else: + velocityV=numpy.append(velocityV, numpy.NaN) + #FirstMoment[Height]= numpy.NaN +# if SNRdBMean[Height] <12: +# FirstMoment[Height] = numpy.NaN +# velocityX[Height] = numpy.NaN +# velocityY[Height] = numpy.NaN + + + data_output[0]=numpy.array(velocityX) + data_output[1]=numpy.array(velocityY) + data_output[2]=-velocityV#FirstMoment + + print ' ' + #print 'FirstMoment' + #print FirstMoment + print 'velocityX',data_output[0] + print ' ' + print 'velocityY',data_output[1] + #print numpy.array(velocityY) + print ' ' + #print 'SNR' + #print 10*numpy.log10(dataOut.data_SNR) + #print numpy.shape(10*numpy.log10(dataOut.data_SNR)) + print ' ' + + + dataOut.data_output=data_output + return + + + def moving_average(self,x, N=2): + return numpy.convolve(x, numpy.ones((N,))/N)[(N-1):] + + def gaus(self,xSamples,a,x0,sigma): + return a*numpy.exp(-(xSamples-x0)**2/(2*sigma**2)) + + def Find(self,x,value): + for index in range(len(x)): + if x[index]==value: + return index + + def WindEstimation(self, spc, cspc, pairsList, ChanDist, Height, noise, VelRange, dbSNR, SNRlimit): + + ySamples=numpy.ones([spc.shape[0],spc.shape[1]]) + phase=numpy.ones([spc.shape[0],spc.shape[1]]) + CSPCSamples=numpy.ones([spc.shape[0],spc.shape[1]],dtype=numpy.complex_) + coherence=numpy.ones([spc.shape[0],spc.shape[1]]) + PhaseSlope=numpy.ones(spc.shape[0]) + PhaseInter=numpy.ones(spc.shape[0]) + xFrec=VelRange + + '''Getting Eij and Nij''' + + E01=ChanDist[0][0] + N01=ChanDist[0][1] + + E02=ChanDist[1][0] + N02=ChanDist[1][1] + + E12=ChanDist[2][0] + N12=ChanDist[2][1] + + z = spc.copy() + z = numpy.where(numpy.isfinite(z), z, numpy.NAN) + + for i in range(spc.shape[0]): + + '''****** Line of Data SPC ******''' + zline=z[i,:,Height] + + '''****** SPC is normalized ******''' + FactNorm= (zline.copy()-noise[i]) / numpy.sum(zline.copy()) + FactNorm= FactNorm/numpy.sum(FactNorm) + + SmoothSPC=self.moving_average(FactNorm,N=3) + + xSamples = ar(range(len(SmoothSPC))) + ySamples[i] = SmoothSPC + + #dbSNR=10*numpy.log10(dataSNR) + print ' ' + print ' ' + print ' ' + + #print 'dataSNR', dbSNR.shape, dbSNR[0,40:120] + print 'SmoothSPC', SmoothSPC.shape, SmoothSPC[0:20] + print 'noise',noise + print 'zline',zline.shape, zline[0:20] + print 'FactNorm',FactNorm.shape, FactNorm[0:20] + print 'FactNorm suma', numpy.sum(FactNorm) + + for i in range(spc.shape[0]): + + '''****** Line of Data CSPC ******''' + cspcLine=cspc[i,:,Height].copy() + + '''****** CSPC is normalized ******''' + chan_index0 = pairsList[i][0] + chan_index1 = pairsList[i][1] + CSPCFactor= abs(numpy.sum(ySamples[chan_index0]) * numpy.sum(ySamples[chan_index1])) # + + CSPCNorm = (cspcLine.copy() -noise[i]) / numpy.sqrt(CSPCFactor) + + CSPCSamples[i] = CSPCNorm + coherence[i] = numpy.abs(CSPCSamples[i]) / numpy.sqrt(CSPCFactor) + + coherence[i]= self.moving_average(coherence[i],N=2) + + phase[i] = self.moving_average( numpy.arctan2(CSPCSamples[i].imag, CSPCSamples[i].real),N=1)#*180/numpy.pi + + print 'cspcLine', cspcLine.shape, cspcLine[0:20] + print 'CSPCFactor', CSPCFactor#, CSPCFactor[0:20] + print numpy.sum(ySamples[chan_index0]), numpy.sum(ySamples[chan_index1]), -noise[i] + print 'CSPCNorm', CSPCNorm.shape, CSPCNorm[0:20] + print 'CSPCNorm suma', numpy.sum(CSPCNorm) + print 'CSPCSamples', CSPCSamples.shape, CSPCSamples[0,0:20] + + '''****** Getting fij width ******''' + + yMean=[] + yMean2=[] + + for j in range(len(ySamples[1])): + yMean=numpy.append(yMean,numpy.mean([ySamples[0,j],ySamples[1,j],ySamples[2,j]])) + + '''******* Getting fitting Gaussian ******''' + meanGauss=sum(xSamples*yMean) / len(xSamples) + sigma=sum(yMean*(xSamples-meanGauss)**2) / len(xSamples) + + print '****************************' + print 'len(xSamples): ',len(xSamples) + print 'yMean: ', yMean.shape, yMean[0:20] + print 'ySamples', ySamples.shape, ySamples[0,0:20] + print 'xSamples: ',xSamples.shape, xSamples[0:20] + + print 'meanGauss',meanGauss + print 'sigma',sigma + + #if (abs(meanGauss/sigma**2) > 0.0001) : #0.000000001): + if dbSNR > SNRlimit : + try: + popt,pcov = curve_fit(self.gaus,xSamples,yMean,p0=[1,meanGauss,sigma]) + + if numpy.amax(popt)>numpy.amax(yMean)*0.3: + FitGauss=self.gaus(xSamples,*popt) + + else: + FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) + print 'Verificador: Dentro', Height + except :#RuntimeError: + FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) + + + else: + FitGauss=numpy.ones(len(xSamples))*numpy.mean(yMean) + + Maximun=numpy.amax(yMean) + eMinus1=Maximun*numpy.exp(-1)#*0.8 + + HWpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-eMinus1))) + HalfWidth= xFrec[HWpos] + GCpos=self.Find(FitGauss, numpy.amax(FitGauss)) + Vpos=self.Find(FactNorm, numpy.amax(FactNorm)) + + #Vpos=FirstMoment[] + + '''****** Getting Fij ******''' + + GaussCenter=xFrec[GCpos] + if (GaussCenter<0 and HalfWidth>0) or (GaussCenter>0 and HalfWidth<0): + Fij=abs(GaussCenter)+abs(HalfWidth)+0.0000001 + else: + Fij=abs(GaussCenter-HalfWidth)+0.0000001 + + '''****** Getting Frecuency range of significant data ******''' + + Rangpos=self.Find(FitGauss,min(FitGauss, key=lambda value:abs(value-Maximun*0.10))) + + if Rangpos5 and len(FrecRange)=hmin) & (h1met8) & (vmet<50) & (spcmet<10) + indthisH = numpy.where(thisH) - vthisH = vmet[(h1met>=hmin) & (h1met 3: + + vel_aux = vmet[thisH] + chan_aux = cmet[thisH] + cosu_aux = dir_cosu[chan_aux] + cosv_aux = dir_cosv[chan_aux] + cosw_aux = dir_cosw[chan_aux] + + nch = numpy.size(numpy.unique(chan_aux)) + if nch > 1: + A = self.__calculateMatA(cosu_aux, cosv_aux, cosw_aux, True) + velEst[i,:] = numpy.dot(A,vel_aux) - def run(self, dataOut, technique, **kwargs): - + return velEst + + def run(self, dataOut, technique, nHours=1, hmin=70, hmax=110, **kwargs): + param = dataOut.data_param if dataOut.abscissaList != None: absc = dataOut.abscissaList[:-1] - noise = dataOut.noise + # noise = dataOut.noise heightList = dataOut.heightList SNR = dataOut.data_SNR @@ -1101,11 +2371,6 @@ class WindProfiler(Operation): if kwargs.has_key('hmax'): hmax = kwargs['hmax'] else: hmax = 110 - - if kwargs.has_key('BinKm'): - binkm = kwargs['BinKm'] - else: - binkm = 2 dataOut.outputInterval = nHours*3600 @@ -1131,7 +2396,7 @@ class WindProfiler(Operation): self.__initime += dataOut.outputInterval #to erase time offset - dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax, binkm) + dataOut.data_output, dataOut.heightList = self.techniqueMeteors(self.__buffer, meteorThresh, hmin, hmax) dataOut.flagNoData = False self.__buffer = None @@ -1147,13 +2412,17 @@ class WindProfiler(Operation): else: rx_location = [(0,1),(1,1),(1,0)] if kwargs.has_key('azimuth'): azimuth = kwargs['azimuth'] - else: azimuth = 51 + else: azimuth = 51.06 if kwargs.has_key('dfactor'): dfactor = kwargs['dfactor'] if kwargs.has_key('mode'): mode = kwargs['mode'] - else: mode = 'SA' - + if kwargs.has_key('theta_x'): + theta_x = kwargs['theta_x'] + if kwargs.has_key('theta_y'): + theta_y = kwargs['theta_y'] + else: mode = 'SA' + #Borrar luego esto if dataOut.groupList is None: dataOut.groupList = [(0,1),(0,2),(1,2)] @@ -1194,7 +2463,7 @@ class WindProfiler(Operation): if mode == 'SA': dataOut.data_output = self.techniqueNSM_SA(rx_location=rx_location, groupList=groupList, azimuth=azimuth, dfactor=dfactor, k=k,metArray=metArray, heightList=heightList,timeList=timeList) elif mode == 'DBS': - dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList) + dataOut.data_output = self.techniqueNSM_DBS(metArray=metArray,heightList=heightList,timeList=timeList, azimuth=azimuth, theta_x=theta_x, theta_y=theta_y) dataOut.data_output = dataOut.data_output.T dataOut.flagNoData = False self.__buffer = None @@ -1203,8 +2472,8 @@ class WindProfiler(Operation): class EWDriftsEstimation(Operation): - def __init__(self): - Operation.__init__(self) + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) def __correctValues(self, heiRang, phi, velRadial, SNR): listPhi = phi.tolist() @@ -1273,26 +2542,27 @@ class EWDriftsEstimation(Operation): class NonSpecularMeteorDetection(Operation): - def run(self, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False): - data_acf = self.dataOut.data_pre[0] - data_ccf = self.dataOut.data_pre[1] + def run(self, dataOut, mode, SNRthresh=8, phaseDerThresh=0.5, cohThresh=0.8, allData = False): + data_acf = dataOut.data_pre[0] + data_ccf = dataOut.data_pre[1] + pairsList = dataOut.groupList[1] - lamb = self.dataOut.C/self.dataOut.frequency - tSamp = self.dataOut.ippSeconds*self.dataOut.nCohInt - paramInterval = self.dataOut.paramInterval + lamb = dataOut.C/dataOut.frequency + tSamp = dataOut.ippSeconds*dataOut.nCohInt + paramInterval = dataOut.paramInterval nChannels = data_acf.shape[0] nLags = data_acf.shape[1] nProfiles = data_acf.shape[2] - nHeights = self.dataOut.nHeights - nCohInt = self.dataOut.nCohInt - sec = numpy.round(nProfiles/self.dataOut.paramInterval) - heightList = self.dataOut.heightList - ippSeconds = self.dataOut.ippSeconds*self.dataOut.nCohInt*self.dataOut.nAvg - utctime = self.dataOut.utctime - - self.dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds) + nHeights = dataOut.nHeights + nCohInt = dataOut.nCohInt + sec = numpy.round(nProfiles/dataOut.paramInterval) + heightList = dataOut.heightList + ippSeconds = dataOut.ippSeconds*dataOut.nCohInt*dataOut.nAvg + utctime = dataOut.utctime + dataOut.abscissaList = numpy.arange(0,paramInterval+ippSeconds,ippSeconds) + #------------------------ SNR -------------------------------------- power = data_acf[:,0,:,:].real noise = numpy.zeros(nChannels) @@ -1304,15 +2574,16 @@ class NonSpecularMeteorDetection(Operation): SNRdB = 10*numpy.log10(SNR) if mode == 'SA': - nPairs = data_ccf.shape[0] + dataOut.groupList = dataOut.groupList[1] + nPairs = data_ccf.shape[0] #---------------------- Coherence and Phase -------------------------- phase = numpy.zeros(data_ccf[:,0,:,:].shape) # phase1 = numpy.copy(phase) coh1 = numpy.zeros(data_ccf[:,0,:,:].shape) for p in range(nPairs): - ch0 = self.dataOut.groupList[p][0] - ch1 = self.dataOut.groupList[p][1] + ch0 = pairsList[p][0] + ch1 = pairsList[p][1] ccf = data_ccf[p,0,:,:]/numpy.sqrt(data_acf[ch0,0,:,:]*data_acf[ch1,0,:,:]) phase[p,:,:] = ndimage.median_filter(numpy.angle(ccf), size = (5,1)) #median filter # phase1[p,:,:] = numpy.angle(ccf) #median filter @@ -1384,17 +2655,19 @@ class NonSpecularMeteorDetection(Operation): data_param[:,6:] = phase[:,tmet,hmet].T elif mode == 'DBS': - self.dataOut.groupList = numpy.arange(nChannels) - + dataOut.groupList = numpy.arange(nChannels) + #Radial Velocities -# phase = numpy.angle(data_acf[:,1,:,:]) - phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1)) + phase = numpy.angle(data_acf[:,1,:,:]) +# phase = ndimage.median_filter(numpy.angle(data_acf[:,1,:,:]), size = (1,5,1)) velRad = phase*lamb/(4*numpy.pi*tSamp) #Spectral width - acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1)) - acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1)) - +# acf1 = ndimage.median_filter(numpy.abs(data_acf[:,1,:,:]), size = (1,5,1)) +# acf2 = ndimage.median_filter(numpy.abs(data_acf[:,2,:,:]), size = (1,5,1)) + acf1 = data_acf[:,1,:,:] + acf2 = data_acf[:,2,:,:] + spcWidth = (lamb/(2*numpy.sqrt(6)*numpy.pi*tSamp))*numpy.sqrt(numpy.log(acf1/acf2)) # velRad = ndimage.median_filter(velRad, size = (1,5,1)) if allData: @@ -1405,7 +2678,7 @@ class NonSpecularMeteorDetection(Operation): boolMet1 = ndimage.median_filter(boolMet1, size=(1,5,5)) #Radial velocity - boolMet2 = numpy.abs(velRad) < 30 + boolMet2 = numpy.abs(velRad) < 20 boolMet2 = ndimage.median_filter(boolMet2, (1,5,5)) #Spectral Width @@ -1432,9 +2705,9 @@ class NonSpecularMeteorDetection(Operation): # self.dataOut.data_param = data_int if len(data_param) == 0: - self.dataOut.flagNoData = True + dataOut.flagNoData = True else: - self.dataOut.data_param = data_param + dataOut.data_param = data_param def __erase_small(self, binArray, threshX, threshY): labarray, numfeat = ndimage.measurements.label(binArray) @@ -1860,7 +3133,7 @@ class SMDetection(Operation): if (indDNthresh.size > 0): indEnd = indDNthresh[0] - 1 - indInit = indUPthresh[j] if isinstance(indUPthresh[j], (int, float)) else indUPthresh[j][0] ##CHECK!!!! + indInit = indUPthresh[j] meteor = powerAux[indInit:indEnd + 1] indPeak = meteor.argmax() + indInit @@ -1915,19 +3188,19 @@ class SMDetection(Operation): indSides = pairsarray[:,1] pairslist1 = list(pairslist) - pairslist1.append((0,4)) - pairslist1.append((1,3)) + pairslist1.append((0,1)) + pairslist1.append((3,4)) listMeteors1 = [] listPowerSeries = [] listVoltageSeries = [] #volts has the war data - if frequency == 30.175e6: + if frequency == 30e6: timeLag = 45*10**-3 else: timeLag = 15*10**-3 - lag = int(numpy.ceil(timeLag/timeInterval)) + lag = numpy.ceil(timeLag/timeInterval) for i in range(len(listMeteors)): @@ -1935,10 +3208,10 @@ class SMDetection(Operation): meteorAux = numpy.zeros(16) #Loading meteor Data (mHeight, mStart, mPeak, mEnd) - mHeight = int(listMeteors[i][0]) - mStart = int(listMeteors[i][1]) - mPeak = int(listMeteors[i][2]) - mEnd = int(listMeteors[i][3]) + mHeight = listMeteors[i][0] + mStart = listMeteors[i][1] + mPeak = listMeteors[i][2] + mEnd = listMeteors[i][3] #get the volt data between the start and end times of the meteor meteorVolts = volts[:,mStart:mEnd+1,mHeight] @@ -2027,7 +3300,7 @@ class SMDetection(Operation): threshError = 10 #Depending if it is 30 or 50 MHz - if frequency == 30.175e6: + if frequency == 30e6: timeLag = 45*10**-3 else: timeLag = 15*10**-3 @@ -2087,14 +3360,14 @@ class SMDetection(Operation): def __getRadialVelocity(self, listMeteors, listVolts, radialStdThresh, pairslist, timeInterval): pairslist1 = list(pairslist) - pairslist1.append((0,4)) - pairslist1.append((1,3)) + pairslist1.append((0,1)) + pairslist1.append((3,4)) numPairs = len(pairslist1) #Time Lag timeLag = 45*10**-3 c = 3e8 lag = numpy.ceil(timeLag/timeInterval) - freq = 30.175e6 + freq = 30e6 listMeteors1 = [] @@ -2115,7 +3388,7 @@ class SMDetection(Operation): #Method 2 slopes = numpy.zeros(numPairs) time = numpy.array([-2,-1,1,2])*timeInterval - angAllCCF = numpy.angle(allCCFs[:,[0,4,2,3],0]) + angAllCCF = numpy.angle(allCCFs[:,[0,1,3,4],0]) #Correct phases derPhaseCCF = angAllCCF[:,1:] - angAllCCF[:,0:-1] @@ -2240,11 +3513,11 @@ class SMPhaseCalibration(Operation): for i in range(len(pairs)): pairi = pairs[i] - - phip3 = phases[:,pairi[1]] - d3 = d[pairi[1]] - phip2 = phases[:,pairi[0]] - d2 = d[pairi[0]] + + phip3 = phases[:,pairi[0]] + d3 = d[pairi[0]] + phip2 = phases[:,pairi[1]] + d2 = d[pairi[1]] #Calculating gamma # jdcos = alp1/(k*d1) # jgamma = numpy.angle(numpy.exp(1j*(d0*alp1/d1 - alp0))) @@ -2257,7 +3530,7 @@ class SMPhaseCalibration(Operation): jgammaArray = numpy.hstack((jgamma,jgamma+0.5*numpy.pi,jgamma-0.5*numpy.pi)) #Histogram - nBins = 64.0 + nBins = 64 rmin = -0.5*numpy.pi rmax = 0.5*numpy.pi phaseHisto = numpy.histogram(jgammaArray, bins=nBins, range=(rmin,rmax)) @@ -2299,16 +3572,16 @@ class SMPhaseCalibration(Operation): def __getPhases(self, azimuth, h, pairsList, d, gammas, meteorsArray): meteorOps = SMOperations() nchan = 4 - pairx = pairsList[0] - pairy = pairsList[1] + pairx = pairsList[0] #x es 0 + pairy = pairsList[1] #y es 1 center_xangle = 0 center_yangle = 0 range_angle = numpy.array([10*numpy.pi,numpy.pi,numpy.pi/2,numpy.pi/4]) ntimes = len(range_angle) - - nstepsx = 20.0 - nstepsy = 20.0 - + + nstepsx = 20 + nstepsy = 20 + for iz in range(ntimes): min_xangle = -range_angle[iz]/2 + center_xangle max_xangle = range_angle[iz]/2 + center_xangle @@ -2327,14 +3600,28 @@ class SMPhaseCalibration(Operation): # Iterations looking for the offset for iy in range(int(nstepsy)): for ix in range(int(nstepsx)): - jph[pairy[1]] = alpha_y[iy] - jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]] + d3 = d[pairsList[1][0]] + d2 = d[pairsList[1][1]] + d5 = d[pairsList[0][0]] + d4 = d[pairsList[0][1]] + + alp2 = alpha_y[iy] #gamma 1 + alp4 = alpha_x[ix] #gamma 0 + + alp3 = -alp2*d3/d2 - gammas[1] + alp5 = -alp4*d5/d4 - gammas[0] +# jph[pairy[1]] = alpha_y[iy] +# jph[pairy[0]] = -gammas[1] - alpha_y[iy]*d[pairy[1]]/d[pairy[0]] - jph[pairx[1]] = alpha_x[ix] - jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]] - +# jph[pairx[1]] = alpha_x[ix] +# jph[pairx[0]] = -gammas[0] - alpha_x[ix]*d[pairx[1]]/d[pairx[0]] + jph[pairsList[0][1]] = alp4 + jph[pairsList[0][0]] = alp5 + jph[pairsList[1][0]] = alp3 + jph[pairsList[1][1]] = alp2 jph_array[:,ix,iy] = jph - +# d = [2.0,2.5,2.5,2.0] + #falta chequear si va a leer bien los meteoros meteorsArray1 = meteorOps.getMeteorParams(meteorsArray, azimuth, h, pairsList, d, jph) error = meteorsArray1[:,-1] ind1 = numpy.where(error==0)[0] @@ -2383,14 +3670,26 @@ class SMPhaseCalibration(Operation): k = 2*numpy.pi/lamb azimuth = 0 h = (hmin, hmax) - pairs = ((0,1),(2,3)) - +# pairs = ((0,1),(2,3)) #Estrella +# pairs = ((1,0),(2,3)) #T + if channelPositions is None: # channelPositions = [(2.5,0), (0,2.5), (0,0), (0,4.5), (-2,0)] #T channelPositions = [(4.5,2), (2,4.5), (2,2), (2,0), (0,2)] #Estrella meteorOps = SMOperations() pairslist0, distances = meteorOps.getPhasePairs(channelPositions) + #Checking correct order of pairs + pairs = [] + if distances[1] > distances[0]: + pairs.append((1,0)) + else: + pairs.append((0,1)) + + if distances[3] > distances[2]: + pairs.append((3,2)) + else: + pairs.append((2,3)) # distances1 = [-distances[0]*lamb, distances[1]*lamb, -distances[2]*lamb, distances[3]*lamb] meteorsArray = self.__buffer @@ -2409,7 +3708,6 @@ class SMPhaseCalibration(Operation): phasesOff = phasesOff.reshape((1,phasesOff.size)) dataOut.data_output = -phasesOff dataOut.flagNoData = False - dataOut.channelList = pairslist0 self.__buffer = None @@ -2541,8 +3839,8 @@ class SMOperations(): hCorr = hi[ind_h, :] ind_hCorr = numpy.where(numpy.logical_and(hi > minHeight, hi < maxHeight)) - - hCorr = hi[ind_hCorr] + + hCorr = hi[ind_hCorr][:len(ind_h)] heights[ind_h] = hCorr #Setting Error diff --git a/schainpy/model/proc/jroproc_spectra.py b/schainpy/model/proc/jroproc_spectra.py index 9ccc91e..0c84cac 100644 --- a/schainpy/model/proc/jroproc_spectra.py +++ b/schainpy/model/proc/jroproc_spectra.py @@ -1,15 +1,18 @@ +import itertools + import numpy from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jrodata import Spectra from schainpy.model.data.jrodata import hildebrand_sekhon + class SpectraProc(ProcessingUnit): - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + self.buffer = None self.firstdatatime = None self.profIndex = 0 @@ -18,684 +21,730 @@ class SpectraProc(ProcessingUnit): self.id_max = None def __updateSpecFromVoltage(self): - + self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + try: + self.dataOut.processingHeaderObj = self.dataIn.processingHeaderObj.copy() + except: + pass self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy() self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy() self.dataOut.channelList = self.dataIn.channelList self.dataOut.heightList = self.dataIn.heightList - self.dataOut.dtype = numpy.dtype([('real',' maxHei): - raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei) - + raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % ( + minHei, maxHei) + if (minHei < self.dataOut.heightList[0]): minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]): maxHei = self.dataOut.heightList[-1] minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: maxIndex = len(heights) self.selectHeightsByIndex(minIndex, maxIndex) - + return 1 - def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None): - newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex]) - + def getBeaconSignal(self, tauindex=0, channelindex=0, hei_ref=None): + newheis = numpy.where( + self.dataOut.heightList > self.dataOut.radarControllerHeaderObj.Taus[tauindex]) + if hei_ref != None: - newheis = numpy.where(self.dataOut.heightList>hei_ref) - + newheis = numpy.where(self.dataOut.heightList > hei_ref) + minIndex = min(newheis[0]) maxIndex = max(newheis[0]) - data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] - heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1] + heightList = self.dataOut.heightList[minIndex:maxIndex + 1] + # determina indices - nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0])) - avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0)) + nheis = int(self.dataOut.radarControllerHeaderObj.txB / + (self.dataOut.heightList[1] - self.dataOut.heightList[0])) + avg_dB = 10 * \ + numpy.log10(numpy.sum(data_spc[channelindex, :, :], axis=0)) beacon_dB = numpy.sort(avg_dB)[-nheis:] beacon_heiIndexList = [] for val in avg_dB.tolist(): if val >= beacon_dB[0]: beacon_heiIndexList.append(avg_dB.tolist().index(val)) - + #data_spc = data_spc[:,:,beacon_heiIndexList] data_cspc = None if self.dataOut.data_cspc is not None: - data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] + data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1] #data_cspc = data_cspc[:,:,beacon_heiIndexList] - + data_dc = None if self.dataOut.data_dc is not None: - data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] + data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1] #data_dc = data_dc[:,beacon_heiIndexList] - + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc self.dataOut.heightList = heightList self.dataOut.beacon_heiIndexList = beacon_heiIndexList - + return 1 - - + def selectHeightsByIndex(self, minIndex, maxIndex): """ Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango minIndex <= index <= maxIndex - + Input: - minIndex : valor de indice minimo de altura a considerar + minIndex : valor de indice minimo de altura a considerar maxIndex : valor de indice maximo de altura a considerar - + Affected: self.dataOut.data_spc self.dataOut.data_cspc self.dataOut.data_dc self.dataOut.heightList - + Return: 1 si el metodo se ejecuto con exito caso contrario devuelve 0 """ - + if (minIndex < 0) or (minIndex > maxIndex): - raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex) - + raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % ( + minIndex, maxIndex) + if (maxIndex >= self.dataOut.nHeights): - maxIndex = self.dataOut.nHeights-1 + maxIndex = self.dataOut.nHeights - 1 + + # Spectra + data_spc = self.dataOut.data_spc[:, :, minIndex:maxIndex + 1] - #Spectra - data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] - data_cspc = None if self.dataOut.data_cspc is not None: - data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] - + data_cspc = self.dataOut.data_cspc[:, :, minIndex:maxIndex + 1] + data_dc = None if self.dataOut.data_dc is not None: - data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] - + data_dc = self.dataOut.data_dc[:, minIndex:maxIndex + 1] + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc - - self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + + self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex + 1] + return 1 - - def removeDC(self, mode = 2): + + def removeDC(self, mode=2): jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc - - + num_chan = jspectra.shape[0] num_hei = jspectra.shape[2] - + if jcspectra is not None: jcspectraExist = True num_pairs = jcspectra.shape[0] - else: jcspectraExist = False - - freq_dc = jspectra.shape[1]/2 - ind_vel = numpy.array([-2,-1,1,2]) + freq_dc - - if ind_vel[0]<0: - ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof - - if mode == 1: - jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION - + else: + jcspectraExist = False + + freq_dc = jspectra.shape[1] / 2 + ind_vel = numpy.array([-2, -1, 1, 2]) + freq_dc + + if ind_vel[0] < 0: + ind_vel[range(0, 1)] = ind_vel[range(0, 1)] + self.num_prof + + if mode == 1: + jspectra[:, freq_dc, :] = ( + jspectra[:, ind_vel[1], :] + jspectra[:, ind_vel[2], :]) / 2 # CORRECCION + if jcspectraExist: - jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2 - + jcspectra[:, freq_dc, :] = ( + jcspectra[:, ind_vel[1], :] + jcspectra[:, ind_vel[2], :]) / 2 + if mode == 2: - - vel = numpy.array([-2,-1,1,2]) - xx = numpy.zeros([4,4]) - + + vel = numpy.array([-2, -1, 1, 2]) + xx = numpy.zeros([4, 4]) + for fil in range(4): - xx[fil,:] = vel[fil]**numpy.asarray(range(4)) - + xx[fil, :] = vel[fil]**numpy.asarray(range(4)) + xx_inv = numpy.linalg.inv(xx) - xx_aux = xx_inv[0,:] - + xx_aux = xx_inv[0, :] + for ich in range(num_chan): - yy = jspectra[ich,ind_vel,:] - jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy) + yy = jspectra[ich, ind_vel, :] + jspectra[ich, freq_dc, :] = numpy.dot(xx_aux, yy) - junkid = jspectra[ich,freq_dc,:]<=0 + junkid = jspectra[ich, freq_dc, :] <= 0 cjunkid = sum(junkid) - + if cjunkid.any(): - jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2 - + jspectra[ich, freq_dc, junkid.nonzero()] = ( + jspectra[ich, ind_vel[1], junkid] + jspectra[ich, ind_vel[2], junkid]) / 2 + if jcspectraExist: for ip in range(num_pairs): - yy = jcspectra[ip,ind_vel,:] - jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy) - - + yy = jcspectra[ip, ind_vel, :] + jcspectra[ip, freq_dc, :] = numpy.dot(xx_aux, yy) + self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - - def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None): - + + def removeInterference(self, interf=2, hei_interf=None, nhei_interf=None, offhei_interf=None): + jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc jnoise = self.dataOut.getNoise() num_incoh = self.dataOut.nIncohInt - - num_channel = jspectra.shape[0] - num_prof = jspectra.shape[1] - num_hei = jspectra.shape[2] - - #hei_interf + + num_channel = jspectra.shape[0] + num_prof = jspectra.shape[1] + num_hei = jspectra.shape[2] + + # hei_interf if hei_interf is None: - count_hei = num_hei/2 #Como es entero no importa + count_hei = num_hei / 2 # Como es entero no importa hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei hei_interf = numpy.asarray(hei_interf)[0] - #nhei_interf + # nhei_interf if (nhei_interf == None): nhei_interf = 5 if (nhei_interf < 1): - nhei_interf = 1 + nhei_interf = 1 if (nhei_interf > count_hei): nhei_interf = count_hei - if (offhei_interf == None): + if (offhei_interf == None): offhei_interf = 0 - + ind_hei = range(num_hei) -# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 +# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1 - mask_prof = numpy.asarray(range(num_prof)) + mask_prof = numpy.asarray(range(num_prof)) num_mask_prof = mask_prof.size - comp_mask_prof = [0, num_prof/2] - - - #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal + comp_mask_prof = [0, num_prof / 2] + + # noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal if (jnoise.size < num_channel or numpy.isnan(jnoise).any()): jnoise = numpy.nan noise_exist = jnoise[0] < numpy.Inf - - #Subrutina de Remocion de la Interferencia + + # Subrutina de Remocion de la Interferencia for ich in range(num_channel): - #Se ordena los espectros segun su potencia (menor a mayor) - power = jspectra[ich,mask_prof,:] - power = power[:,hei_interf] - power = power.sum(axis = 0) + # Se ordena los espectros segun su potencia (menor a mayor) + power = jspectra[ich, mask_prof, :] + power = power[:, hei_interf] + power = power.sum(axis=0) psort = power.ravel().argsort() - - #Se estima la interferencia promedio en los Espectros de Potencia empleando - junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]] - + + # Se estima la interferencia promedio en los Espectros de Potencia empleando + junkspc_interf = jspectra[ich, :, hei_interf[psort[range( + offhei_interf, nhei_interf + offhei_interf)]]] + if noise_exist: - # tmp_noise = jnoise[ich] / num_prof + # tmp_noise = jnoise[ich] / num_prof tmp_noise = jnoise[ich] junkspc_interf = junkspc_interf - tmp_noise #junkspc_interf[:,comp_mask_prof] = 0 - - jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf + + jspc_interf = junkspc_interf.sum(axis=0) / nhei_interf jspc_interf = jspc_interf.transpose() - #Calculando el espectro de interferencia promedio - noiseid = numpy.where(jspc_interf <= tmp_noise/ numpy.sqrt(num_incoh)) + # Calculando el espectro de interferencia promedio + noiseid = numpy.where( + jspc_interf <= tmp_noise / numpy.sqrt(num_incoh)) noiseid = noiseid[0] cnoiseid = noiseid.size - interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh)) + interfid = numpy.where( + jspc_interf > tmp_noise / numpy.sqrt(num_incoh)) interfid = interfid[0] cinterfid = interfid.size - - if (cnoiseid > 0): jspc_interf[noiseid] = 0 - - #Expandiendo los perfiles a limpiar + + if (cnoiseid > 0): + jspc_interf[noiseid] = 0 + + # Expandiendo los perfiles a limpiar if (cinterfid > 0): - new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof - new_interfid = numpy.asarray(new_interfid) + new_interfid = ( + numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof) % num_prof + new_interfid = numpy.asarray(new_interfid) new_interfid = {x for x in new_interfid} new_interfid = numpy.array(list(new_interfid)) new_cinterfid = new_interfid.size - else: new_cinterfid = 0 - + else: + new_cinterfid = 0 + for ip in range(new_cinterfid): - ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort() - jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]] - - - jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices - - #Removiendo la interferencia del punto de mayor interferencia + ind = junkspc_interf[:, new_interfid[ip]].ravel().argsort() + jspc_interf[new_interfid[ip] + ] = junkspc_interf[ind[nhei_interf / 2], new_interfid[ip]] + + jspectra[ich, :, ind_hei] = jspectra[ich, :, + ind_hei] - jspc_interf # Corregir indices + + # Removiendo la interferencia del punto de mayor interferencia ListAux = jspc_interf[mask_prof].tolist() maxid = ListAux.index(max(ListAux)) - - + if cinterfid > 0: - for ip in range(cinterfid*(interf == 2) - 1): - ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero() + for ip in range(cinterfid * (interf == 2) - 1): + ind = (jspectra[ich, interfid[ip], :] < tmp_noise * + (1 + 1 / numpy.sqrt(num_incoh))).nonzero() cind = len(ind) - + if (cind > 0): - jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh)) - - ind = numpy.array([-2,-1,1,2]) - xx = numpy.zeros([4,4]) - + jspectra[ich, interfid[ip], ind] = tmp_noise * \ + (1 + (numpy.random.uniform(cind) - 0.5) / + numpy.sqrt(num_incoh)) + + ind = numpy.array([-2, -1, 1, 2]) + xx = numpy.zeros([4, 4]) + for id1 in range(4): - xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx[:, id1] = ind[id1]**numpy.asarray(range(4)) + xx_inv = numpy.linalg.inv(xx) - xx = xx_inv[:,0] - ind = (ind + maxid + num_mask_prof)%num_mask_prof - yy = jspectra[ich,mask_prof[ind],:] - jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - - - indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero() - jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh)) - - #Remocion de Interferencia en el Cross Spectra - if jcspectra is None: return jspectra, jcspectra - num_pairs = jcspectra.size/(num_prof*num_hei) + xx = xx_inv[:, 0] + ind = (ind + maxid + num_mask_prof) % num_mask_prof + yy = jspectra[ich, mask_prof[ind], :] + jspectra[ich, mask_prof[maxid], :] = numpy.dot( + yy.transpose(), xx) + + indAux = (jspectra[ich, :, :] < tmp_noise * + (1 - 1 / numpy.sqrt(num_incoh))).nonzero() + jspectra[ich, indAux[0], indAux[1]] = tmp_noise * \ + (1 - 1 / numpy.sqrt(num_incoh)) + + # Remocion de Interferencia en el Cross Spectra + if jcspectra is None: + return jspectra, jcspectra + num_pairs = jcspectra.size / (num_prof * num_hei) jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei) - + for ip in range(num_pairs): - + #------------------------------------------- - - cspower = numpy.abs(jcspectra[ip,mask_prof,:]) - cspower = cspower[:,hei_interf] - cspower = cspower.sum(axis = 0) - + + cspower = numpy.abs(jcspectra[ip, mask_prof, :]) + cspower = cspower[:, hei_interf] + cspower = cspower.sum(axis=0) + cspsort = cspower.ravel().argsort() - junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]] + junkcspc_interf = jcspectra[ip, :, hei_interf[cspsort[range( + offhei_interf, nhei_interf + offhei_interf)]]] junkcspc_interf = junkcspc_interf.transpose() - jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf - + jcspc_interf = junkcspc_interf.sum(axis=1) / nhei_interf + ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort() - - median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) - median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) - junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag) - + + median_real = numpy.median(numpy.real( + junkcspc_interf[mask_prof[ind[range(3 * num_prof / 4)]], :])) + median_imag = numpy.median(numpy.imag( + junkcspc_interf[mask_prof[ind[range(3 * num_prof / 4)]], :])) + junkcspc_interf[comp_mask_prof, :] = numpy.complex( + median_real, median_imag) + for iprof in range(num_prof): - ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort() - jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]] - - #Removiendo la Interferencia - jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf - + ind = numpy.abs(junkcspc_interf[iprof, :]).ravel().argsort() + jcspc_interf[iprof] = junkcspc_interf[iprof, + ind[nhei_interf / 2]] + + # Removiendo la Interferencia + jcspectra[ip, :, ind_hei] = jcspectra[ip, + :, ind_hei] - jcspc_interf + ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist() maxid = ListAux.index(max(ListAux)) - - ind = numpy.array([-2,-1,1,2]) - xx = numpy.zeros([4,4]) - + + ind = numpy.array([-2, -1, 1, 2]) + xx = numpy.zeros([4, 4]) + for id1 in range(4): - xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx[:, id1] = ind[id1]**numpy.asarray(range(4)) + xx_inv = numpy.linalg.inv(xx) - xx = xx_inv[:,0] - - ind = (ind + maxid + num_mask_prof)%num_mask_prof - yy = jcspectra[ip,mask_prof[ind],:] - jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - - #Guardar Resultados + xx = xx_inv[:, 0] + + ind = (ind + maxid + num_mask_prof) % num_mask_prof + yy = jcspectra[ip, mask_prof[ind], :] + jcspectra[ip, mask_prof[maxid], :] = numpy.dot(yy.transpose(), xx) + + # Guardar Resultados self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - + def setRadarFrequency(self, frequency=None): - + if frequency != None: self.dataOut.frequency = frequency - + return 1 - - def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): - #validacion de rango + + def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): + # validacion de rango if minHei == None: minHei = self.dataOut.heightList[0] - + if maxHei == None: maxHei = self.dataOut.heightList[-1] - + if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei): - print 'minHei: %.2f is out of the heights range'%(minHei) - print 'minHei is setting to %.2f'%(self.dataOut.heightList[0]) + print 'minHei: %.2f is out of the heights range' % (minHei) + print 'minHei is setting to %.2f' % (self.dataOut.heightList[0]) minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei): - print 'maxHei: %.2f is out of the heights range'%(maxHei) - print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1]) + print 'maxHei: %.2f is out of the heights range' % (maxHei) + print 'maxHei is setting to %.2f' % (self.dataOut.heightList[-1]) maxHei = self.dataOut.heightList[-1] - + # validacion de velocidades velrange = self.dataOut.getVelRange(1) - + if minVel == None: minVel = velrange[0] - + if maxVel == None: maxVel = velrange[-1] - + if (minVel < velrange[0]) or (minVel > maxVel): - print 'minVel: %.2f is out of the velocity range'%(minVel) - print 'minVel is setting to %.2f'%(velrange[0]) + print 'minVel: %.2f is out of the velocity range' % (minVel) + print 'minVel is setting to %.2f' % (velrange[0]) minVel = velrange[0] - + if (maxVel > velrange[-1]) or (maxVel < minVel): - print 'maxVel: %.2f is out of the velocity range'%(maxVel) - print 'maxVel is setting to %.2f'%(velrange[-1]) + print 'maxVel: %.2f is out of the velocity range' % (maxVel) + print 'maxVel is setting to %.2f' % (velrange[-1]) maxVel = velrange[-1] - - # seleccion de indices para rango + + # seleccion de indices para rango minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: maxIndex = len(heights) if (minIndex < 0) or (minIndex > maxIndex): - raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex) - + raise ValueError, "some value in (%d,%d) is not valid" % ( + minIndex, maxIndex) + if (maxIndex >= self.dataOut.nHeights): - maxIndex = self.dataOut.nHeights-1 + maxIndex = self.dataOut.nHeights - 1 # seleccion de indices para velocidades indminvel = numpy.where(velrange >= minVel) @@ -704,201 +753,200 @@ class SpectraProc(ProcessingUnit): minIndexVel = indminvel[0][0] except: minIndexVel = 0 - + try: maxIndexVel = indmaxvel[0][-1] - except: + except: maxIndexVel = len(velrange) - - #seleccion del espectro - data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1] - #estimacion de ruido + + # seleccion del espectro + data_spc = self.dataOut.data_spc[:, + minIndexVel:maxIndexVel + 1, minIndex:maxIndex + 1] + # estimacion de ruido noise = numpy.zeros(self.dataOut.nChannels) - + for channel in range(self.dataOut.nChannels): - daux = data_spc[channel,:,:] + daux = data_spc[channel, :, :] noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt) - + self.dataOut.noise_estimation = noise.copy() - + return 1 - + + class IncohInt(Operation): - - + __profIndex = 0 - __withOverapping = False - + __withOverapping = False + __byTime = False __initime = None __lastdatatime = None __integrationtime = None - + __buffer_spc = None __buffer_cspc = None __buffer_dc = None - + __dataReady = False - + __timeInterval = None - + n = None - - - - def __init__(self): - - Operation.__init__(self) + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) # self.isConfig = False - + def setup(self, n=None, timeInterval=None, overlapping=False): """ Set the parameters of the integration class. - + Inputs: - + n : Number of coherent integrations timeInterval : Time of integration. If the parameter "n" is selected this one does not work - overlapping : - + overlapping : + """ - + self.__initime = None self.__lastdatatime = 0 - + self.__buffer_spc = 0 self.__buffer_cspc = 0 self.__buffer_dc = 0 - + self.__profIndex = 0 self.__dataReady = False self.__byTime = False - + if n is None and timeInterval is None: - raise ValueError, "n or timeInterval should be specified ..." - + raise ValueError, "n or timeInterval should be specified ..." + if n is not None: self.n = int(n) else: - self.__integrationtime = int(timeInterval) #if (type(timeInterval)!=integer) -> change this line + # if (type(timeInterval)!=integer) -> change this line + self.__integrationtime = int(timeInterval) self.n = None self.__byTime = True - + def putData(self, data_spc, data_cspc, data_dc): - """ Add a profile to the __buffer_spc and increase in one the __profileIndex - + """ - + self.__buffer_spc += data_spc - + if data_cspc is None: self.__buffer_cspc = None else: self.__buffer_cspc += data_cspc - + if data_dc is None: self.__buffer_dc = None else: self.__buffer_dc += data_dc - + self.__profIndex += 1 - + return - + def pushData(self): """ Return the sum of the last profiles and the profiles used in the sum. - + Affected: - + self.__profileIndex - + """ - + data_spc = self.__buffer_spc data_cspc = self.__buffer_cspc data_dc = self.__buffer_dc n = self.__profIndex - + self.__buffer_spc = 0 self.__buffer_cspc = 0 self.__buffer_dc = 0 self.__profIndex = 0 - + return data_spc, data_cspc, data_dc, n - + def byProfiles(self, *args): - + self.__dataReady = False avgdata_spc = None avgdata_cspc = None avgdata_dc = None - + self.putData(*args) - + if self.__profIndex == self.n: - + avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData() self.n = n self.__dataReady = True - + return avgdata_spc, avgdata_cspc, avgdata_dc - + def byTime(self, datatime, *args): - + self.__dataReady = False avgdata_spc = None avgdata_cspc = None avgdata_dc = None - + self.putData(*args) - + if (datatime - self.__initime) >= self.__integrationtime: avgdata_spc, avgdata_cspc, avgdata_dc, n = self.pushData() self.n = n self.__dataReady = True - + return avgdata_spc, avgdata_cspc, avgdata_dc - + def integrate(self, datatime, *args): - + if self.__profIndex == 0: self.__initime = datatime - + if self.__byTime: - avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime(datatime, *args) + avgdata_spc, avgdata_cspc, avgdata_dc = self.byTime( + datatime, *args) else: avgdata_spc, avgdata_cspc, avgdata_dc = self.byProfiles(*args) - + if not self.__dataReady: return None, None, None, None - + return self.__initime, avgdata_spc, avgdata_cspc, avgdata_dc - + def run(self, dataOut, n=None, timeInterval=None, overlapping=False): - - if n==1: + if n == 1: return - + dataOut.flagNoData = True - + if not self.isConfig: self.setup(n, timeInterval, overlapping) self.isConfig = True - + avgdatatime, avgdata_spc, avgdata_cspc, avgdata_dc = self.integrate(dataOut.utctime, dataOut.data_spc, dataOut.data_cspc, dataOut.data_dc) - + if self.__dataReady: - + dataOut.data_spc = avgdata_spc dataOut.data_cspc = avgdata_cspc dataOut.data_dc = avgdata_dc - + dataOut.nIncohInt *= self.n dataOut.utctime = avgdatatime dataOut.flagNoData = False diff --git a/schainpy/model/proc/jroproc_spectra_acf.py b/schainpy/model/proc/jroproc_spectra_acf.py index d257d7e..4d316d2 100644 --- a/schainpy/model/proc/jroproc_spectra_acf.py +++ b/schainpy/model/proc/jroproc_spectra_acf.py @@ -5,11 +5,11 @@ from schainpy.model.data.jrodata import Spectra from schainpy.model.data.jrodata import hildebrand_sekhon class SpectraAFCProc(ProcessingUnit): - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + self.buffer = None self.firstdatatime = None self.profIndex = 0 @@ -18,102 +18,102 @@ class SpectraAFCProc(ProcessingUnit): self.id_max = None def __updateSpecFromVoltage(self): - + self.dataOut.plotting = "spectra_acf" - + self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy() self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy() self.dataOut.ippSeconds = self.dataIn.getDeltaH()*(10**-6)/0.15 - + self.dataOut.channelList = self.dataIn.channelList self.dataOut.heightList = self.dataIn.heightList self.dataOut.dtype = numpy.dtype([('real',' maxHei): raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei) - + if (minHei < self.dataOut.heightList[0]): minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]): maxHei = self.dataOut.heightList[-1] minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: maxIndex = len(heights) self.selectHeightsByIndex(minIndex, maxIndex) - + return 1 def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None): newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex]) - + if hei_ref != None: newheis = numpy.where(self.dataOut.heightList>hei_ref) - + minIndex = min(newheis[0]) maxIndex = max(newheis[0]) data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + # determina indices nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0])) avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0)) @@ -353,167 +353,167 @@ class SpectraAFCProc(ProcessingUnit): for val in avg_dB.tolist(): if val >= beacon_dB[0]: beacon_heiIndexList.append(avg_dB.tolist().index(val)) - + #data_spc = data_spc[:,:,beacon_heiIndexList] data_cspc = None if self.dataOut.data_cspc is not None: data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] #data_cspc = data_cspc[:,:,beacon_heiIndexList] - + data_dc = None if self.dataOut.data_dc is not None: data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] #data_dc = data_dc[:,beacon_heiIndexList] - + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc self.dataOut.heightList = heightList self.dataOut.beacon_heiIndexList = beacon_heiIndexList - + return 1 - - + + def selectHeightsByIndex(self, minIndex, maxIndex): """ Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango minIndex <= index <= maxIndex - + Input: - minIndex : valor de indice minimo de altura a considerar + minIndex : valor de indice minimo de altura a considerar maxIndex : valor de indice maximo de altura a considerar - + Affected: self.dataOut.data_spc self.dataOut.data_cspc self.dataOut.data_dc self.dataOut.heightList - + Return: 1 si el metodo se ejecuto con exito caso contrario devuelve 0 """ - + if (minIndex < 0) or (minIndex > maxIndex): raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex) - + if (maxIndex >= self.dataOut.nHeights): maxIndex = self.dataOut.nHeights-1 #Spectra data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] - + data_cspc = None if self.dataOut.data_cspc is not None: data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] - + data_dc = None if self.dataOut.data_dc is not None: data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] - + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc - + self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + return 1 - + def removeDC(self, mode = 2): jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc - - + + num_chan = jspectra.shape[0] num_hei = jspectra.shape[2] - + if jcspectra is not None: jcspectraExist = True num_pairs = jcspectra.shape[0] else: jcspectraExist = False - + freq_dc = jspectra.shape[1]/2 - ind_vel = numpy.array([-2,-1,1,2]) + freq_dc - + ind_vel = numpy.array([-2,-1,1,2]) + freq_dc + if ind_vel[0]<0: ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof - - if mode == 1: + + if mode == 1: jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION - + if jcspectraExist: jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2 - + if mode == 2: - + vel = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for fil in range(4): xx[fil,:] = vel[fil]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx_aux = xx_inv[0,:] - + for ich in range(num_chan): yy = jspectra[ich,ind_vel,:] jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy) junkid = jspectra[ich,freq_dc,:]<=0 cjunkid = sum(junkid) - + if cjunkid.any(): jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2 - + if jcspectraExist: for ip in range(num_pairs): yy = jcspectra[ip,ind_vel,:] jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy) - - + + self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - + def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None): - + jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc jnoise = self.dataOut.getNoise() num_incoh = self.dataOut.nIncohInt - + num_channel = jspectra.shape[0] num_prof = jspectra.shape[1] num_hei = jspectra.shape[2] - + #hei_interf if hei_interf is None: count_hei = num_hei/2 #Como es entero no importa hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei hei_interf = numpy.asarray(hei_interf)[0] - #nhei_interf + #nhei_interf if (nhei_interf == None): nhei_interf = 5 if (nhei_interf < 1): - nhei_interf = 1 + nhei_interf = 1 if (nhei_interf > count_hei): nhei_interf = count_hei - if (offhei_interf == None): + if (offhei_interf == None): offhei_interf = 0 - + ind_hei = range(num_hei) -# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 +# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1 - mask_prof = numpy.asarray(range(num_prof)) + mask_prof = numpy.asarray(range(num_prof)) num_mask_prof = mask_prof.size comp_mask_prof = [0, num_prof/2] - - + + #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal if (jnoise.size < num_channel or numpy.isnan(jnoise).any()): jnoise = numpy.nan noise_exist = jnoise[0] < numpy.Inf - + #Subrutina de Remocion de la Interferencia for ich in range(num_channel): #Se ordena los espectros segun su potencia (menor a mayor) @@ -521,16 +521,16 @@ class SpectraAFCProc(ProcessingUnit): power = power[:,hei_interf] power = power.sum(axis = 0) psort = power.ravel().argsort() - + #Se estima la interferencia promedio en los Espectros de Potencia empleando junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]] - + if noise_exist: # tmp_noise = jnoise[ich] / num_prof tmp_noise = jnoise[ich] junkspc_interf = junkspc_interf - tmp_noise #junkspc_interf[:,comp_mask_prof] = 0 - + jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf jspc_interf = jspc_interf.transpose() #Calculando el espectro de interferencia promedio @@ -540,164 +540,164 @@ class SpectraAFCProc(ProcessingUnit): interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh)) interfid = interfid[0] cinterfid = interfid.size - + if (cnoiseid > 0): jspc_interf[noiseid] = 0 - + #Expandiendo los perfiles a limpiar if (cinterfid > 0): new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof - new_interfid = numpy.asarray(new_interfid) + new_interfid = numpy.asarray(new_interfid) new_interfid = {x for x in new_interfid} new_interfid = numpy.array(list(new_interfid)) new_cinterfid = new_interfid.size else: new_cinterfid = 0 - + for ip in range(new_cinterfid): - ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort() + ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort() jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]] - - + + jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices - + #Removiendo la interferencia del punto de mayor interferencia ListAux = jspc_interf[mask_prof].tolist() maxid = ListAux.index(max(ListAux)) - - + + if cinterfid > 0: for ip in range(cinterfid*(interf == 2) - 1): ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero() cind = len(ind) - + if (cind > 0): jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh)) - + ind = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for id1 in range(4): xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx = xx_inv[:,0] ind = (ind + maxid + num_mask_prof)%num_mask_prof yy = jspectra[ich,mask_prof[ind],:] jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - - - indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero() + + + indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero() jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh)) - + #Remocion de Interferencia en el Cross Spectra if jcspectra is None: return jspectra, jcspectra num_pairs = jcspectra.size/(num_prof*num_hei) jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei) - + for ip in range(num_pairs): - + #------------------------------------------- - + cspower = numpy.abs(jcspectra[ip,mask_prof,:]) cspower = cspower[:,hei_interf] cspower = cspower.sum(axis = 0) - + cspsort = cspower.ravel().argsort() junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]] junkcspc_interf = junkcspc_interf.transpose() jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf - + ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort() - + median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag) - + for iprof in range(num_prof): ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort() jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]] - + #Removiendo la Interferencia jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf - + ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist() maxid = ListAux.index(max(ListAux)) - + ind = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for id1 in range(4): xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx = xx_inv[:,0] - + ind = (ind + maxid + num_mask_prof)%num_mask_prof yy = jcspectra[ip,mask_prof[ind],:] jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - + #Guardar Resultados self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - + def setRadarFrequency(self, frequency=None): - + if frequency != None: self.dataOut.frequency = frequency - + return 1 - - def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): + + def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): #validacion de rango if minHei == None: minHei = self.dataOut.heightList[0] - + if maxHei == None: maxHei = self.dataOut.heightList[-1] - + if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei): print 'minHei: %.2f is out of the heights range'%(minHei) print 'minHei is setting to %.2f'%(self.dataOut.heightList[0]) minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei): print 'maxHei: %.2f is out of the heights range'%(maxHei) print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1]) maxHei = self.dataOut.heightList[-1] - + # validacion de velocidades velrange = self.dataOut.getVelRange(1) - + if minVel == None: minVel = velrange[0] - + if maxVel == None: maxVel = velrange[-1] - + if (minVel < velrange[0]) or (minVel > maxVel): print 'minVel: %.2f is out of the velocity range'%(minVel) print 'minVel is setting to %.2f'%(velrange[0]) minVel = velrange[0] - + if (maxVel > velrange[-1]) or (maxVel < minVel): print 'maxVel: %.2f is out of the velocity range'%(maxVel) print 'maxVel is setting to %.2f'%(velrange[-1]) maxVel = velrange[-1] - - # seleccion de indices para rango + + # seleccion de indices para rango minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: @@ -705,7 +705,7 @@ class SpectraAFCProc(ProcessingUnit): if (minIndex < 0) or (minIndex > maxIndex): raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex) - + if (maxIndex >= self.dataOut.nHeights): maxIndex = self.dataOut.nHeights-1 @@ -716,21 +716,21 @@ class SpectraAFCProc(ProcessingUnit): minIndexVel = indminvel[0][0] except: minIndexVel = 0 - + try: maxIndexVel = indmaxvel[0][-1] - except: + except: maxIndexVel = len(velrange) - + #seleccion del espectro data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1] #estimacion de ruido noise = numpy.zeros(self.dataOut.nChannels) - + for channel in range(self.dataOut.nChannels): daux = data_spc[channel,:,:] noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt) - + self.dataOut.noise_estimation = noise.copy() - - return 1 \ No newline at end of file + + return 1 diff --git a/schainpy/model/proc/jroproc_spectra_lags.py b/schainpy/model/proc/jroproc_spectra_lags.py index 19ed0c5..fa64eae 100644 --- a/schainpy/model/proc/jroproc_spectra_lags.py +++ b/schainpy/model/proc/jroproc_spectra_lags.py @@ -5,11 +5,11 @@ from schainpy.model.data.jrodata import Spectra from schainpy.model.data.jrodata import hildebrand_sekhon class SpectraLagsProc(ProcessingUnit): - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + self.__input_buffer = None self.firstdatatime = None self.profIndex = 0 @@ -17,109 +17,109 @@ class SpectraLagsProc(ProcessingUnit): self.id_min = None self.id_max = None self.__codeIndex = 0 - + self.__lags_buffer = None def __updateSpecFromVoltage(self): - + self.dataOut.plotting = "spectra_lags" self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + self.dataOut.radarControllerHeaderObj = self.dataIn.radarControllerHeaderObj.copy() self.dataOut.systemHeaderObj = self.dataIn.systemHeaderObj.copy() self.dataOut.ippSeconds = self.dataIn.getDeltaH()*(10**-6)/0.15 - + self.dataOut.channelList = self.dataIn.channelList self.dataOut.heightList = self.dataIn.heightList self.dataOut.dtype = numpy.dtype([('real',' maxHei): raise ValueError, "Error selecting heights: Height range (%d,%d) is not valid" % (minHei, maxHei) - + if (minHei < self.dataOut.heightList[0]): minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]): maxHei = self.dataOut.heightList[-1] minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: maxIndex = len(heights) self.selectHeightsByIndex(minIndex, maxIndex) - + return 1 def getBeaconSignal(self, tauindex = 0, channelindex = 0, hei_ref=None): newheis = numpy.where(self.dataOut.heightList>self.dataOut.radarControllerHeaderObj.Taus[tauindex]) - + if hei_ref != None: newheis = numpy.where(self.dataOut.heightList>hei_ref) - + minIndex = min(newheis[0]) maxIndex = max(newheis[0]) data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + # determina indices nheis = int(self.dataOut.radarControllerHeaderObj.txB/(self.dataOut.heightList[1]-self.dataOut.heightList[0])) avg_dB = 10*numpy.log10(numpy.sum(data_spc[channelindex,:,:],axis=0)) @@ -356,167 +356,167 @@ class SpectraLagsProc(ProcessingUnit): for val in avg_dB.tolist(): if val >= beacon_dB[0]: beacon_heiIndexList.append(avg_dB.tolist().index(val)) - + #data_spc = data_spc[:,:,beacon_heiIndexList] data_cspc = None if self.dataOut.data_cspc is not None: data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] #data_cspc = data_cspc[:,:,beacon_heiIndexList] - + data_dc = None if self.dataOut.data_dc is not None: data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] #data_dc = data_dc[:,beacon_heiIndexList] - + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc self.dataOut.heightList = heightList self.dataOut.beacon_heiIndexList = beacon_heiIndexList - + return 1 - - + + def selectHeightsByIndex(self, minIndex, maxIndex): """ Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango minIndex <= index <= maxIndex - + Input: - minIndex : valor de indice minimo de altura a considerar + minIndex : valor de indice minimo de altura a considerar maxIndex : valor de indice maximo de altura a considerar - + Affected: self.dataOut.data_spc self.dataOut.data_cspc self.dataOut.data_dc self.dataOut.heightList - + Return: 1 si el metodo se ejecuto con exito caso contrario devuelve 0 """ - + if (minIndex < 0) or (minIndex > maxIndex): raise ValueError, "Error selecting heights: Index range (%d,%d) is not valid" % (minIndex, maxIndex) - + if (maxIndex >= self.dataOut.nHeights): maxIndex = self.dataOut.nHeights-1 #Spectra data_spc = self.dataOut.data_spc[:,:,minIndex:maxIndex+1] - + data_cspc = None if self.dataOut.data_cspc is not None: data_cspc = self.dataOut.data_cspc[:,:,minIndex:maxIndex+1] - + data_dc = None if self.dataOut.data_dc is not None: data_dc = self.dataOut.data_dc[:,minIndex:maxIndex+1] - + self.dataOut.data_spc = data_spc self.dataOut.data_cspc = data_cspc self.dataOut.data_dc = data_dc - + self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex+1] - + return 1 - + def removeDC(self, mode = 2): jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc - - + + num_chan = jspectra.shape[0] num_hei = jspectra.shape[2] - + if jcspectra is not None: jcspectraExist = True num_pairs = jcspectra.shape[0] else: jcspectraExist = False - + freq_dc = jspectra.shape[1]/2 - ind_vel = numpy.array([-2,-1,1,2]) + freq_dc - + ind_vel = numpy.array([-2,-1,1,2]) + freq_dc + if ind_vel[0]<0: ind_vel[range(0,1)] = ind_vel[range(0,1)] + self.num_prof - - if mode == 1: + + if mode == 1: jspectra[:,freq_dc,:] = (jspectra[:,ind_vel[1],:] + jspectra[:,ind_vel[2],:])/2 #CORRECCION - + if jcspectraExist: jcspectra[:,freq_dc,:] = (jcspectra[:,ind_vel[1],:] + jcspectra[:,ind_vel[2],:])/2 - + if mode == 2: - + vel = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for fil in range(4): xx[fil,:] = vel[fil]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx_aux = xx_inv[0,:] - + for ich in range(num_chan): yy = jspectra[ich,ind_vel,:] jspectra[ich,freq_dc,:] = numpy.dot(xx_aux,yy) junkid = jspectra[ich,freq_dc,:]<=0 cjunkid = sum(junkid) - + if cjunkid.any(): jspectra[ich,freq_dc,junkid.nonzero()] = (jspectra[ich,ind_vel[1],junkid] + jspectra[ich,ind_vel[2],junkid])/2 - + if jcspectraExist: for ip in range(num_pairs): yy = jcspectra[ip,ind_vel,:] jcspectra[ip,freq_dc,:] = numpy.dot(xx_aux,yy) - - + + self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - + def removeInterference(self, interf = 2,hei_interf = None, nhei_interf = None, offhei_interf = None): - + jspectra = self.dataOut.data_spc jcspectra = self.dataOut.data_cspc jnoise = self.dataOut.getNoise() num_incoh = self.dataOut.nIncohInt - + num_channel = jspectra.shape[0] num_prof = jspectra.shape[1] num_hei = jspectra.shape[2] - + #hei_interf if hei_interf is None: count_hei = num_hei/2 #Como es entero no importa hei_interf = numpy.asmatrix(range(count_hei)) + num_hei - count_hei hei_interf = numpy.asarray(hei_interf)[0] - #nhei_interf + #nhei_interf if (nhei_interf == None): nhei_interf = 5 if (nhei_interf < 1): - nhei_interf = 1 + nhei_interf = 1 if (nhei_interf > count_hei): nhei_interf = count_hei - if (offhei_interf == None): + if (offhei_interf == None): offhei_interf = 0 - + ind_hei = range(num_hei) -# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 +# mask_prof = numpy.asarray(range(num_prof - 2)) + 1 # mask_prof[range(num_prof/2 - 1,len(mask_prof))] += 1 - mask_prof = numpy.asarray(range(num_prof)) + mask_prof = numpy.asarray(range(num_prof)) num_mask_prof = mask_prof.size comp_mask_prof = [0, num_prof/2] - - + + #noise_exist: Determina si la variable jnoise ha sido definida y contiene la informacion del ruido de cada canal if (jnoise.size < num_channel or numpy.isnan(jnoise).any()): jnoise = numpy.nan noise_exist = jnoise[0] < numpy.Inf - + #Subrutina de Remocion de la Interferencia for ich in range(num_channel): #Se ordena los espectros segun su potencia (menor a mayor) @@ -524,16 +524,16 @@ class SpectraLagsProc(ProcessingUnit): power = power[:,hei_interf] power = power.sum(axis = 0) psort = power.ravel().argsort() - + #Se estima la interferencia promedio en los Espectros de Potencia empleando junkspc_interf = jspectra[ich,:,hei_interf[psort[range(offhei_interf, nhei_interf + offhei_interf)]]] - + if noise_exist: # tmp_noise = jnoise[ich] / num_prof tmp_noise = jnoise[ich] junkspc_interf = junkspc_interf - tmp_noise #junkspc_interf[:,comp_mask_prof] = 0 - + jspc_interf = junkspc_interf.sum(axis = 0) / nhei_interf jspc_interf = jspc_interf.transpose() #Calculando el espectro de interferencia promedio @@ -543,164 +543,164 @@ class SpectraLagsProc(ProcessingUnit): interfid = numpy.where(jspc_interf > tmp_noise/ numpy.sqrt(num_incoh)) interfid = interfid[0] cinterfid = interfid.size - + if (cnoiseid > 0): jspc_interf[noiseid] = 0 - + #Expandiendo los perfiles a limpiar if (cinterfid > 0): new_interfid = (numpy.r_[interfid - 1, interfid, interfid + 1] + num_prof)%num_prof - new_interfid = numpy.asarray(new_interfid) + new_interfid = numpy.asarray(new_interfid) new_interfid = {x for x in new_interfid} new_interfid = numpy.array(list(new_interfid)) new_cinterfid = new_interfid.size else: new_cinterfid = 0 - + for ip in range(new_cinterfid): - ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort() + ind = junkspc_interf[:,new_interfid[ip]].ravel().argsort() jspc_interf[new_interfid[ip]] = junkspc_interf[ind[nhei_interf/2],new_interfid[ip]] - - + + jspectra[ich,:,ind_hei] = jspectra[ich,:,ind_hei] - jspc_interf #Corregir indices - + #Removiendo la interferencia del punto de mayor interferencia ListAux = jspc_interf[mask_prof].tolist() maxid = ListAux.index(max(ListAux)) - - + + if cinterfid > 0: for ip in range(cinterfid*(interf == 2) - 1): ind = (jspectra[ich,interfid[ip],:] < tmp_noise*(1 + 1/numpy.sqrt(num_incoh))).nonzero() cind = len(ind) - + if (cind > 0): jspectra[ich,interfid[ip],ind] = tmp_noise*(1 + (numpy.random.uniform(cind) - 0.5)/numpy.sqrt(num_incoh)) - + ind = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for id1 in range(4): xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx = xx_inv[:,0] ind = (ind + maxid + num_mask_prof)%num_mask_prof yy = jspectra[ich,mask_prof[ind],:] jspectra[ich,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - - - indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero() + + + indAux = (jspectra[ich,:,:] < tmp_noise*(1-1/numpy.sqrt(num_incoh))).nonzero() jspectra[ich,indAux[0],indAux[1]] = tmp_noise * (1 - 1/numpy.sqrt(num_incoh)) - + #Remocion de Interferencia en el Cross Spectra if jcspectra is None: return jspectra, jcspectra num_pairs = jcspectra.size/(num_prof*num_hei) jcspectra = jcspectra.reshape(num_pairs, num_prof, num_hei) - + for ip in range(num_pairs): - + #------------------------------------------- - + cspower = numpy.abs(jcspectra[ip,mask_prof,:]) cspower = cspower[:,hei_interf] cspower = cspower.sum(axis = 0) - + cspsort = cspower.ravel().argsort() junkcspc_interf = jcspectra[ip,:,hei_interf[cspsort[range(offhei_interf, nhei_interf + offhei_interf)]]] junkcspc_interf = junkcspc_interf.transpose() jcspc_interf = junkcspc_interf.sum(axis = 1)/nhei_interf - + ind = numpy.abs(jcspc_interf[mask_prof]).ravel().argsort() - + median_real = numpy.median(numpy.real(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) median_imag = numpy.median(numpy.imag(junkcspc_interf[mask_prof[ind[range(3*num_prof/4)]],:])) junkcspc_interf[comp_mask_prof,:] = numpy.complex(median_real, median_imag) - + for iprof in range(num_prof): ind = numpy.abs(junkcspc_interf[iprof,:]).ravel().argsort() jcspc_interf[iprof] = junkcspc_interf[iprof, ind[nhei_interf/2]] - + #Removiendo la Interferencia jcspectra[ip,:,ind_hei] = jcspectra[ip,:,ind_hei] - jcspc_interf - + ListAux = numpy.abs(jcspc_interf[mask_prof]).tolist() maxid = ListAux.index(max(ListAux)) - + ind = numpy.array([-2,-1,1,2]) xx = numpy.zeros([4,4]) - + for id1 in range(4): xx[:,id1] = ind[id1]**numpy.asarray(range(4)) - + xx_inv = numpy.linalg.inv(xx) xx = xx_inv[:,0] - + ind = (ind + maxid + num_mask_prof)%num_mask_prof yy = jcspectra[ip,mask_prof[ind],:] jcspectra[ip,mask_prof[maxid],:] = numpy.dot(yy.transpose(),xx) - + #Guardar Resultados self.dataOut.data_spc = jspectra self.dataOut.data_cspc = jcspectra - + return 1 - + def setRadarFrequency(self, frequency=None): - + if frequency != None: self.dataOut.frequency = frequency - + return 1 - - def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): + + def getNoise(self, minHei=None, maxHei=None, minVel=None, maxVel=None): #validacion de rango if minHei == None: minHei = self.dataOut.heightList[0] - + if maxHei == None: maxHei = self.dataOut.heightList[-1] - + if (minHei < self.dataOut.heightList[0]) or (minHei > maxHei): print 'minHei: %.2f is out of the heights range'%(minHei) print 'minHei is setting to %.2f'%(self.dataOut.heightList[0]) minHei = self.dataOut.heightList[0] - + if (maxHei > self.dataOut.heightList[-1]) or (maxHei < minHei): print 'maxHei: %.2f is out of the heights range'%(maxHei) print 'maxHei is setting to %.2f'%(self.dataOut.heightList[-1]) maxHei = self.dataOut.heightList[-1] - + # validacion de velocidades velrange = self.dataOut.getVelRange(1) - + if minVel == None: minVel = velrange[0] - + if maxVel == None: maxVel = velrange[-1] - + if (minVel < velrange[0]) or (minVel > maxVel): print 'minVel: %.2f is out of the velocity range'%(minVel) print 'minVel is setting to %.2f'%(velrange[0]) minVel = velrange[0] - + if (maxVel > velrange[-1]) or (maxVel < minVel): print 'maxVel: %.2f is out of the velocity range'%(maxVel) print 'maxVel is setting to %.2f'%(velrange[-1]) maxVel = velrange[-1] - - # seleccion de indices para rango + + # seleccion de indices para rango minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: @@ -708,7 +708,7 @@ class SpectraLagsProc(ProcessingUnit): if (minIndex < 0) or (minIndex > maxIndex): raise ValueError, "some value in (%d,%d) is not valid" % (minIndex, maxIndex) - + if (maxIndex >= self.dataOut.nHeights): maxIndex = self.dataOut.nHeights-1 @@ -719,21 +719,21 @@ class SpectraLagsProc(ProcessingUnit): minIndexVel = indminvel[0][0] except: minIndexVel = 0 - + try: maxIndexVel = indmaxvel[0][-1] - except: + except: maxIndexVel = len(velrange) - + #seleccion del espectro data_spc = self.dataOut.data_spc[:,minIndexVel:maxIndexVel+1,minIndex:maxIndex+1] #estimacion de ruido noise = numpy.zeros(self.dataOut.nChannels) - + for channel in range(self.dataOut.nChannels): daux = data_spc[channel,:,:] noise[channel] = hildebrand_sekhon(daux, self.dataOut.nIncohInt) - + self.dataOut.noise_estimation = noise.copy() - - return 1 \ No newline at end of file + + return 1 diff --git a/schainpy/model/proc/jroproc_voltage.py b/schainpy/model/proc/jroproc_voltage.py index 030151c..ee0da38 100644 --- a/schainpy/model/proc/jroproc_voltage.py +++ b/schainpy/model/proc/jroproc_voltage.py @@ -1,89 +1,90 @@ import sys import numpy from scipy import interpolate - +from schainpy import cSchain from jroproc_base import ProcessingUnit, Operation from schainpy.model.data.jrodata import Voltage +from time import time -class VoltageProc(ProcessingUnit): - - - def __init__(self): - - ProcessingUnit.__init__(self) - -# self.objectDict = {} +class VoltageProc(ProcessingUnit): + + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + + # self.objectDict = {} self.dataOut = Voltage() self.flip = 1 def run(self): if self.dataIn.type == 'AMISR': self.__updateObjFromAmisrInput() - + if self.dataIn.type == 'Voltage': self.dataOut.copy(self.dataIn) - -# self.dataOut.copy(self.dataIn) + + # self.dataOut.copy(self.dataIn) def __updateObjFromAmisrInput(self): - + self.dataOut.timeZone = self.dataIn.timeZone self.dataOut.dstFlag = self.dataIn.dstFlag self.dataOut.errorCount = self.dataIn.errorCount self.dataOut.useLocalTime = self.dataIn.useLocalTime - + self.dataOut.flagNoData = self.dataIn.flagNoData self.dataOut.data = self.dataIn.data self.dataOut.utctime = self.dataIn.utctime self.dataOut.channelList = self.dataIn.channelList -# self.dataOut.timeInterval = self.dataIn.timeInterval + # self.dataOut.timeInterval = self.dataIn.timeInterval self.dataOut.heightList = self.dataIn.heightList self.dataOut.nProfiles = self.dataIn.nProfiles - + self.dataOut.nCohInt = self.dataIn.nCohInt self.dataOut.ippSeconds = self.dataIn.ippSeconds self.dataOut.frequency = self.dataIn.frequency - + self.dataOut.azimuth = self.dataIn.azimuth self.dataOut.zenith = self.dataIn.zenith - + self.dataOut.beam.codeList = self.dataIn.beam.codeList self.dataOut.beam.azimuthList = self.dataIn.beam.azimuthList self.dataOut.beam.zenithList = self.dataIn.beam.zenithList -# -# pass# -# -# def init(self): -# -# -# if self.dataIn.type == 'AMISR': -# self.__updateObjFromAmisrInput() -# -# if self.dataIn.type == 'Voltage': -# self.dataOut.copy(self.dataIn) -# # No necesita copiar en cada init() los atributos de dataIn -# # la copia deberia hacerse por cada nuevo bloque de datos - + # + # pass# + # + # def init(self): + # + # + # if self.dataIn.type == 'AMISR': + # self.__updateObjFromAmisrInput() + # + # if self.dataIn.type == 'Voltage': + # self.dataOut.copy(self.dataIn) + # # No necesita copiar en cada init() los atributos de dataIn + # # la copia deberia hacerse por cada nuevo bloque de datos + def selectChannels(self, channelList): - + channelIndexList = [] - + for channel in channelList: if channel not in self.dataOut.channelList: raise ValueError, "Channel %d is not in %s" %(channel, str(self.dataOut.channelList)) - + index = self.dataOut.channelList.index(channel) channelIndexList.append(index) - + self.selectChannelsByIndex(channelIndexList) - + def selectChannelsByIndex(self, channelIndexList): """ - Selecciona un bloque de datos en base a canales segun el channelIndexList - + Selecciona un bloque de datos en base a canales segun el channelIndexList + Input: - channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7] - + channelIndexList : lista sencilla de canales a seleccionar por ej. [2,3,7] + Affected: self.dataOut.data self.dataOut.channelIndexList @@ -91,7 +92,7 @@ class VoltageProc(ProcessingUnit): self.dataOut.m_ProcessingHeader.totalSpectra self.dataOut.systemHeaderObj.numChannels self.dataOut.m_ProcessingHeader.blockSize - + Return: None """ @@ -100,7 +101,7 @@ class VoltageProc(ProcessingUnit): if channelIndex not in self.dataOut.channelIndexList: print channelIndexList raise ValueError, "The value %d in channelIndexList is not valid" %channelIndex - + if self.dataOut.flagDataAsBlock: """ Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis] @@ -108,86 +109,86 @@ class VoltageProc(ProcessingUnit): data = self.dataOut.data[channelIndexList,:,:] else: data = self.dataOut.data[channelIndexList,:] - + self.dataOut.data = data self.dataOut.channelList = [self.dataOut.channelList[i] for i in channelIndexList] -# self.dataOut.nChannels = nChannels - + # self.dataOut.nChannels = nChannels + return 1 - + def selectHeights(self, minHei=None, maxHei=None): """ Selecciona un bloque de datos en base a un grupo de valores de alturas segun el rango minHei <= height <= maxHei - + Input: - minHei : valor minimo de altura a considerar + minHei : valor minimo de altura a considerar maxHei : valor maximo de altura a considerar - + Affected: Indirectamente son cambiados varios valores a travez del metodo selectHeightsByIndex - + Return: 1 si el metodo se ejecuto con exito caso contrario devuelve 0 """ - + if minHei == None: minHei = self.dataOut.heightList[0] - + if maxHei == None: maxHei = self.dataOut.heightList[-1] - + if (minHei < self.dataOut.heightList[0]): minHei = self.dataOut.heightList[0] if (maxHei > self.dataOut.heightList[-1]): maxHei = self.dataOut.heightList[-1] - + minIndex = 0 maxIndex = 0 heights = self.dataOut.heightList - + inda = numpy.where(heights >= minHei) indb = numpy.where(heights <= maxHei) - + try: minIndex = inda[0][0] except: minIndex = 0 - + try: maxIndex = indb[0][-1] except: maxIndex = len(heights) self.selectHeightsByIndex(minIndex, maxIndex) - + return 1 - + def selectHeightsByIndex(self, minIndex, maxIndex): """ Selecciona un bloque de datos en base a un grupo indices de alturas segun el rango minIndex <= index <= maxIndex - + Input: - minIndex : valor de indice minimo de altura a considerar + minIndex : valor de indice minimo de altura a considerar maxIndex : valor de indice maximo de altura a considerar - + Affected: self.dataOut.data self.dataOut.heightList - + Return: 1 si el metodo se ejecuto con exito caso contrario devuelve 0 """ - + if (minIndex < 0) or (minIndex > maxIndex): raise ValueError, "Height index range (%d,%d) is not valid" % (minIndex, maxIndex) - + if (maxIndex >= self.dataOut.nHeights): maxIndex = self.dataOut.nHeights - + #voltage if self.dataOut.flagDataAsBlock: """ @@ -197,31 +198,31 @@ class VoltageProc(ProcessingUnit): else: data = self.dataOut.data[:, minIndex:maxIndex] -# firstHeight = self.dataOut.heightList[minIndex] + # firstHeight = self.dataOut.heightList[minIndex] self.dataOut.data = data self.dataOut.heightList = self.dataOut.heightList[minIndex:maxIndex] - + if self.dataOut.nHeights <= 1: raise ValueError, "selectHeights: Too few heights. Current number of heights is %d" %(self.dataOut.nHeights) - + return 1 - - + + def filterByHeights(self, window): - + deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0] - + if window == None: window = (self.dataOut.radarControllerHeaderObj.txA/self.dataOut.radarControllerHeaderObj.nBaud) / deltaHeight - + newdelta = deltaHeight * window r = self.dataOut.nHeights % window newheights = (self.dataOut.nHeights-r)/window - + if newheights <= 1: raise ValueError, "filterByHeights: Too few heights. Current number of heights is %d and window is %d" %(self.dataOut.nHeights, window) - + if self.dataOut.flagDataAsBlock: """ Si la data es obtenida por bloques, dimension = [nChannels, nProfiles, nHeis] @@ -229,9 +230,9 @@ class VoltageProc(ProcessingUnit): buffer = self.dataOut.data[:, :, 0:self.dataOut.nHeights-r] buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nProfiles,self.dataOut.nHeights/window,window) buffer = numpy.sum(buffer,3) - + else: - buffer = self.dataOut.data[:,0:self.dataOut.nHeights-r] + buffer = self.dataOut.data[:,0:self.dataOut.nHeights-r] buffer = buffer.reshape(self.dataOut.nChannels,self.dataOut.nHeights/window,window) buffer = numpy.sum(buffer,2) @@ -240,24 +241,24 @@ class VoltageProc(ProcessingUnit): self.dataOut.windowOfFilter = window def setH0(self, h0, deltaHeight = None): - + if not deltaHeight: deltaHeight = self.dataOut.heightList[1] - self.dataOut.heightList[0] - + nHeights = self.dataOut.nHeights - + newHeiRange = h0 + numpy.arange(nHeights)*deltaHeight - + self.dataOut.heightList = newHeiRange - + def deFlip(self, channelList = []): - + data = self.dataOut.data.copy() - + if self.dataOut.flagDataAsBlock: flip = self.flip profileList = range(self.dataOut.nProfiles) - + if not channelList: for thisProfile in profileList: data[:,thisProfile,:] = data[:,thisProfile,:]*flip @@ -266,13 +267,13 @@ class VoltageProc(ProcessingUnit): for thisChannel in channelList: if thisChannel not in self.dataOut.channelList: continue - + for thisProfile in profileList: data[thisChannel,thisProfile,:] = data[thisChannel,thisProfile,:]*flip flip *= -1.0 - + self.flip = flip - + else: if not channelList: data[:,:] = data[:,:]*self.flip @@ -280,20 +281,20 @@ class VoltageProc(ProcessingUnit): for thisChannel in channelList: if thisChannel not in self.dataOut.channelList: continue - + data[thisChannel,:] = data[thisChannel,:]*self.flip - + self.flip *= -1. - + self.dataOut.data = data - + def setRadarFrequency(self, frequency=None): - + if frequency != None: self.dataOut.frequency = frequency - + return 1 - + def interpolateHeights(self, topLim, botLim): #69 al 72 para julia #82-84 para meteoros @@ -309,57 +310,53 @@ class VoltageProc(ProcessingUnit): f = interpolate.interp1d(x, y, axis = 2) xnew = numpy.arange(botLim,topLim+1) ynew = f(xnew) - + self.dataOut.data[:,:,botLim:topLim+1] = ynew -# import collections - + # import collections + class CohInt(Operation): - + isConfig = False - __profIndex = 0 - __withOverapping = False - __byTime = False __initime = None __lastdatatime = None __integrationtime = None - __buffer = None - + __bufferStride = [] __dataReady = False - + __profIndexStride = 0 + __dataToPutStride = False n = None - - - def __init__(self): - - Operation.__init__(self) - -# self.isConfig = False - - def setup(self, n=None, timeInterval=None, overlapping=False, byblock=False): + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + + # self.isConfig = False + + def setup(self, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False): """ Set the parameters of the integration class. - + Inputs: - - n : Number of coherent integrations - timeInterval : Time of integration. If the parameter "n" is selected this one does not work - overlapping : - + + n : Number of coherent integrations + timeInterval : Time of integration. If the parameter "n" is selected this one does not work + overlapping : """ - + self.__initime = None self.__lastdatatime = 0 self.__buffer = None self.__dataReady = False self.byblock = byblock - + self.stride = stride + if n == None and timeInterval == None: - raise ValueError, "n or timeInterval should be specified ..." - + raise ValueError, "n or timeInterval should be specified ..." + if n != None: self.n = n self.__byTime = False @@ -367,330 +364,370 @@ class CohInt(Operation): self.__integrationtime = timeInterval #* 60. #if (type(timeInterval)!=integer) -> change this line self.n = 9999 self.__byTime = True - + if overlapping: - self.__withOverapping = True + self.__withOverlapping = True self.__buffer = None else: - self.__withOverapping = False + self.__withOverlapping = False self.__buffer = 0 - + self.__profIndex = 0 - + def putData(self, data): - + """ Add a profile to the __buffer and increase in one the __profileIndex - + """ - - if not self.__withOverapping: + + if not self.__withOverlapping: self.__buffer += data.copy() - self.__profIndex += 1 + self.__profIndex += 1 return - + #Overlapping data nChannels, nHeis = data.shape data = numpy.reshape(data, (1, nChannels, nHeis)) - + #If the buffer is empty then it takes the data value if self.__buffer is None: self.__buffer = data self.__profIndex += 1 return - + #If the buffer length is lower than n then stakcing the data value if self.__profIndex < self.n: self.__buffer = numpy.vstack((self.__buffer, data)) self.__profIndex += 1 return - - #If the buffer length is equal to n then replacing the last buffer value with the data value + + #If the buffer length is equal to n then replacing the last buffer value with the data value self.__buffer = numpy.roll(self.__buffer, -1, axis=0) self.__buffer[self.n-1] = data self.__profIndex = self.n return - - + + def pushData(self): """ Return the sum of the last profiles and the profiles used in the sum. - + Affected: - + self.__profileIndex - + """ - - if not self.__withOverapping: + + if not self.__withOverlapping: data = self.__buffer n = self.__profIndex - + self.__buffer = 0 self.__profIndex = 0 - + return data, n - + #Integration with Overlapping data = numpy.sum(self.__buffer, axis=0) + # print data + # raise n = self.__profIndex - + return data, n - + def byProfiles(self, data): - + self.__dataReady = False avgdata = None -# n = None - + # n = None + # print data + # raise self.putData(data) - + if self.__profIndex == self.n: - avgdata, n = self.pushData() self.__dataReady = True - + return avgdata - + def byTime(self, data, datatime): - + self.__dataReady = False avgdata = None n = None - + self.putData(data) - + if (datatime - self.__initime) >= self.__integrationtime: avgdata, n = self.pushData() self.n = n self.__dataReady = True - + return avgdata - + + def integrateByStride(self, data, datatime): + # print data + if self.__profIndex == 0: + self.__buffer = [[data.copy(), datatime]] + else: + self.__buffer.append([data.copy(),datatime]) + self.__profIndex += 1 + self.__dataReady = False + + if self.__profIndex == self.n * self.stride : + self.__dataToPutStride = True + self.__profIndexStride = 0 + self.__profIndex = 0 + self.__bufferStride = [] + for i in range(self.stride): + current = self.__buffer[i::self.stride] + data = numpy.sum([t[0] for t in current], axis=0) + avgdatatime = numpy.average([t[1] for t in current]) + # print data + self.__bufferStride.append((data, avgdatatime)) + + if self.__dataToPutStride: + self.__dataReady = True + self.__profIndexStride += 1 + if self.__profIndexStride == self.stride: + self.__dataToPutStride = False + # print self.__bufferStride[self.__profIndexStride - 1] + # raise + return self.__bufferStride[self.__profIndexStride - 1] + + + return None, None + def integrate(self, data, datatime=None): - + if self.__initime == None: self.__initime = datatime - + if self.__byTime: avgdata = self.byTime(data, datatime) else: avgdata = self.byProfiles(data) - - + + self.__lastdatatime = datatime - + if avgdata is None: return None, None - + avgdatatime = self.__initime + + deltatime = datatime - self.__lastdatatime - deltatime = datatime -self.__lastdatatime - - if not self.__withOverapping: + if not self.__withOverlapping: self.__initime = datatime else: self.__initime += deltatime - + return avgdata, avgdatatime - + def integrateByBlock(self, dataOut): - + times = int(dataOut.data.shape[1]/self.n) avgdata = numpy.zeros((dataOut.nChannels, times, dataOut.nHeights), dtype=numpy.complex) - + id_min = 0 id_max = self.n - + for i in range(times): junk = dataOut.data[:,id_min:id_max,:] avgdata[:,i,:] = junk.sum(axis=1) id_min += self.n - id_max += self.n - + id_max += self.n + timeInterval = dataOut.ippSeconds*self.n - avgdatatime = (times - 1) * timeInterval + dataOut.utctime + avgdatatime = (times - 1) * timeInterval + dataOut.utctime self.__dataReady = True return avgdata, avgdatatime - def run(self, dataOut, **kwargs): - + def run(self, dataOut, n=None, timeInterval=None, stride=None, overlapping=False, byblock=False, **kwargs): if not self.isConfig: - self.setup(**kwargs) + self.setup(n=n, stride=stride, timeInterval=timeInterval, overlapping=overlapping, byblock=byblock, **kwargs) self.isConfig = True - + if dataOut.flagDataAsBlock: """ Si la data es leida por bloques, dimension = [nChannels, nProfiles, nHeis] """ avgdata, avgdatatime = self.integrateByBlock(dataOut) dataOut.nProfiles /= self.n - else: - avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime) + else: + if stride is None: + avgdata, avgdatatime = self.integrate(dataOut.data, dataOut.utctime) + else: + avgdata, avgdatatime = self.integrateByStride(dataOut.data, dataOut.utctime) + -# dataOut.timeInterval *= n + # dataOut.timeInterval *= n dataOut.flagNoData = True - + if self.__dataReady: dataOut.data = avgdata dataOut.nCohInt *= self.n dataOut.utctime = avgdatatime -# dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt + # print avgdata, avgdatatime + # raise + # dataOut.timeInterval = dataOut.ippSeconds * dataOut.nCohInt dataOut.flagNoData = False class Decoder(Operation): - + isConfig = False __profIndex = 0 - + code = None - - nCode = None + + nCode = None nBaud = None - - - def __init__(self): - - Operation.__init__(self) - + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + self.times = None self.osamp = None -# self.__setValues = False + # self.__setValues = False self.isConfig = False - + def setup(self, code, osamp, dataOut): - + self.__profIndex = 0 - + self.code = code - - self.nCode = len(code) + + self.nCode = len(code) self.nBaud = len(code[0]) - + if (osamp != None) and (osamp >1): self.osamp = osamp self.code = numpy.repeat(code, repeats=self.osamp, axis=1) self.nBaud = self.nBaud*self.osamp - + self.__nChannels = dataOut.nChannels self.__nProfiles = dataOut.nProfiles self.__nHeis = dataOut.nHeights - + if self.__nHeis < self.nBaud: raise ValueError, 'Number of heights (%d) should be greater than number of bauds (%d)' %(self.__nHeis, self.nBaud) - + #Frequency __codeBuffer = numpy.zeros((self.nCode, self.__nHeis), dtype=numpy.complex) - + __codeBuffer[:,0:self.nBaud] = self.code - + self.fft_code = numpy.conj(numpy.fft.fft(__codeBuffer, axis=1)) - + if dataOut.flagDataAsBlock: - + self.ndatadec = self.__nHeis #- self.nBaud + 1 - + self.datadecTime = numpy.zeros((self.__nChannels, self.__nProfiles, self.ndatadec), dtype=numpy.complex) - + else: - + #Time self.ndatadec = self.__nHeis #- self.nBaud + 1 - - self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex) - + + self.datadecTime = numpy.zeros((self.__nChannels, self.ndatadec), dtype=numpy.complex) + def __convolutionInFreq(self, data): - + fft_code = self.fft_code[self.__profIndex].reshape(1,-1) - + fft_data = numpy.fft.fft(data, axis=1) - + conv = fft_data*fft_code - + data = numpy.fft.ifft(conv,axis=1) - + return data - + def __convolutionInFreqOpt(self, data): - + raise NotImplementedError - + def __convolutionInTime(self, data): - + code = self.code[self.__profIndex] - for i in range(self.__nChannels): self.datadecTime[i,:] = numpy.correlate(data[i,:], code, mode='full')[self.nBaud-1:] - + return self.datadecTime - + def __convolutionByBlockInTime(self, data): - + repetitions = self.__nProfiles / self.nCode junk = numpy.lib.stride_tricks.as_strided(self.code, (repetitions, self.code.size), (0, self.code.itemsize)) junk = junk.flatten() code_block = numpy.reshape(junk, (self.nCode*repetitions, self.nBaud)) + profilesList = xrange(self.__nProfiles) - for i in range(self.__nChannels): - for j in range(self.__nProfiles): - self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:] - - return self.datadecTime - + for i in range(self.__nChannels): + for j in profilesList: + self.datadecTime[i,j,:] = numpy.correlate(data[i,j,:], code_block[j,:], mode='full')[self.nBaud-1:] + return self.datadecTime + def __convolutionByBlockInFreq(self, data): - + raise NotImplementedError, "Decoder by frequency fro Blocks not implemented" fft_code = self.fft_code[self.__profIndex].reshape(1,-1) - + fft_data = numpy.fft.fft(data, axis=2) - + conv = fft_data*fft_code - + data = numpy.fft.ifft(conv,axis=2) - + return data + def run(self, dataOut, code=None, nCode=None, nBaud=None, mode = 0, osamp=None, times=None): - + if dataOut.flagDecodeData: print "This data is already decoded, recoding again ..." - + if not self.isConfig: - + if code is None: if dataOut.code is None: raise ValueError, "Code could not be read from %s instance. Enter a value in Code parameter" %dataOut.type - + code = dataOut.code else: code = numpy.array(code).reshape(nCode,nBaud) - self.setup(code, osamp, dataOut) - + self.isConfig = True - + if mode == 3: sys.stderr.write("Decoder Warning: mode=%d is not valid, using mode=0\n" %mode) - + if times != None: sys.stderr.write("Decoder Warning: Argument 'times' in not used anymore\n") - + if self.code is None: print "Fail decoding: Code is not defined." return - + + self.__nProfiles = dataOut.nProfiles datadec = None + if mode == 3: mode = 0 - + if dataOut.flagDataAsBlock: """ Decoding when data have been read as block, """ - + if mode == 0: datadec = self.__convolutionByBlockInTime(dataOut.data) if mode == 1: @@ -701,73 +738,73 @@ class Decoder(Operation): """ if mode == 0: datadec = self.__convolutionInTime(dataOut.data) - + if mode == 1: datadec = self.__convolutionInFreq(dataOut.data) - + if mode == 2: datadec = self.__convolutionInFreqOpt(dataOut.data) - + if datadec is None: raise ValueError, "Codification mode selected is not valid: mode=%d. Try selecting 0 or 1" %mode - + dataOut.code = self.code dataOut.nCode = self.nCode dataOut.nBaud = self.nBaud - + dataOut.data = datadec - + dataOut.heightList = dataOut.heightList[0:datadec.shape[-1]] - + dataOut.flagDecodeData = True #asumo q la data esta decodificada - if self.__profIndex == self.nCode-1: - self.__profIndex = 0 + if self.__profIndex == self.nCode-1: + self.__profIndex = 0 return 1 - + self.__profIndex += 1 - + return 1 -# dataOut.flagDeflipData = True #asumo q la data no esta sin flip + # dataOut.flagDeflipData = True #asumo q la data no esta sin flip class ProfileConcat(Operation): - + isConfig = False buffer = None - - def __init__(self): - - Operation.__init__(self) + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) self.profileIndex = 0 - + def reset(self): self.buffer = numpy.zeros_like(self.buffer) self.start_index = 0 self.times = 1 - + def setup(self, data, m, n=1): self.buffer = numpy.zeros((data.shape[0],data.shape[1]*m),dtype=type(data[0,0])) self.nHeights = data.shape[1]#.nHeights self.start_index = 0 self.times = 1 - + def concat(self, data): - + self.buffer[:,self.start_index:self.nHeights*self.times] = data.copy() - self.start_index = self.start_index + self.nHeights - + self.start_index = self.start_index + self.nHeights + def run(self, dataOut, m): - + dataOut.flagNoData = True - + if not self.isConfig: self.setup(dataOut.data, m, 1) self.isConfig = True - + if dataOut.flagDataAsBlock: raise ValueError, "ProfileConcat can only be used when voltage have been read profile by profile, getBlock = False" - + else: self.concat(dataOut.data) self.times += 1 @@ -776,508 +813,507 @@ class ProfileConcat(Operation): self.reset() dataOut.flagNoData = False # se deben actualizar mas propiedades del header y del objeto dataOut, por ejemplo, las alturas - deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] + deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] xf = dataOut.heightList[0] + dataOut.nHeights * deltaHeight * m - dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight) + dataOut.heightList = numpy.arange(dataOut.heightList[0], xf, deltaHeight) dataOut.ippSeconds *= m class ProfileSelector(Operation): - + profileIndex = None # Tamanho total de los perfiles nProfiles = None - - def __init__(self): - - Operation.__init__(self) + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) self.profileIndex = 0 - + def incProfileIndex(self): - + self.profileIndex += 1 - + if self.profileIndex >= self.nProfiles: self.profileIndex = 0 - + def isThisProfileInRange(self, profileIndex, minIndex, maxIndex): - + if profileIndex < minIndex: return False - + if profileIndex > maxIndex: return False - + return True - + def isThisProfileInList(self, profileIndex, profileList): - + if profileIndex not in profileList: return False - + return True - + def run(self, dataOut, profileList=None, profileRangeList=None, beam=None, byblock=False, rangeList = None, nProfiles=None): """ ProfileSelector: - + Inputs: - profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8) - + profileList : Index of profiles selected. Example: profileList = (0,1,2,7,8) + profileRangeList : Minimum and maximum profile indexes. Example: profileRangeList = (4, 30) - + rangeList : List of profile ranges. Example: rangeList = ((4, 30), (32, 64), (128, 256)) - + """ - + if rangeList is not None: if type(rangeList[0]) not in (tuple, list): rangeList = [rangeList] - + dataOut.flagNoData = True - + if dataOut.flagDataAsBlock: """ data dimension = [nChannels, nProfiles, nHeis] """ if profileList != None: dataOut.data = dataOut.data[:,profileList,:] - + if profileRangeList != None: minIndex = profileRangeList[0] maxIndex = profileRangeList[1] profileList = range(minIndex, maxIndex+1) - + dataOut.data = dataOut.data[:,minIndex:maxIndex+1,:] - + if rangeList != None: - + profileList = [] - + for thisRange in rangeList: minIndex = thisRange[0] maxIndex = thisRange[1] - + profileList.extend(range(minIndex, maxIndex+1)) - + dataOut.data = dataOut.data[:,profileList,:] - + dataOut.nProfiles = len(profileList) dataOut.profileIndex = dataOut.nProfiles - 1 dataOut.flagNoData = False - + return True - + """ data dimension = [nChannels, nHeis] """ - + if profileList != None: - + if self.isThisProfileInList(dataOut.profileIndex, profileList): - + self.nProfiles = len(profileList) dataOut.nProfiles = self.nProfiles dataOut.profileIndex = self.profileIndex dataOut.flagNoData = False - + self.incProfileIndex() return True - + if profileRangeList != None: - + minIndex = profileRangeList[0] maxIndex = profileRangeList[1] - + if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex): - + self.nProfiles = maxIndex - minIndex + 1 dataOut.nProfiles = self.nProfiles dataOut.profileIndex = self.profileIndex dataOut.flagNoData = False - + self.incProfileIndex() return True - + if rangeList != None: - + nProfiles = 0 - + for thisRange in rangeList: minIndex = thisRange[0] maxIndex = thisRange[1] - + nProfiles += maxIndex - minIndex + 1 - + for thisRange in rangeList: - + minIndex = thisRange[0] maxIndex = thisRange[1] - + if self.isThisProfileInRange(dataOut.profileIndex, minIndex, maxIndex): - + self.nProfiles = nProfiles dataOut.nProfiles = self.nProfiles dataOut.profileIndex = self.profileIndex dataOut.flagNoData = False - + self.incProfileIndex() - + break - + return True - - + + if beam != None: #beam is only for AMISR data if self.isThisProfileInList(dataOut.profileIndex, dataOut.beamRangeDict[beam]): dataOut.flagNoData = False dataOut.profileIndex = self.profileIndex - + self.incProfileIndex() - + return True - + raise ValueError, "ProfileSelector needs profileList, profileRangeList or rangeList parameter" - + return False - + class Reshaper(Operation): - - def __init__(self): - - Operation.__init__(self) - + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + self.__buffer = None self.__nitems = 0 - + def __appendProfile(self, dataOut, nTxs): - + if self.__buffer is None: shape = (dataOut.nChannels, int(dataOut.nHeights/nTxs) ) self.__buffer = numpy.empty(shape, dtype = dataOut.data.dtype) - + ini = dataOut.nHeights * self.__nitems end = ini + dataOut.nHeights - + self.__buffer[:, ini:end] = dataOut.data - + self.__nitems += 1 - + return int(self.__nitems*nTxs) - + def __getBuffer(self): - + if self.__nitems == int(1./self.__nTxs): - + self.__nitems = 0 - + return self.__buffer.copy() - + return None - + def __checkInputs(self, dataOut, shape, nTxs): - + if shape is None and nTxs is None: raise ValueError, "Reshaper: shape of factor should be defined" - + if nTxs: if nTxs < 0: raise ValueError, "nTxs should be greater than 0" - + if nTxs < 1 and dataOut.nProfiles % (1./nTxs) != 0: raise ValueError, "nProfiles= %d is not divisibled by (1./nTxs) = %f" %(dataOut.nProfiles, (1./nTxs)) - + shape = [dataOut.nChannels, dataOut.nProfiles*nTxs, dataOut.nHeights/nTxs] - + return shape, nTxs - + if len(shape) != 2 and len(shape) != 3: raise ValueError, "shape dimension should be equal to 2 or 3. shape = (nProfiles, nHeis) or (nChannels, nProfiles, nHeis). Actually shape = (%d, %d, %d)" %(dataOut.nChannels, dataOut.nProfiles, dataOut.nHeights) - + if len(shape) == 2: shape_tuple = [dataOut.nChannels] shape_tuple.extend(shape) else: shape_tuple = list(shape) - + nTxs = 1.0*shape_tuple[1]/dataOut.nProfiles - + return shape_tuple, nTxs - + def run(self, dataOut, shape=None, nTxs=None): - + shape_tuple, self.__nTxs = self.__checkInputs(dataOut, shape, nTxs) - + dataOut.flagNoData = True profileIndex = None - + if dataOut.flagDataAsBlock: - + dataOut.data = numpy.reshape(dataOut.data, shape_tuple) dataOut.flagNoData = False - + profileIndex = int(dataOut.nProfiles*self.__nTxs) - 1 - + else: - + if self.__nTxs < 1: - + self.__appendProfile(dataOut, self.__nTxs) new_data = self.__getBuffer() - + if new_data is not None: dataOut.data = new_data dataOut.flagNoData = False - + profileIndex = dataOut.profileIndex*nTxs - + else: raise ValueError, "nTxs should be greater than 0 and lower than 1, or use VoltageReader(..., getblock=True)" - + deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] - + dataOut.heightList = numpy.arange(dataOut.nHeights/self.__nTxs) * deltaHeight + dataOut.heightList[0] - + dataOut.nProfiles = int(dataOut.nProfiles*self.__nTxs) - + dataOut.profileIndex = profileIndex - + dataOut.ippSeconds /= self.__nTxs - + class SplitProfiles(Operation): - - def __init__(self): - - Operation.__init__(self) - + + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + def run(self, dataOut, n): - + dataOut.flagNoData = True profileIndex = None - + if dataOut.flagDataAsBlock: - + #nchannels, nprofiles, nsamples shape = dataOut.data.shape - + if shape[2] % n != 0: raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[2]) - + new_shape = shape[0], shape[1]*n, shape[2]/n - + dataOut.data = numpy.reshape(dataOut.data, new_shape) dataOut.flagNoData = False - + profileIndex = int(dataOut.nProfiles/n) - 1 - + else: - + raise ValueError, "Could not split the data when is read Profile by Profile. Use VoltageReader(..., getblock=True)" - + deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] - + dataOut.heightList = numpy.arange(dataOut.nHeights/n) * deltaHeight + dataOut.heightList[0] - + dataOut.nProfiles = int(dataOut.nProfiles*n) - + dataOut.profileIndex = profileIndex - + dataOut.ippSeconds /= n - + class CombineProfiles(Operation): - - def __init__(self): - - Operation.__init__(self) - + def __init__(self, **kwargs): + + Operation.__init__(self, **kwargs) + self.__remData = None self.__profileIndex = 0 def run(self, dataOut, n): - + dataOut.flagNoData = True profileIndex = None - + if dataOut.flagDataAsBlock: - + #nchannels, nprofiles, nsamples shape = dataOut.data.shape new_shape = shape[0], shape[1]/n, shape[2]*n - + if shape[1] % n != 0: raise ValueError, "Could not split the data, n=%d has to be multiple of %d" %(n, shape[1]) - + dataOut.data = numpy.reshape(dataOut.data, new_shape) dataOut.flagNoData = False - + profileIndex = int(dataOut.nProfiles*n) - 1 - + else: - + #nchannels, nsamples if self.__remData is None: newData = dataOut.data else: newData = numpy.concatenate((self.__remData, dataOut.data), axis=1) - + self.__profileIndex += 1 - + if self.__profileIndex < n: self.__remData = newData #continue return - + self.__profileIndex = 0 self.__remData = None - + dataOut.data = newData dataOut.flagNoData = False - + profileIndex = dataOut.profileIndex/n - - + + deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] - + dataOut.heightList = numpy.arange(dataOut.nHeights*n) * deltaHeight + dataOut.heightList[0] - + dataOut.nProfiles = int(dataOut.nProfiles/n) - + dataOut.profileIndex = profileIndex - + dataOut.ippSeconds *= n # import collections # from scipy.stats import mode -# +# # class Synchronize(Operation): -# +# # isConfig = False # __profIndex = 0 -# -# def __init__(self): -# -# Operation.__init__(self) +# +# def __init__(self, **kwargs): +# +# Operation.__init__(self, **kwargs) # # self.isConfig = False # self.__powBuffer = None # self.__startIndex = 0 # self.__pulseFound = False -# +# # def __findTxPulse(self, dataOut, channel=0, pulse_with = None): -# +# # #Read data -# +# # powerdB = dataOut.getPower(channel = channel) # noisedB = dataOut.getNoise(channel = channel)[0] -# +# # self.__powBuffer.extend(powerdB.flatten()) -# +# # dataArray = numpy.array(self.__powBuffer) -# +# # filteredPower = numpy.correlate(dataArray, dataArray[0:self.__nSamples], "same") -# +# # maxValue = numpy.nanmax(filteredPower) -# +# # if maxValue < noisedB + 10: # #No se encuentra ningun pulso de transmision # return None -# +# # maxValuesIndex = numpy.where(filteredPower > maxValue - 0.1*abs(maxValue))[0] -# +# # if len(maxValuesIndex) < 2: # #Solo se encontro un solo pulso de transmision de un baudio, esperando por el siguiente TX # return None -# +# # phasedMaxValuesIndex = maxValuesIndex - self.__nSamples -# +# # #Seleccionar solo valores con un espaciamiento de nSamples # pulseIndex = numpy.intersect1d(maxValuesIndex, phasedMaxValuesIndex) -# +# # if len(pulseIndex) < 2: # #Solo se encontro un pulso de transmision con ancho mayor a 1 # return None -# +# # spacing = pulseIndex[1:] - pulseIndex[:-1] -# +# # #remover senales que se distancien menos de 10 unidades o muestras # #(No deberian existir IPP menor a 10 unidades) -# +# # realIndex = numpy.where(spacing > 10 )[0] -# +# # if len(realIndex) < 2: # #Solo se encontro un pulso de transmision con ancho mayor a 1 # return None -# +# # #Eliminar pulsos anchos (deja solo la diferencia entre IPPs) # realPulseIndex = pulseIndex[realIndex] -# +# # period = mode(realPulseIndex[1:] - realPulseIndex[:-1])[0][0] -# +# # print "IPP = %d samples" %period -# +# # self.__newNSamples = dataOut.nHeights #int(period) # self.__startIndex = int(realPulseIndex[0]) -# +# # return 1 -# -# +# +# # def setup(self, nSamples, nChannels, buffer_size = 4): -# +# # self.__powBuffer = collections.deque(numpy.zeros( buffer_size*nSamples,dtype=numpy.float), # maxlen = buffer_size*nSamples) -# +# # bufferList = [] -# +# # for i in range(nChannels): # bufferByChannel = collections.deque(numpy.zeros( buffer_size*nSamples, dtype=numpy.complex) + numpy.NAN, # maxlen = buffer_size*nSamples) -# +# # bufferList.append(bufferByChannel) -# +# # self.__nSamples = nSamples # self.__nChannels = nChannels # self.__bufferList = bufferList -# +# # def run(self, dataOut, channel = 0): -# +# # if not self.isConfig: # nSamples = dataOut.nHeights # nChannels = dataOut.nChannels # self.setup(nSamples, nChannels) # self.isConfig = True -# +# # #Append new data to internal buffer # for thisChannel in range(self.__nChannels): # bufferByChannel = self.__bufferList[thisChannel] # bufferByChannel.extend(dataOut.data[thisChannel]) -# +# # if self.__pulseFound: # self.__startIndex -= self.__nSamples -# +# # #Finding Tx Pulse # if not self.__pulseFound: # indexFound = self.__findTxPulse(dataOut, channel) -# +# # if indexFound == None: # dataOut.flagNoData = True # return -# +# # self.__arrayBuffer = numpy.zeros((self.__nChannels, self.__newNSamples), dtype = numpy.complex) # self.__pulseFound = True # self.__startIndex = indexFound -# +# # #If pulse was found ... # for thisChannel in range(self.__nChannels): # bufferByChannel = self.__bufferList[thisChannel] -# #print self.__startIndex +# #print self.__startIndex # x = numpy.array(bufferByChannel) # self.__arrayBuffer[thisChannel] = x[self.__startIndex:self.__startIndex+self.__newNSamples] -# +# # deltaHeight = dataOut.heightList[1] - dataOut.heightList[0] # dataOut.heightList = numpy.arange(self.__newNSamples)*deltaHeight # # dataOut.ippSeconds = (self.__newNSamples / deltaHeight)/1e6 -# +# # dataOut.data = self.__arrayBuffer -# +# # self.__startIndex += self.__newNSamples -# -# return \ No newline at end of file +# +# return diff --git a/schainpy/model/proc/pxproc_parameters.py b/schainpy/model/proc/pxproc_parameters.py new file mode 100644 index 0000000..5d5e9d8 --- /dev/null +++ b/schainpy/model/proc/pxproc_parameters.py @@ -0,0 +1,64 @@ +''' +Created on Oct 24, 2016 + +@author: roj- LouVD +''' + +import numpy +import datetime +import time +from time import gmtime + +from numpy import transpose + +from jroproc_base import ProcessingUnit, Operation +from schainpy.model.data.jrodata import Parameters + + +class PXParametersProc(ProcessingUnit): + ''' + Processing unit for PX parameters data + ''' + + def __init__(self, **kwargs): + """ + Inputs: None + """ + ProcessingUnit.__init__(self, **kwargs) + self.dataOut = Parameters() + self.isConfig = False + + def setup(self, mode): + """ + """ + self.dataOut.mode = mode + + def run(self, mode): + """ + Args: + mode (str): select independent variable 'E' for elevation or 'A' for azimuth + """ + + if not self.isConfig: + self.setup(mode) + self.isConfig = True + + if self.dataIn.type == 'Parameters': + self.dataOut.copy(self.dataIn) + + self.dataOut.data_param = numpy.array([self.dataOut.data[var] for var in self.dataOut.parameters]) + self.dataOut.data_param[self.dataOut.data_param == self.dataOut.missing] = numpy.nan + + if mode.upper()=='E': + self.dataOut.heightList = self.dataOut.data['Azimuth'] + else: + self.dataOut.heightList = self.dataOut.data['Elevation'] + + attrs = ['units', 'elevation', 'azimuth', 'max_range', 'latitude', 'longitude'] + meta = {} + + for attr in attrs: + meta[attr] = getattr(self.dataOut, attr) + + meta['mode'] = mode + self.dataOut.meta = meta \ No newline at end of file diff --git a/schainpy/model/utils/jroutils_ftp.py b/schainpy/model/utils/jroutils_ftp.py index 3a2a77f..a507f2f 100644 --- a/schainpy/model/utils/jroutils_ftp.py +++ b/schainpy/model/utils/jroutils_ftp.py @@ -15,156 +15,156 @@ import time import threading Thread = threading.Thread - + # try: # from gevent import sleep # except: from time import sleep - + from schainpy.model.proc.jroproc_base import ProcessingUnit, Operation class Remote(Thread): """ Remote is a parent class used to define the behaviour of FTP and SSH class. These clases are used to upload or download files remotely. - + Non-standard Python modules used: None - + Written by: "Miguel Urco":mailto:miguel.urco@jro.igp.gob.pe Jun. 03, 2015 """ - + server = None username = None password = None remotefolder = None - + period = 60 fileList = [] bussy = False - + def __init__(self, server, username, password, remotefolder, period=60): - + Thread.__init__(self) - + self.setDaemon(True) - + self.status = 0 self.__server = server self.__username = username self.__password = password self.__remotefolder = remotefolder - + self.period = period - + self.fileList = [] self.bussy = False - + self.stopFlag = False - + print "[Remote Server] Opening server: %s" %self.__server if self.open(self.__server, self.__username, self.__password, self.__remotefolder): print "[Remote Server] %s server was opened successfully" %self.__server - + self.close() - + self.mutex = threading.Lock() - + def stop(self): - + self.stopFlag = True self.join(10) - + def open(self): """ Connect to server and create a connection class (FTP or SSH) to remote server. """ raise NotImplementedError, "Implement this method in child class" - + def close(self): """ Close connection to server """ raise NotImplementedError, "Implement this method in child class" - + def mkdir(self, remotefolder): """ Create a folder remotely """ raise NotImplementedError, "Implement this method in child class" - + def cd(self, remotefolder): """ Change working directory in remote server """ raise NotImplementedError, "Implement this method in child class" - + def download(self, filename, localfolder=None): """ Download a file from server to local host """ raise NotImplementedError, "Implement this method in child class" - + def sendFile(self, fullfilename): """ sendFile method is used to upload a local file to the current directory in remote server - + Inputs: fullfilename - full path name of local file to store in remote directory - + Returns: 0 in error case else 1 """ raise NotImplementedError, "Implement this method in child class" - - def upload(self, fullfilename, remotefolder=None): + + def upload(self, fullfilename, remotefolder=None): """ upload method is used to upload a local file to remote directory. This method changes working directory before sending a file. - + Inputs: fullfilename - full path name of local file to store in remote directory - - remotefolder - remote directory - + + remotefolder - remote directory + Returns: 0 in error case else 1 """ print "[Remote Server] Uploading %s to %s:%s" %(fullfilename, self.server, self.remotefolder) - + if not self.status: return 0 - + if remotefolder == None: remotefolder = self.remotefolder - + if not self.cd(remotefolder): return 0 - + if not self.sendFile(fullfilename): print "[Remote Server] Error uploading file %s" %fullfilename return 0 - + print "[Remote Server] upload finished successfully" - + return 1 - + def delete(self, filename): """ Remove a file from remote server """ pass - + def updateFileList(self, fileList): """ Remove a file from remote server """ - + if fileList == self.fileList: return 0 - + self.mutex.acquire() # init = time.time() # @@ -176,88 +176,88 @@ class Remote(Thread): self.fileList = fileList self.mutex.release() return 1 - + def run(self): - + if not self.status: print "Finishing FTP service" return - + if not self.cd(self.remotefolder): raise ValueError, "Could not access to the new remote directory: %s" %self.remotefolder - + while True: - + for i in range(self.period): if self.stopFlag: break sleep(1) - + if self.stopFlag: break - # self.bussy = True + # self.bussy = True self.mutex.acquire() - + print "[Remote Server] Opening %s" %self.__server if not self.open(self.__server, self.__username, self.__password, self.__remotefolder): self.mutex.release() continue - + for thisFile in self.fileList: self.upload(thisFile, self.remotefolder) - + print "[Remote Server] Closing %s" %self.__server self.close() - + self.mutex.release() -# self.bussy = False - + # self.bussy = False + print "[Remote Server] Thread stopped successfully" - + class FTPClient(Remote): - + __ftpClientObj = None - + def __init__(self, server, username, password, remotefolder, period=60): """ """ Remote.__init__(self, server, username, password, remotefolder, period) - + def open(self, server, username, password, remotefolder): - + """ This method is used to set FTP parameters and establish a connection to remote server - + Inputs: - server - remote server IP Address - - username - remote server Username - + server - remote server IP Address + + username - remote server Username + password - remote server password - + remotefolder - remote server current working directory - + Return: Boolean - Returns 1 if a connection has been established, 0 otherwise - - Affects: + + Affects: self.status - in case of error or fail connection this parameter is set to 0 else 1 """ - + if server == None: raise ValueError, "FTP server should be defined" - + if username == None: raise ValueError, "FTP username should be defined" - + if password == None: raise ValueError, "FTP password should be defined" - + if remotefolder == None: raise ValueError, "FTP remote folder should be defined" - + try: ftpClientObj = ftplib.FTP(server) except ftplib.all_errors, e: @@ -265,14 +265,14 @@ class FTPClient(Remote): print "[FTP Server]:", e self.status = 0 return 0 - + try: ftpClientObj.login(username, password) except ftplib.all_errors: print "[FTP Server]: FTP username or password are incorrect" self.status = 0 return 0 - + if remotefolder == None: remotefolder = ftpClientObj.pwd() else: @@ -281,122 +281,122 @@ class FTPClient(Remote): except ftplib.all_errors: print "[FTP Server]: FTP remote folder is invalid: %s" %remotefolder remotefolder = ftpClientObj.pwd() - + self.server = server self.username = username self.password = password self.remotefolder = remotefolder self.__ftpClientObj = ftpClientObj self.status = 1 - + return 1 - + def close(self): """ Close connection to remote server """ if not self.status: return 0 - + self.__ftpClientObj.close() - + def mkdir(self, remotefolder): """ mkdir is used to make a new directory in remote server - + Input: remotefolder - directory name - + Return: 0 in error case else 1 """ if not self.status: return 0 - + try: self.__ftpClientObj.mkd(dirname) except ftplib.all_errors: print "[FTP Server]: Error creating remote folder: %s" %remotefolder return 0 - + return 1 - + def cd(self, remotefolder): """ cd is used to change remote working directory on server - + Input: remotefolder - current working directory - + Affects: self.remotefolder - - Return: + + Return: 0 in case of error else 1 """ if not self.status: return 0 - + if remotefolder == self.remotefolder: return 1 - - try: - self.__ftpClientObj.cwd(remotefolder) + + try: + self.__ftpClientObj.cwd(remotefolder) except ftplib.all_errors: print '[FTP Server]: Error changing to %s' %remotefolder print '[FTP Server]: Trying to create remote folder' - + if not self.mkdir(remotefolder): print '[FTP Server]: Remote folder could not be created' return 0 - - try: - self.__ftpClientObj.cwd(remotefolder) + + try: + self.__ftpClientObj.cwd(remotefolder) except ftplib.all_errors: return 0 - + self.remotefolder = remotefolder - + return 1 - + def sendFile(self, fullfilename): if not self.status: return 0 - + fp = open(fullfilename, 'rb') - + filename = os.path.basename(fullfilename) - + command = "STOR %s" %filename - + try: self.__ftpClientObj.storbinary(command, fp) except ftplib.all_errors, e: print "[FTP Server]:", e return 0 - + try: self.__ftpClientObj.sendcmd('SITE CHMOD 755 ' + filename) except ftplib.all_errors, e: print "[FTP Server]:", e - + fp.close() - + return 1 class SSHClient(Remote): - + __sshClientObj = None __scpClientObj = None - + def __init__(self, server, username, password, remotefolder, period=60): """ """ Remote.__init__(self, server, username, password, remotefolder, period) - + def open(self, server, username, password, remotefolder, port=22): - + """ This method is used to set SSH parameters and establish a connection to a remote server @@ -416,27 +416,27 @@ class SSHClient(Remote): """ import socket - + if server == None: raise ValueError, "SSH server should be defined" - + if username == None: raise ValueError, "SSH username should be defined" - + if password == None: raise ValueError, "SSH password should be defined" - + if remotefolder == None: raise ValueError, "SSH remote folder should be defined" - + sshClientObj = paramiko.SSHClient() - + sshClientObj.load_system_host_keys() sshClientObj.set_missing_host_key_policy(paramiko.WarningPolicy()) - + self.status = 0 try: - sshClientObj.connect(server, username=username, password=password, port=port) + sshClientObj.connect(server, username=username, password=password, port=port) except paramiko.AuthenticationException, e: # print "SSH username or password are incorrect: %s" print "[SSH Server]:", e @@ -448,35 +448,35 @@ class SSHClient(Remote): self.status = 0 print "[SSH Server]:", e return 0 - + self.status = 1 scpClientObj = scp.SCPClient(sshClientObj.get_transport(), socket_timeout=30) - + if remotefolder == None: remotefolder = self.pwd() - + self.server = server self.username = username self.password = password self.__sshClientObj = sshClientObj self.__scpClientObj = scpClientObj self.status = 1 - + if not self.cd(remotefolder): raise ValueError, "[SSH Server]: Could not access to remote folder: %s" %remotefolder return 0 - + self.remotefolder = remotefolder - + return 1 - + def close(self): """ Close connection to remote server """ if not self.status: return 0 - + self.__scpClientObj.close() self.__sshClientObj.close() @@ -494,7 +494,7 @@ class SSHClient(Remote): return 0 stdin, stdout, stderr = self.__sshClientObj.exec_command(command) - + result = stderr.readlines() if len(result) > 1: return 0 @@ -502,9 +502,9 @@ class SSHClient(Remote): result = stdout.readlines() if len(result) > 1: return result[0][:-1] - + return 1 - + def mkdir(self, remotefolder): """ mkdir is used to make a new directory in remote server @@ -515,17 +515,17 @@ class SSHClient(Remote): Return: 0 in error case else 1 """ - + command = 'mkdir %s' %remotefolder - + return self.__execute(command) - + def pwd(self): command = 'pwd' - + return self.__execute(command) - + def cd(self, remotefolder): """ cd is used to change remote working directory on server @@ -544,97 +544,98 @@ class SSHClient(Remote): if remotefolder == self.remotefolder: return 1 - + chk_command = "cd %s; pwd" %remotefolder mkdir_command = "mkdir %s" %remotefolder - + if not self.__execute(chk_command): if not self.__execute(mkdir_command): self.remotefolder = None return 0 - + self.remotefolder = remotefolder - + return 1 - + def sendFile(self, fullfilename): if not self.status: return 0 - + try: self.__scpClientObj.put(fullfilename, remote_path=self.remotefolder) except scp.ScpError, e: print "[SSH Server]", str(e) return 0 - + remotefile = os.path.join(self.remotefolder, os.path.split(fullfilename)[-1]) command = 'chmod 775 %s' %remotefile - + return self.__execute(command) - + class SendToServer(ProcessingUnit): - - def __init__(self): - - ProcessingUnit.__init__(self) - + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + self.isConfig = False self.clientObj = None def setup(self, server, username, password, remotefolder, localfolder, ext='.png', period=60, protocol='ftp', **kwargs): - + self.clientObj = None self.localfolder = localfolder self.ext = ext self.period = period - + if str.lower(protocol) == 'ftp': self.clientObj = FTPClient(server, username, password, remotefolder, period) - + if str.lower(protocol) == 'ssh': self.clientObj = SSHClient(server, username, password, remotefolder, period) - + if not self.clientObj: raise ValueError, "%s has been chosen as remote access protocol but it is not valid" %protocol - + self.clientObj.start() - + def findFiles(self): - + if not type(self.localfolder) == list: folderList = [self.localfolder] else: folderList = self.localfolder - + #Remove duplicate items folderList = list(set(folderList)) - + fullfilenameList = [] - + for thisFolder in folderList: - + print "[Remote Server]: Searching files on %s" %thisFolder - + filenameList = glob.glob1(thisFolder, '*%s' %self.ext) - + if len(filenameList) < 1: + continue - + for thisFile in filenameList: fullfilename = os.path.join(thisFolder, thisFile) - + if fullfilename in fullfilenameList: continue - + #Only files modified in the last 30 minutes are considered if os.path.getmtime(fullfilename) < time.time() - 30*60: continue - + fullfilenameList.append(fullfilename) - + return fullfilenameList - + def run(self, **kwargs): if not self.isConfig: self.init = time.time() @@ -647,53 +648,53 @@ class SendToServer(ProcessingUnit): if time.time() - self.init >= self.period: fullfilenameList = self.findFiles() - + if self.clientObj.updateFileList(fullfilenameList): print "[Remote Server]: Sending the next files ", str(fullfilenameList) self.init = time.time() - + def close(self): print "[Remote Server] Stopping thread" self.clientObj.stop() - - + + class FTP(object): """ Ftp is a public class used to define custom File Transfer Protocol from "ftplib" python module - + Non-standard Python modules used: None - + Written by "Daniel Suarez":mailto:daniel.suarez@jro.igp.gob.pe Oct. 26, 2010 """ - - def __init__(self,server = None, username=None, password=None, remotefolder=None): + + def __init__(self,server = None, username=None, password=None, remotefolder=None): """ This method is used to setting parameters for FTP and establishing connection to remote server - + Inputs: - server - remote server IP Address - - username - remote server Username - + server - remote server IP Address + + username - remote server Username + password - remote server password - + remotefolder - remote server current working directory - + Return: void - - Affects: + + Affects: self.status - in Error Case or Connection Failed this parameter is set to 1 else 0 - + self.folderList - sub-folder list of remote folder - + self.fileList - file list of remote folder - - + + """ - + if ((server == None) and (username==None) and (password==None) and (remotefolder==None)): server, username, password, remotefolder = self.parmsByDefault() - + self.server = server self.username = username self.password = password @@ -701,36 +702,36 @@ class FTP(object): self.file = None self.ftp = None self.status = 0 - + try: self.ftp = ftplib.FTP(self.server) self.ftp.login(self.username,self.password) self.ftp.cwd(self.remotefolder) - # print 'Connect to FTP Server: Successfully' + # print 'Connect to FTP Server: Successfully' except ftplib.all_errors: print 'Error FTP Service' self.status = 1 return - - - + + + self.dirList = [] try: self.dirList = self.ftp.nlst() - + except ftplib.error_perm, resp: if str(resp) == "550 No files found": print "no files in this directory" self.status = 1 return - + except ftplib.all_errors: print 'Error Displaying Dir-Files' self.status = 1 return - + self.fileList = [] self.folderList = [] #only for test @@ -745,85 +746,85 @@ class FTP(object): username = 'wmaster' password = 'mst2010vhf' remotefolder = '/home/wmaster/graficos' - + return server, username, password, remotefolder - - + + def mkd(self,dirname): """ mkd is used to make directory in remote server - + Input: dirname - directory name - + Return: 1 in error case else 0 """ - try: + try: self.ftp.mkd(dirname) except: print 'Error creating remote folder:%s'%dirname return 1 - + return 0 - - + + def delete(self,filename): """ delete is used to delete file in current working directory of remote server - + Input: filename - filename to delete in remote folder - + Return: 1 in error case else 0 """ - + try: self.ftp.delete(filename) except: print 'Error deleting remote file:%s'%filename return 1 - + return 0 - + def download(self,filename,localfolder): """ download is used to downloading file from remote folder into local folder - + Inputs: filename - filename to donwload - + localfolder - directory local to store filename - + Returns: self.status - 1 in error case else 0 """ - + self.status = 0 - - + + if not(filename in self.fileList): print 'filename:%s not exists'%filename self.status = 1 return self.status - + newfilename = os.path.join(localfolder,filename) - - self.file = open(newfilename, 'wb') - + + self.file = open(newfilename, 'wb') + try: - print 'Download: ' + filename + print 'Download: ' + filename self.ftp.retrbinary('RETR ' + filename, self.__handleDownload) print 'Download Complete' except ftplib.all_errors: print 'Error Downloading ' + filename self.status = 1 return self.status - + self.file.close() - - return self.status + + return self.status def __handleDownload(self,block): @@ -831,85 +832,85 @@ class FTP(object): __handleDownload is used to handle writing file """ self.file.write(block) - - + + def upload(self,filename,remotefolder=None): """ upload is used to uploading local file to remote directory - + Inputs: filename - full path name of local file to store in remote directory - - remotefolder - remote directory - + + remotefolder - remote directory + Returns: self.status - 1 in error case else 0 """ - + if remotefolder == None: remotefolder = self.remotefolder - + self.status = 0 - + try: - self.ftp.cwd(remotefolder) - + self.ftp.cwd(remotefolder) + self.file = open(filename, 'rb') - + (head, tail) = os.path.split(filename) - + command = "STOR " + tail - + print 'Uploading: ' + tail - self.ftp.storbinary(command, self.file) + self.ftp.storbinary(command, self.file) print 'Upload Completed' - + except ftplib.all_errors: print 'Error Uploading ' + tail self.status = 1 return self.status - + self.file.close() - + #back to initial directory in __init__() - self.ftp.cwd(self.remotefolder) - - return self.status - - + self.ftp.cwd(self.remotefolder) + + return self.status + + def dir(self,remotefolder): """ dir is used to change working directory of remote server and get folder and file list - + Input: remotefolder - current working directory - + Affects: self.fileList - file list of working directory - - Return: + + Return: infoList - list with filenames and size of file in bytes - + self.folderList - folder list """ - + self.remotefolder = remotefolder print 'Change to ' + self.remotefolder - try: - self.ftp.cwd(remotefolder) + try: + self.ftp.cwd(remotefolder) except ftplib.all_errors: - print 'Error Change to ' + self.remotefolder + print 'Error Change to ' + self.remotefolder infoList = None self.folderList = None return infoList,self.folderList - + self.dirList = [] try: self.dirList = self.ftp.nlst() - + except ftplib.error_perm, resp: - if str(resp) == "550 No files found": + if str(resp) == "550 No files found": print "no files in this directory" infoList = None self.folderList = None @@ -918,91 +919,90 @@ class FTP(object): print 'Error Displaying Dir-Files' infoList = None self.folderList = None - return infoList,self.folderList - - infoList = [] + return infoList,self.folderList + + infoList = [] self.fileList = [] self.folderList = [] for f in self.dirList: name,ext = os.path.splitext(f) - if ext != '': + if ext != '': self.fileList.append(f) value = (f,self.ftp.size(f)) - infoList.append(value) - - if ext == '': + infoList.append(value) + + if ext == '': self.folderList.append(f) - + return infoList,self.folderList - - + + def close(self): """ close is used to close and end FTP connection - + Inputs: None - + Return: void - + """ self.ftp.close() class SendByFTP(Operation): - - def __init__(self): - + + def __init__(self, **kwargs): + Operation.__init__(self, **kwargs) self.status = 1 self.counter = 0 - + def error_print(self, ValueError): - + print ValueError, 'Error FTP' print "don't worry the program is running..." - + def worker_ftp(self, server, username, password, remotefolder, filenameList): - + self.ftpClientObj = FTP(server, username, password, remotefolder) for filename in filenameList: self.ftpClientObj.upload(filename) self.ftpClientObj.close() - + def ftp_thread(self, server, username, password, remotefolder): if not(self.status): return - + import multiprocessing - + p = multiprocessing.Process(target=self.worker_ftp, args=(server, username, password, remotefolder, self.filenameList,)) p.start() - + p.join(3) - + if p.is_alive(): p.terminate() p.join() print 'killing ftp process...' self.status = 0 return - + self.status = 1 return - + def filterByExt(self, ext, localfolder): fnameList = glob.glob1(localfolder,ext) self.filenameList = [os.path.join(localfolder,x) for x in fnameList] if len(self.filenameList) == 0: self.status = 0 - + def run(self, dataOut, ext, localfolder, remotefolder, server, username, password, period=1): - - self.counter += 1 + + self.counter += 1 if self.counter >= period: self.filterByExt(ext, localfolder) - + self.ftp_thread(server, username, password, remotefolder) self.counter = 0 - + self.status = 1 - diff --git a/schainpy/model/utils/jroutils_publish.py b/schainpy/model/utils/jroutils_publish.py index a9088a4..fdd71ab 100644 --- a/schainpy/model/utils/jroutils_publish.py +++ b/schainpy/model/utils/jroutils_publish.py @@ -2,25 +2,57 @@ @author: Juan C. Espinoza ''' +import os +import glob import time import json import numpy import paho.mqtt.client as mqtt import zmq -import cPickle as pickle import datetime +import ftplib from zmq.utils.monitor import recv_monitor_message from functools import wraps from threading import Thread from multiprocessing import Process from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit +from schainpy.model.data.jrodata import JROData +from schainpy.utils import log -throttle_value = 5 +MAXNUMX = 500 +MAXNUMY = 500 -class PrettyFloat(float): - def __repr__(self): - return '%.2f' % self +PLOT_CODES = { + 'rti': 0, # Range time intensity (RTI). + 'spc': 1, # Spectra (and Cross-spectra) information. + 'cspc': 2, # Cross-Correlation information. + 'coh': 3, # Coherence map. + 'base': 4, # Base lines graphic. + 'row': 5, # Row Spectra. + 'total': 6, # Total Power. + 'drift': 7, # Drifts graphics. + 'height': 8, # Height profile. + 'phase': 9, # Signal Phase. + 'power': 16, + 'noise': 17, + 'beacon': 18, + 'wind': 22, + 'skymap': 23, + 'Unknown': 24, + 'V-E': 25, # PIP Velocity. + 'Z-E': 26, # PIP Reflectivity. + 'V-A': 27, # RHI Velocity. + 'Z-A': 28, # RHI Reflectivity. +} + +def get_plot_code(s): + label = s.split('_')[0] + codes = [key for key in PLOT_CODES if key in label] + if codes: + return PLOT_CODES[codes[0]] + else: + return 24 def roundFloats(obj): if isinstance(obj, list): @@ -28,17 +60,14 @@ def roundFloats(obj): elif isinstance(obj, float): return round(obj, 2) -def pretty_floats(obj): - if isinstance(obj, float): - return PrettyFloat(obj) - elif isinstance(obj, dict): - return dict((k, pretty_floats(v)) for k, v in obj.items()) - elif isinstance(obj, (list, tuple)): - return map(pretty_floats, obj) - return obj +def decimate(z, MAXNUMY): + dy = int(len(z[0])/MAXNUMY) + 1 + + return z[::, ::dy] class throttle(object): - """Decorator that prevents a function from being called more than once every + ''' + Decorator that prevents a function from being called more than once every time period. To create a function that cannot be called more than once a minute, but will sleep until it can be called: @@ -49,35 +78,242 @@ class throttle(object): for i in range(10): foo() print "This function has run %s times." % i - """ + ''' def __init__(self, seconds=0, minutes=0, hours=0): self.throttle_period = datetime.timedelta( seconds=seconds, minutes=minutes, hours=hours ) + self.time_of_last_call = datetime.datetime.min def __call__(self, fn): @wraps(fn) def wrapper(*args, **kwargs): - now = datetime.datetime.now() - time_since_last_call = now - self.time_of_last_call - time_left = self.throttle_period - time_since_last_call + coerce = kwargs.pop('coerce', None) + if coerce: + self.time_of_last_call = datetime.datetime.now() + return fn(*args, **kwargs) + else: + now = datetime.datetime.now() + time_since_last_call = now - self.time_of_last_call + time_left = self.throttle_period - time_since_last_call - if time_left > datetime.timedelta(seconds=0): - return + if time_left > datetime.timedelta(seconds=0): + return self.time_of_last_call = datetime.datetime.now() return fn(*args, **kwargs) return wrapper +class Data(object): + ''' + Object to hold data to be plotted + ''' + + def __init__(self, plottypes, throttle_value, exp_code, buffering=True): + self.plottypes = plottypes + self.throttle = throttle_value + self.exp_code = exp_code + self.buffering = buffering + self.ended = False + self.localtime = False + self.meta = {} + self.__times = [] + self.__heights = [] + + def __str__(self): + dum = ['{}{}'.format(key, self.shape(key)) for key in self.data] + return 'Data[{}][{}]'.format(';'.join(dum), len(self.__times)) + + def __len__(self): + return len(self.__times) + + def __getitem__(self, key): + if key not in self.data: + raise KeyError(log.error('Missing key: {}'.format(key))) + + if 'spc' in key or not self.buffering: + ret = self.data[key] + else: + ret = numpy.array([self.data[key][x] for x in self.times]) + if ret.ndim > 1: + ret = numpy.swapaxes(ret, 0, 1) + return ret + + def __contains__(self, key): + return key in self.data + + def setup(self): + ''' + Configure object + ''' + + self.type = '' + self.ended = False + self.data = {} + self.__times = [] + self.__heights = [] + self.__all_heights = set() + for plot in self.plottypes: + if 'snr' in plot: + plot = 'snr' + self.data[plot] = {} + + def shape(self, key): + ''' + Get the shape of the one-element data for the given key + ''' + + if len(self.data[key]): + if 'spc' in key or not self.buffering: + return self.data[key].shape + return self.data[key][self.__times[0]].shape + return (0,) + + def update(self, dataOut, tm): + ''' + Update data object with new dataOut + ''' + + if tm in self.__times: + return + + self.type = dataOut.type + self.parameters = getattr(dataOut, 'parameters', []) + if hasattr(dataOut, 'pairsList'): + self.pairs = dataOut.pairsList + if hasattr(dataOut, 'meta'): + self.meta = dataOut.meta + self.channels = dataOut.channelList + self.interval = dataOut.getTimeInterval() + self.localtime = dataOut.useLocalTime + if 'spc' in self.plottypes or 'cspc' in self.plottypes: + self.xrange = (dataOut.getFreqRange(1)/1000., dataOut.getAcfRange(1), dataOut.getVelRange(1)) + self.__heights.append(dataOut.heightList) + self.__all_heights.update(dataOut.heightList) + self.__times.append(tm) + + for plot in self.plottypes: + if plot == 'spc': + z = dataOut.data_spc/dataOut.normFactor + buffer = 10*numpy.log10(z) + if plot == 'cspc': + buffer = dataOut.data_cspc + if plot == 'noise': + buffer = 10*numpy.log10(dataOut.getNoise()/dataOut.normFactor) + if plot == 'rti': + buffer = dataOut.getPower() + if plot == 'snr_db': + buffer = dataOut.data_SNR + if plot == 'snr': + buffer = 10*numpy.log10(dataOut.data_SNR) + if plot == 'dop': + buffer = 10*numpy.log10(dataOut.data_DOP) + if plot == 'mean': + buffer = dataOut.data_MEAN + if plot == 'std': + buffer = dataOut.data_STD + if plot == 'coh': + buffer = dataOut.getCoherence() + if plot == 'phase': + buffer = dataOut.getCoherence(phase=True) + if plot == 'output': + buffer = dataOut.data_output + if plot == 'param': + buffer = dataOut.data_param + + if 'spc' in plot: + self.data[plot] = buffer + else: + if self.buffering: + self.data[plot][tm] = buffer + else: + self.data[plot] = buffer + + def normalize_heights(self): + ''' + Ensure same-dimension of the data for different heighList + ''' + + H = numpy.array(list(self.__all_heights)) + H.sort() + for key in self.data: + shape = self.shape(key)[:-1] + H.shape + for tm, obj in self.data[key].items(): + h = self.__heights[self.__times.index(tm)] + if H.size == h.size: + continue + index = numpy.where(numpy.in1d(H, h))[0] + dummy = numpy.zeros(shape) + numpy.nan + if len(shape) == 2: + dummy[:, index] = obj + else: + dummy[index] = obj + self.data[key][tm] = dummy + + self.__heights = [H for tm in self.__times] + + def jsonify(self, decimate=False): + ''' + Convert data to json + ''' + + data = {} + tm = self.times[-1] + dy = int(self.heights.size/MAXNUMY) + 1 + for key in self.data: + if key in ('spc', 'cspc') or not self.buffering: + dx = int(self.data[key].shape[1]/MAXNUMX) + 1 + data[key] = roundFloats(self.data[key][::, ::dx, ::dy].tolist()) + else: + data[key] = roundFloats(self.data[key][tm].tolist()) + + ret = {'data': data} + ret['exp_code'] = self.exp_code + ret['time'] = tm + ret['interval'] = self.interval + ret['localtime'] = self.localtime + ret['yrange'] = roundFloats(self.heights[::dy].tolist()) + if 'spc' in self.data or 'cspc' in self.data: + ret['xrange'] = roundFloats(self.xrange[2][::dx].tolist()) + else: + ret['xrange'] = [] + if hasattr(self, 'pairs'): + ret['pairs'] = self.pairs + else: + ret['pairs'] = [] + + for key, value in self.meta.items(): + ret[key] = value + + return json.dumps(ret) + + @property + def times(self): + ''' + Return the list of times of the current data + ''' + + ret = numpy.array(self.__times) + ret.sort() + return ret + + @property + def heights(self): + ''' + Return the list of heights of the current data + ''' + + return numpy.array(self.__heights[-1]) class PublishData(Operation): - """Clase publish.""" + ''' + Operation to send data over zmq. + ''' - __MAXNUMX = 100 - __MAXNUMY = 100 + __attrs__ = ['host', 'port', 'delay', 'zeromq', 'mqtt', 'verbose'] def __init__(self, **kwargs): """Inicio.""" @@ -89,18 +325,17 @@ class PublishData(Operation): def on_disconnect(self, client, userdata, rc): if rc != 0: - print("Unexpected disconnection.") + log.warning('Unexpected disconnection.') self.connect() def connect(self): - print 'trying to connect' + log.warning('trying to connect') try: self.client.connect( host=self.host, port=self.port, keepalive=60*10, bind_address='') - print "connected" self.client.loop_start() # self.client.publish( # self.topic + 'SETUP', @@ -108,10 +343,10 @@ class PublishData(Operation): # retain=True # ) except: - print "MQTT Conection error." + log.error('MQTT Conection error.') self.client = False - def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, **kwargs): + def setup(self, port=1883, username=None, password=None, clientId="user", zeromq=1, verbose=True, **kwargs): self.counter = 0 self.topic = kwargs.get('topic', 'schain') self.delay = kwargs.get('delay', 0) @@ -123,9 +358,9 @@ class PublishData(Operation): self.zeromq = zeromq self.mqtt = kwargs.get('plottype', 0) self.client = None + self.verbose = verbose setup = [] if mqtt is 1: - print 'mqqt es 1' self.client = mqtt.Client( client_id=self.clientId + self.topic + 'SCHAIN', clean_session=True) @@ -146,15 +381,14 @@ class PublishData(Operation): context = zmq.Context() self.zmq_socket = context.socket(zmq.PUSH) server = kwargs.get('server', 'zmq.pipe') - + if 'tcp://' in server: address = server else: address = 'ipc:///tmp/%s' % server - + self.zmq_socket.connect(address) time.sleep(1) - print 'zeromq configured' def publish_data(self): @@ -166,8 +400,8 @@ class PublishData(Operation): z = data/self.dataOut.normFactor zdB = 10*numpy.log10(z) xlen, ylen = zdB[0].shape - dx = numpy.floor(xlen/self.__MAXNUMX) + 1 - dy = numpy.floor(ylen/self.__MAXNUMY) + 1 + dx = int(xlen/MAXNUMX) + 1 + dy = int(ylen/MAXNUMY) + 1 Z = [0 for i in self.dataOut.channelList] for i in self.dataOut.channelList: Z[i] = zdB[i][::dx, ::dy].tolist() @@ -179,7 +413,6 @@ class PublishData(Operation): 'type': self.plottype, 'yData': yData } - # print payload elif self.plottype in ('rti', 'power'): data = getattr(self.dataOut, 'data_spc') @@ -233,11 +466,15 @@ class PublishData(Operation): 'timestamp': 'None', 'type': None } - # print 'Publishing data to {}'.format(self.host) + self.client.publish(self.topic + self.plottype, json.dumps(payload), qos=0) if self.zeromq is 1: - print '[Sending] {} - {}'.format(self.dataOut.type, self.dataOut.datatime) + if self.verbose: + log.log( + 'Sending {} - {}'.format(self.dataOut.type, self.dataOut.datatime), + self.name + ) self.zmq_socket.send_pyobj(self.dataOut) def run(self, dataOut, **kwargs): @@ -253,7 +490,375 @@ class PublishData(Operation): if self.zeromq is 1: self.dataOut.finished = True self.zmq_socket.send_pyobj(self.dataOut) - + time.sleep(0.1) + self.zmq_socket.close() if self.client: self.client.loop_stop() self.client.disconnect() + + +class ReceiverData(ProcessingUnit): + + __attrs__ = ['server'] + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + + self.isConfig = False + server = kwargs.get('server', 'zmq.pipe') + if 'tcp://' in server: + address = server + else: + address = 'ipc:///tmp/%s' % server + + self.address = address + self.dataOut = JROData() + + def setup(self): + + self.context = zmq.Context() + self.receiver = self.context.socket(zmq.PULL) + self.receiver.bind(self.address) + time.sleep(0.5) + log.success('ReceiverData from {}'.format(self.address)) + + + def run(self): + + if not self.isConfig: + self.setup() + self.isConfig = True + + self.dataOut = self.receiver.recv_pyobj() + log.log('{} - {}'.format(self.dataOut.type, + self.dataOut.datatime.ctime(),), + 'Receiving') + + +class PlotterReceiver(ProcessingUnit, Process): + + throttle_value = 5 + __attrs__ = ['server', 'plottypes', 'realtime', 'localtime', 'throttle', + 'exp_code', 'web_server', 'buffering'] + + def __init__(self, **kwargs): + + ProcessingUnit.__init__(self, **kwargs) + Process.__init__(self) + self.mp = False + self.isConfig = False + self.isWebConfig = False + self.connections = 0 + server = kwargs.get('server', 'zmq.pipe') + web_server = kwargs.get('web_server', None) + if 'tcp://' in server: + address = server + else: + address = 'ipc:///tmp/%s' % server + self.address = address + self.web_address = web_server + self.plottypes = [s.strip() for s in kwargs.get('plottypes', 'rti').split(',')] + self.realtime = kwargs.get('realtime', False) + self.localtime = kwargs.get('localtime', True) + self.buffering = kwargs.get('buffering', True) + self.throttle_value = kwargs.get('throttle', 5) + self.exp_code = kwargs.get('exp_code', None) + self.sendData = self.initThrottle(self.throttle_value) + self.dates = [] + self.setup() + + def setup(self): + + self.data = Data(self.plottypes, self.throttle_value, self.exp_code, self.buffering) + self.isConfig = True + + def event_monitor(self, monitor): + + events = {} + + for name in dir(zmq): + if name.startswith('EVENT_'): + value = getattr(zmq, name) + events[value] = name + + while monitor.poll(): + evt = recv_monitor_message(monitor) + if evt['event'] == 32: + self.connections += 1 + if evt['event'] == 512: + pass + + evt.update({'description': events[evt['event']]}) + + if evt['event'] == zmq.EVENT_MONITOR_STOPPED: + break + monitor.close() + print('event monitor thread done!') + + def initThrottle(self, throttle_value): + + @throttle(seconds=throttle_value) + def sendDataThrottled(fn_sender, data): + fn_sender(data) + + return sendDataThrottled + + def send(self, data): + log.log('Sending {}'.format(data), self.name) + self.sender.send_pyobj(data) + + def run(self): + + log.log( + 'Starting from {}'.format(self.address), + self.name + ) + + self.context = zmq.Context() + self.receiver = self.context.socket(zmq.PULL) + self.receiver.bind(self.address) + monitor = self.receiver.get_monitor_socket() + self.sender = self.context.socket(zmq.PUB) + if self.web_address: + log.success( + 'Sending to web: {}'.format(self.web_address), + self.name + ) + self.sender_web = self.context.socket(zmq.REQ) + self.sender_web.connect(self.web_address) + self.poll = zmq.Poller() + self.poll.register(self.sender_web, zmq.POLLIN) + time.sleep(1) + + if 'server' in self.kwargs: + self.sender.bind("ipc:///tmp/{}.plots".format(self.kwargs['server'])) + else: + self.sender.bind("ipc:///tmp/zmq.plots") + + time.sleep(2) + + t = Thread(target=self.event_monitor, args=(monitor,)) + t.start() + + while True: + dataOut = self.receiver.recv_pyobj() + if not dataOut.flagNoData: + if dataOut.type == 'Parameters': + tm = dataOut.utctimeInit + else: + tm = dataOut.utctime + if dataOut.useLocalTime: + if not self.localtime: + tm += time.timezone + dt = datetime.datetime.fromtimestamp(tm).date() + else: + if self.localtime: + tm -= time.timezone + dt = datetime.datetime.utcfromtimestamp(tm).date() + coerce = False + if dt not in self.dates: + if self.data: + self.data.ended = True + self.send(self.data) + coerce = True + self.data.setup() + self.dates.append(dt) + + self.data.update(dataOut, tm) + + if dataOut.finished is True: + self.connections -= 1 + if self.connections == 0 and dt in self.dates: + self.data.ended = True + self.send(self.data) + # self.data.setup() + time.sleep(1) + break + else: + if self.realtime: + self.send(self.data) + if self.web_address: + retries = 5 + while True: + self.sender_web.send(self.data.jsonify()) + socks = dict(self.poll.poll(5000)) + if socks.get(self.sender_web) == zmq.POLLIN: + reply = self.sender_web.recv_string() + if reply == 'ok': + break + else: + print("Malformed reply from server: %s" % reply) + + else: + print("No response from server, retrying...") + self.sender_web.setsockopt(zmq.LINGER, 0) + self.sender_web.close() + self.poll.unregister(self.sender_web) + retries -= 1 + if retries == 0: + print("Server seems to be offline, abandoning") + break + self.sender_web = self.context.socket(zmq.REQ) + self.sender_web.connect(self.web_address) + self.poll.register(self.sender_web, zmq.POLLIN) + time.sleep(1) + else: + self.sendData(self.send, self.data, coerce=coerce) + coerce = False + + return + + +class SendToFTP(Operation, Process): + + ''' + Operation to send data over FTP. + ''' + + __attrs__ = ['server', 'username', 'password', 'patterns', 'timeout'] + + def __init__(self, **kwargs): + ''' + patterns = [(local1, remote1, ext, delay, exp_code, sub_exp_code), ...] + ''' + Operation.__init__(self, **kwargs) + Process.__init__(self) + self.server = kwargs.get('server') + self.username = kwargs.get('username') + self.password = kwargs.get('password') + self.patterns = kwargs.get('patterns') + self.timeout = kwargs.get('timeout', 30) + self.times = [time.time() for p in self.patterns] + self.latest = ['' for p in self.patterns] + self.mp = False + self.ftp = None + + def setup(self): + + log.log('Connecting to ftp://{}'.format(self.server), self.name) + try: + self.ftp = ftplib.FTP(self.server, timeout=self.timeout) + except ftplib.all_errors: + log.error('Server connection fail: {}'.format(self.server), self.name) + if self.ftp is not None: + self.ftp.close() + self.ftp = None + self.isConfig = False + return + + try: + self.ftp.login(self.username, self.password) + except ftplib.all_errors: + log.error('The given username y/o password are incorrect', self.name) + if self.ftp is not None: + self.ftp.close() + self.ftp = None + self.isConfig = False + return + + log.success('Connection success', self.name) + self.isConfig = True + return + + def check(self): + + try: + self.ftp.voidcmd("NOOP") + except: + log.warning('Connection lost... trying to reconnect', self.name) + if self.ftp is not None: + self.ftp.close() + self.ftp = None + self.setup() + + def find_files(self, path, ext): + + files = glob.glob1(path, '*{}'.format(ext)) + files.sort() + if files: + return files[-1] + return None + + def getftpname(self, filename, exp_code, sub_exp_code): + + thisDatetime = datetime.datetime.strptime(filename.split('_')[1], '%Y%m%d') + YEAR_STR = '%4.4d'%thisDatetime.timetuple().tm_year + DOY_STR = '%3.3d'%thisDatetime.timetuple().tm_yday + exp_code = '%3.3d'%exp_code + sub_exp_code = '%2.2d'%sub_exp_code + plot_code = '%2.2d'% get_plot_code(filename) + name = YEAR_STR + DOY_STR + '00' + exp_code + sub_exp_code + plot_code + '00.png' + return name + + def upload(self, src, dst): + + log.log('Uploading {} '.format(src), self.name, nl=False) + + fp = open(src, 'rb') + command = 'STOR {}'.format(dst) + + try: + self.ftp.storbinary(command, fp, blocksize=1024) + except Exception, e: + log.error('{}'.format(e), self.name) + if self.ftp is not None: + self.ftp.close() + self.ftp = None + return 0 + + try: + self.ftp.sendcmd('SITE CHMOD 755 {}'.format(dst)) + except Exception, e: + log.error('{}'.format(e), self.name) + if self.ftp is not None: + self.ftp.close() + self.ftp = None + return 0 + + fp.close() + log.success('OK', tag='') + return 1 + + def send_files(self): + + for x, pattern in enumerate(self.patterns): + local, remote, ext, delay, exp_code, sub_exp_code = pattern + if time.time()-self.times[x] >= delay: + srcname = self.find_files(local, ext) + src = os.path.join(local, srcname) + if os.path.getmtime(src) < time.time() - 30*60: + continue + + if srcname is None or srcname == self.latest[x]: + continue + + if 'png' in ext: + dstname = self.getftpname(srcname, exp_code, sub_exp_code) + else: + dstname = srcname + + dst = os.path.join(remote, dstname) + + if self.upload(src, dst): + self.times[x] = time.time() + self.latest[x] = srcname + else: + self.isConfig = False + break + + def run(self): + + while True: + if not self.isConfig: + self.setup() + if self.ftp is not None: + self.check() + self.send_files() + time.sleep(10) + + def close(): + + if self.ftp is not None: + self.ftp.close() + self.terminate() diff --git a/schainpy/scripts/150km_January_longPulse.py b/schainpy/scripts/150km_January_longPulse.py deleted file mode 100644 index 9a27226..0000000 --- a/schainpy/scripts/150km_January_longPulse.py +++ /dev/null @@ -1,185 +0,0 @@ -import os, sys -import numpy -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.append(path) - -from schainpy.controller import Project - -desc = "150 km Jicamarca January 2015" -filename = "150km_jicamarca.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#path = '/home/operaciones/150km_jicamarca_january/RAW_EXP/2015_ISR' -path = '/media/DATOS/2015_ISR' -#path = '/media/New Volume2/DATA/RAW_EXP/2015_ISR' - -figpath = '/home/operaciones/Pictures/150km_jicamarca_january' - -remotefolder = "/home/wmaster/graficos" - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/13', - endDate='2015/01/30', - startTime='07:55:00', - endTime='23:59:59', - online=0, - delay=10, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -a=[] -for i in range(85): - if i>20: - a.append(i) -for i in range(170): - if i>105: - a.append(i) -for i in range(255): - if i>190: - a.append(i) -for i in range(340): - if 339>i>275: - a.append(i) - if i==339: - a.append(i) - -b= str(a) -profileIndex = b[1:][:-1] - -opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -#profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19' -opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') - - -# opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -# opObj11.addParameter(name='profileRangeList', value='21,84', format='intlist') - - -binary28="1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1" - - -CODEB=numpy.array([1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1]) -x= numpy.array([ CODEB,CODEB,-CODEB,-CODEB]) -code= ",".join(map(str,x.flatten())) - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='intlist') -opObj11.addParameter(name='nCode', value='4', format='int') -opObj11.addParameter(name='nBaud', value='28', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='deFlip') -opObj11.addParameter(name='channelList', value='1,3,5,7', format='intlist') - -# opObj10 = procUnitConfObj0.addOperation(name='selectHeights') -# opObj10.addParameter(name='minHei', value='50', format='float') -# opObj10.addParameter(name='maxHei', value='150', format='float') - -# opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='4', format='float') - - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='Voltage', format='str') -# opObj11.addParameter(name='zmin', value='40', format='int') -# opObj11.addParameter(name='zmax', value='90', format='int') - -#opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='64', format='int') - -#procUnitConfObj1.addParameter(name='pairsList', value='(3,7),(2,6)', format='pairsList') -procUnitConfObj1.addParameter(name='pairsList', value='(1,0),(3,2),(5,4),(7,6)', format='pairsList') - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='60', format='float') - -# opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='2001', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca', format='str') -# #opObj11.addParameter(name='channelList', value='0,1,2,3,45', format='intlist') -# # opObj11.addParameter(name='zmin', value='0', format='int') -# # opObj11.addParameter(name='zmax', value='60', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -opObj11.addParameter(name='id', value='2005', format='int') -opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_LongPulse', format='str') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='80', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='exp_code', value='13', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath) -opObj11.addParameter(name='ftp', value='1', format='int') - - - - - -opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='Coherence', format='str') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') - -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='exp_code', value='13', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath) -opObj11.addParameter(name='ftp', value='1', format='int') - - - - - - - -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='3002', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca_LongPulse', format='str') -# # opObj11.addParameter(name='xmin', value='20.5', format='float') -# # opObj11.addParameter(name='xmax', value='24', format='float') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='80', format='int') -# #opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -# #opObj11.addParameter(name='channelList', value='0,1,2,3,4,5,6,7', format='intlist') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=figpath, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value=60, format='int') -procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/150km_January_shortPulse.py b/schainpy/scripts/150km_January_shortPulse.py deleted file mode 100644 index f82449e..0000000 --- a/schainpy/scripts/150km_January_shortPulse.py +++ /dev/null @@ -1,152 +0,0 @@ -import os, sys -import numpy -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.append(path) - -from schainpy.controller import Project - -desc = "150 km Jicamarca January 2015" -filename = "150km_jicamarca.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#path = '/home/operaciones/150km_jicamarca_january/RAW_EXP/2015_ISR' -path = '/media/DATOS/2015_ISR' -#path = '/media/New Volume2/DATA/RAW_EXP/2015_ISR' - -figpath = '/home/operaciones/Pictures/150km_jicamarca_january' - -remotefolder = "/home/wmaster/graficos" - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/14', - endDate='2015/01/30', - startTime='07:40:00', - endTime='23:59:59', - online=0, - delay=10, - walk=1, - nTxs=4) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='rangeList', value='(1,80),(341,420),(681,760),(1021,1100)', format='multiList') - -# opObj11 = procUnitConfObj0.addOperation(name='filterByHeights') -# opObj11.addParameter(name='window', value='1', format='int') -# opObj11.addParameter(name='axis', value='2', format='int') - -cod7barker="1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1" -# 1,1,1,-1,-1,1,-1 -#-1,-1,-1,1,1,-1,1 -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=cod7barker, format='floatlist') -opObj11.addParameter(name='nCode', value='4', format='int') -opObj11.addParameter(name='nBaud', value='7', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='deFlip') -opObj11.addParameter(name='channelList', value='1,3,5,7', format='intlist') - -# cod7barker="1,1,1,-1,-1,1,-1" -# opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -# opObj11.addParameter(name='code', value=cod7barker, format='intlist') -# opObj11.addParameter(name='nCode', value='1', format='int') -# opObj11.addParameter(name='nBaud', value='7', format='int') - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='Voltage', format='str') -# opObj11.addParameter(name='zmin', value='40', format='int') -# opObj11.addParameter(name='zmax', value='90', format='int') - -#opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='80', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='80', format='int') -#procUnitConfObj1.addParameter(name='pairsList', value='(3,7),(2,6)', format='pairsList') -procUnitConfObj1.addParameter(name='pairsList', value='(1,0),(3,2),(5,4),(7,6)', format='pairsList') - -# -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='60', format='float') -# -# opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='2004', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca_ShortPulse', format='str') -# #opObj11.addParameter(name='channelList', value='0,1,2,3,45', format='intlist') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -opObj11.addParameter(name='id', value='2006', format='int') -opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_ShortPulse', format='str') -opObj11.addParameter(name='coherence_cmap', value='jet', format='str') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') -# opObj11.addParameter(name='ymin', value='0', format='int') -# opObj11.addParameter(name='ymax', value='105', format='int') -opObj11.addParameter(name='zmin', value='15', format='int') -opObj11.addParameter(name='zmax', value='45', format='int') -opObj11.addParameter(name='exp_code', value='14', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath) -opObj11.addParameter(name='ftp', value='1', format='int') - -# -opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -opObj11.addParameter(name='id', value='102', format='int') -opObj11.addParameter(name='wintitle', value='Coherence', format='str') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='14', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath) -opObj11.addParameter(name='ftp', value='1', format='int') - - -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='3005', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca_ShortPulse', format='str') -# # opObj11.addParameter(name='xmin', value='20.5', format='float') -# # opObj11.addParameter(name='xmax', value='24', format='float') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') -# #opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -# #opObj11.addParameter(name='channelList', value='0,1,2,3,4,5,6,7', format='intlist') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=figpath, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value=60, format='int') -procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/150km_january_1.py b/schainpy/scripts/150km_january_1.py deleted file mode 100644 index 99680bf..0000000 --- a/schainpy/scripts/150km_january_1.py +++ /dev/null @@ -1,119 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "150 km Jicamarca January 2015" -filename = "150km_jicamarca.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/home/operaciones/150km_jicamarca_january/RAW_EXP/2015_ISR' - -figpath = '/home/operaciones/Pictures/150km_jicamarca_january' - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/13', - endDate='2015/01/30', - startTime='07:55:00', - endTime='23:59:59', - online=1, - delay=10, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='profileRangeList', value='21,84', format='intlist') - - -binary28="1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1" - -#cod7barker="1,1,1,-1,-1,1,-1" -#cod7barkerneg="-1,-1,-1,1,1,-1,1" -CODEB=numpy.array([1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1]) -x= numpy.array([ CODEB,CODEB,-CODEB,-CODEB]) -code= ",".join(map(str,x.flatten())) - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='intlist') -opObj11.addParameter(name='nCode', value='4', format='int') -opObj11.addParameter(name='nBaud', value='28', format='int') - -# opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='4', format='float') - - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='Voltage', format='str') - - - -# opObj11.addParameter(name='zmin', value='40', format='int') -# opObj11.addParameter(name='zmax', value='90', format='int') - -#opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='64', format='int') - -#procUnitConfObj1.addParameter(name='pairsList', value='(0,1),(2,3),(4,5),(6,7)', format='pairsList') - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='10', format='float') - -opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='2001', format='int') -opObj11.addParameter(name='wintitle', value='150km_Jicamarca', format='str') -#opObj11.addParameter(name='channelList', value='0,1,2,3,45', format='intlist') -# opObj11.addParameter(name='zmin', value='0', format='int') -# opObj11.addParameter(name='zmax', value='60', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='exp_code', value='13', format='int') - - - -# opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='2005', format='int') -# opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_ShortPulse', format='str') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -# -opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='3002', format='int') -opObj11.addParameter(name='wintitle', value='150km_Jicamarca', format='str') -# opObj11.addParameter(name='xmin', value='20.5', format='float') -# opObj11.addParameter(name='xmax', value='24', format='float') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') -#opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -#opObj11.addParameter(name='channelList', value='0,1,2,3,4,5,6,7', format='intlist') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='exp_code', value='13', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/150km_january_3.py b/schainpy/scripts/150km_january_3.py deleted file mode 100644 index fe56f3e..0000000 --- a/schainpy/scripts/150km_january_3.py +++ /dev/null @@ -1,128 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "150 km Jicamarca January 2015" -filename = "150km_jicamarca.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = './' - -figpath = '/Users/miguel/tmp' - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/14', - endDate='2015/01/14', - startTime='08:30:00', - endTime='09:30:59', - online=1, - delay=10, - walk=1, - nTxs = 4) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='rangeList', value='(1,80),(341,420),(681,760),(1021,1100)', format='multiList') - - -cod7barker="1,1,1,-1,-1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1" - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=cod7barker, format='floatlist') -opObj11.addParameter(name='nCode', value='4', format='int') -opObj11.addParameter(name='nBaud', value='7', format='int') -# -opObj11 = procUnitConfObj0.addOperation(name='deFlip') -opObj11.addParameter(name='channelList', value='1,3,5,7', format='intlist') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='80', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='80', format='int') -procUnitConfObj1.addParameter(name='pairsList', value='(1,0),(3,2),(5,4),(7,6)', format='pairsList') -# -# # -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='60', format='float') -# -# opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='2004', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca_ShortPulse', format='str') -# #opObj11.addParameter(name='channelList', value='0,1,2,3,45', format='intlist') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - -# -opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -opObj11.addParameter(name='id', value='2006', format='int') -opObj11.addParameter(name='wintitle', value='CrossSpectraPlot_ShortPulse', format='str') -opObj11.addParameter(name='ymin', value='0', format='int') -opObj11.addParameter(name='ymax', value='105', format='int') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') -opObj11.addParameter(name='zmin', value='15', format='int') -opObj11.addParameter(name='zmax', value='45', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='exp_code', value='13', format='int') -# -# -opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -opObj11.addParameter(name='id', value='102', format='int') -opObj11.addParameter(name='wintitle', value='Coherence', format='str') -opObj11.addParameter(name='phase_cmap', value='jet', format='str') -opObj11.addParameter(name='xmin', value='8.5', format='float') -opObj11.addParameter(name='xmax', value='9.5', format='float') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='save', value=1, format='bool') -opObj11.addParameter(name='pairsList', value='(1,0),(3,2)', format='pairsList') - -# opObj11.addParameter(name='wr_period', value='2', format='int') - -# opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -# opObj11.addParameter(name='id', value='103', format='int') -# opObj11.addParameter(name='wintitle', value='Coherence', format='str') -# opObj11.addParameter(name='phase_cmap', value='jet', format='str') -# opObj11.addParameter(name='xmin', value='8.5', format='float') -# opObj11.addParameter(name='xmax', value='9.5', format='float') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='save', value=1, format='bool') -# opObj11.addParameter(name='pairsList', value='(5,4),(7,6)', format='pairsList') - -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='3005', format='int') -# opObj11.addParameter(name='wintitle', value='150km_Jicamarca_ShortPulse', format='str') -# # opObj11.addParameter(name='xmin', value='20.5', format='float') -# # opObj11.addParameter(name='xmax', value='24', format='float') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') -#opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -#opObj11.addParameter(name='channelList', value='0,1,2,3,4,5,6,7', format='intlist') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='exp_code', value='13', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/150km_jicamarca.xml b/schainpy/scripts/150km_jicamarca.xml deleted file mode 100644 index cceca18..0000000 --- a/schainpy/scripts/150km_jicamarca.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/schainpy/scripts/EWDrifts_estimation01.py b/schainpy/scripts/EWDrifts_estimation01.py deleted file mode 100644 index dbb9449..0000000 --- a/schainpy/scripts/EWDrifts_estimation01.py +++ /dev/null @@ -1,140 +0,0 @@ -# DIAS 19 Y 20 FEB 2014 -# Comprobacion de Resultados DBS con SA - -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -path = '/host/Jicamarca/EW_Drifts/d2012248' -pathFigure = '/home/propietario/workspace/Graficos/drifts' - - -path = "/home/soporte/Data/drifts" -pathFigure = '/home/soporte/workspace/Graficos/drifts/prueba' -pathFile = '/home/soporte/Data/drifts/HDF5' - -xmin = 0 -xmax = 24 -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2012/09/06', - endDate='2012/09/06', - startTime='00:00:00', - endTime='23:59:59', - online=0, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='profileRangeList', value='0,127', format='intlist') - -opObj11 = procUnitConfObj0.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='3', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -# opObj11.addParameter(name='code', value='1,-1', format='floatlist') -# opObj11.addParameter(name='nCode', value='2', format='int') -# opObj11.addParameter(name='nBaud', value='1', format='int') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='128', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='128', format='int') -procUnitConfObj1.addParameter(name='pairsList', value='(0,1),(2,3)', format='pairsList')#,(2,3) - -opObj11 = procUnitConfObj1.addOperation(name='selectHeights') -# # opObj11.addParameter(name='minHei', value='320.0', format='float') -# # opObj11.addParameter(name='maxHei', value='350.0', format='float') -opObj11.addParameter(name='minHei', value='200.0', format='float') -opObj11.addParameter(name='maxHei', value='600.0', format='float') - -opObj11 = procUnitConfObj1.addOperation(name='selectChannels') -opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='300.0', format='float') - -opObj13 = procUnitConfObj1.addOperation(name='removeDC') - -# opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj14.addParameter(name='id', value='1', format='int') -# # opObj14.addParameter(name='wintitle', value='Con interf', format='str') -# opObj14.addParameter(name='save', value='1', format='bool') -# opObj14.addParameter(name='figpath', value=pathFigure, format='str') -# # opObj14.addParameter(name='zmin', value='5', format='int') -# opObj14.addParameter(name='zmax', value='30', format='int') -# -# opObj12 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj12.addParameter(name='id', value='2', format='int') -# opObj12.addParameter(name='wintitle', value='RTI Plot', format='str') -# opObj12.addParameter(name='save', value='1', format='bool') -# opObj12.addParameter(name='figpath', value = pathFigure, format='str') -# opObj12.addParameter(name='xmin', value=xmin, format='float') -# opObj12.addParameter(name='xmax', value=xmax, format='float') -# # opObj12.addParameter(name='zmin', value='5', format='int') -# opObj12.addParameter(name='zmax', value='30', format='int') - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -opObj20 = procUnitConfObj2.addOperation(name='SpectralFitting') -opObj20.addParameter(name='path', value='/home/soporte/workspace/RemoteSystemsTempFiles', format='str') -opObj20.addParameter(name='file', value='modelSpectralFitting', format='str') -opObj20.addParameter(name='groupList', value='(0,1),(2,3)',format='multiList') - -opObj11 = procUnitConfObj2.addOperation(name='SpectralFittingPlot', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -opObj11.addParameter(name='wintitle', value='DopplerPlot', format='str') -opObj11.addParameter(name='cutHeight', value='350', format='int') -opObj11.addParameter(name='fit', value='1', format='int')#1--True/include fit -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = pathFigure, format='str') - -opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -opObj12.addParameter(name='path', value=pathFile) -opObj12.addParameter(name='blocksPerFile', value='3', format='int') - -opObj11 = procUnitConfObj2.addOperation(name='EWDriftsEstimation', optype='other') -opObj11.addParameter(name='zenith', value='-3.80208,3.10658', format='floatlist') -opObj11.addParameter(name='zenithCorrection', value='0.183201', format='float') - -opObj23 = procUnitConfObj2.addOperation(name='EWDriftsPlot', optype='other') -opObj23.addParameter(name='id', value='4', format='int') -opObj23.addParameter(name='wintitle', value='EW Drifts', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathFigure, format='str') -opObj23.addParameter(name='zminZonal', value='-150', format='int') -opObj23.addParameter(name='zmaxZonal', value='150', format='int') -opObj23.addParameter(name='zminVertical', value='-30', format='float') -opObj23.addParameter(name='zmaxVertical', value='30', format='float') -opObj23.addParameter(name='SNR_1', value='1', format='bool') -opObj23.addParameter(name='SNRmax', value='5', format='int') -# opObj23.addParameter(name='SNRthresh', value='-50', format='float') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') -#-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/EWDrifts_estimation02.py b/schainpy/scripts/EWDrifts_estimation02.py deleted file mode 100644 index 8980f9d..0000000 --- a/schainpy/scripts/EWDrifts_estimation02.py +++ /dev/null @@ -1,65 +0,0 @@ -# DIAS 19 Y 20 FEB 2014 -# Comprobacion de Resultados DBS con SA - -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -path = "/home/soporte/Data/drifts/HDF5" -pathFigure = '/home/soporte/workspace/Graficos/drifts/prueba' -pathFile = '/home/soporte/Data/drifts/HDF5' - -xmin = 0 -xmax = 24 -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='HDF5Reader', - path=path, - startDate='2012/09/06', - endDate='2012/09/06', - startTime='00:00:00', - endTime='23:59:59', - timezone='lt', - walk=1) - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) -#-------------------------------------------------------------------------------------------------- - -opObj11 = procUnitConfObj0.addOperation(name='EWDriftsEstimation', optype='other') -opObj11.addParameter(name='zenith', value='-3.80208,3.10658', format='floatlist') -opObj11.addParameter(name='zenithCorrection', value='0.183201', format='float') - -opObj23 = procUnitConfObj0.addOperation(name='EWDriftsPlot', optype='other') -opObj23.addParameter(name='id', value='4', format='int') -opObj23.addParameter(name='wintitle', value='EW Drifts', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathFigure, format='str') -opObj23.addParameter(name='zminZonal', value='-150', format='int') -opObj23.addParameter(name='zmaxZonal', value='150', format='int') -opObj23.addParameter(name='zminVertical', value='-30', format='float') -opObj23.addParameter(name='zmaxVertical', value='30', format='float') -opObj23.addParameter(name='SNR_1', value='1', format='bool') -opObj23.addParameter(name='SNRmax', value='5', format='int') -# opObj23.addParameter(name='SNRthresh', value='-50', format='float') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') -#-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/JASMET30_MetDet.py b/schainpy/scripts/JASMET30_MetDet.py index 870f1f0..106a7a8 100644 --- a/schainpy/scripts/JASMET30_MetDet.py +++ b/schainpy/scripts/JASMET30_MetDet.py @@ -1,11 +1,6 @@ import os, sys -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - from schainpy.controller import Project controllerObj = Project() @@ -18,7 +13,7 @@ controllerObj.setup(id = '002', name='script02', description="JASMET Meteor Dete # path = '/mnt/jars/2016_08/NOCHE' # path = '/media/joscanoa/DATA_JASMET/JASMET/2016_08/DIA' # path = '/media/joscanoa/DATA_JASMET/JASMET/2016_08/NOCHE' -path = '/media/joscanoa/DATA_JASMET/JASMET/2016_08/DIA' +path = '/home/nanosat/data/jasmet' #Path para los graficos pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/graphics') @@ -27,8 +22,8 @@ pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/graphics') pathfile = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/meteor') #Fechas para busqueda de archivos -startDate = '2016/08/29' -endDate = '2016/09/11' +startDate = '2010/08/29' +endDate = '2017/09/11' #Horas para busqueda de archivos startTime = '00:00:00' endTime = '23:59:59' @@ -60,15 +55,23 @@ opObj00.addParameter(name='channelList', value='0,1,2,3,4', format='intlist') opObj01 = procUnitConfObj0.addOperation(name='setRadarFrequency') opObj01.addParameter(name='frequency', value='30.e6', format='float') -opObj01 = procUnitConfObj0.addOperation(name='interpolateHeights') -opObj01.addParameter(name='topLim', value='73', format='int') -opObj01.addParameter(name='botLim', value='71', format='int') +# opObj01 = procUnitConfObj0.addOperation(name='interpolateHeights') +# opObj01.addParameter(name='topLim', value='73', format='int') +# opObj01.addParameter(name='botLim', value='71', format='int') opObj02 = procUnitConfObj0.addOperation(name='Decoder', optype='other') opObj03 = procUnitConfObj0.addOperation(name='CohInt', optype='other') opObj03.addParameter(name='n', value='2', format='int') +procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) +opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') +opObj11.addParameter(name='id', value='237', format='int') +opObj11.addParameter(name='xmin', value='9.0', format='float') +opObj11.addParameter(name='xmax', value='16.0', format='float') +opObj11.addParameter(name='zmin', value='15.0', format='float') +opObj11.addParameter(name='zmax', value='50.0', format='float') + #--------------------------- Parameters Processing Unit ------------------------------------ procUnitConfObj1 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj0.getId()) @@ -84,14 +87,9 @@ opObj12.addParameter(name='blocksPerFile', value='1000', format='int') opObj12.addParameter(name='metadataList',value='type,heightList,paramInterval,timeZone',format='list') opObj12.addParameter(name='dataList',value='data_param,utctime',format='list') opObj12.addParameter(name='mode',value='2',format='int') - + #-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml("JASMET02.xml") -print "Leyendo el archivo XML" -controllerObj.readXml("JASMET02.xml") +controllerObj.start() + -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/JASMET30_Online_spc.py b/schainpy/scripts/JASMET30_Online_spc.py deleted file mode 100644 index 8e317e1..0000000 --- a/schainpy/scripts/JASMET30_Online_spc.py +++ /dev/null @@ -1,118 +0,0 @@ - -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -controllerObj = Project() -controllerObj.setup(id = '001', name='script01', description="JASMET Online monitoring") - -#-------------------------------------- Setup ----------------------------------------- -#Verificar estas variables - -#Path para los archivos -path = '/mnt/jars/2016_08/DIA' -path = '/media/joscanoa/DATA_JASMET/JASMET/2016_08/NOCHE' -path = '/media/joscanoa/DATA_JASMET/JASMET/2016_08/DIA' -#Path para los graficos -pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/graphics') -#Fechas para busqueda de archivos -startDate = '2016/08/25' -endDate = '2016/08/26' -#Horas para busqueda de archivos -startTime = '10:00:00' -endTime = '23:59:59' - -#------------------------------ Voltage Reading Unit ---------------------------------- - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate=startDate, - endDate=endDate, - startTime=startTime, - endTime=endTime, - online=0, - delay=5, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -#-------------------------- Voltage Processing Unit ------------------------------------ - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj00 = procUnitConfObj0.addOperation(name='selectChannels') -opObj00.addParameter(name='channelList', value='0, 1, 2, 3, 4', format='intlist') - -opObj01 = procUnitConfObj0.addOperation(name='setRadarFrequency') -opObj01.addParameter(name='frequency', value='30.e6', format='float') - -opObj00 = procUnitConfObj0.addOperation(name='interpolateHeights') -opObj00.addParameter(name='topLim', value='73', format='int') -opObj00.addParameter(name='botLim', value='71', format='int') -# opObj00.addParameter(name='topLim', value='82', format='int') -# opObj00.addParameter(name='botLim', value='79', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='int') - -#--------------------------- Spectra Processing Unit ------------------------------------ - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj2.addParameter(name='nFFTPoints', value='128', format='int') -procUnitConfObj2.addParameter(name='nProfiles', value='128', format='int') - -opObj21 = procUnitConfObj2.addOperation(name='IncohInt', optype='other') -opObj21.addParameter(name='n', value='40.0', format='float') - -opObj23 = procUnitConfObj2.addOperation(name='SpectraPlot', optype='other') -opObj23.addParameter(name='id', value='1', format='int') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value=pathfig, format='str') -opObj23.addParameter(name='zmin', value='23', format='int') -opObj23.addParameter(name='zmax', value='40', format='int') -opObj23.addParameter(name='figpath', value=pathfig, format='str') -opObj23.addParameter(name='ftp', value='1', format='int') -opObj23.addParameter(name='xaxis', value='Velocity', format='str') -opObj23.addParameter(name='exp_code', value='15', format='int') -opObj23.addParameter(name='sub_exp_code', value='1', format='int') - -opObj22 = procUnitConfObj2.addOperation(name='RTIPlot', optype='other') -opObj22.addParameter(name='id', value='2', format='int') -opObj22.addParameter(name='save', value='1', format='bool') -opObj22.addParameter(name='figpath', value = pathfig, format='str') -# opObj22.addParameter(name='timerange', value = str(7*60*60), format='int') -opObj22.addParameter(name='xmin', value='18', format='float') -opObj22.addParameter(name='xmax', value='25', format='float') -opObj22.addParameter(name='zmin', value='23', format='int') -opObj22.addParameter(name='zmax', value='40', format='int') -opObj22.addParameter(name='figpath', value=pathfig, format='str') -opObj22.addParameter(name='ftp', value='1', format='int') -opObj22.addParameter(name='exp_code', value='15', format='int') -opObj22.addParameter(name='sub_exp_code', value='1', format='int') - -#------------------------------------ Send images to server ------------------------------- -# procUnitConfObj4 = controllerObj.addProcUnit(name='SendToServer') -# procUnitConfObj4.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# procUnitConfObj4.addParameter(name='username', value='wmaster', format='str') -# procUnitConfObj4.addParameter(name='password', value='mst2010vhf', format='str') -# procUnitConfObj4.addParameter(name='localfolder', value=pathfig, format='str') -# procUnitConfObj4.addParameter(name='remotefolder', value="/home/wmaster/graficos", format='str') -# procUnitConfObj4.addParameter(name='ext', value='.png', format='str') -# procUnitConfObj4.addParameter(name='period', value=120, format='int') -# procUnitConfObj4.addParameter(name='protocol', value='ftp', format='str') - -#-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml("JASMET01.xml") -print "Leyendo el archivo XML" -controllerObj.readXml("JASMET01.xml") - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/JASMET30_PhaseCal.py b/schainpy/scripts/JASMET30_PhaseCal.py index 25b4d61..1b0da1f 100644 --- a/schainpy/scripts/JASMET30_PhaseCal.py +++ b/schainpy/scripts/JASMET30_PhaseCal.py @@ -14,17 +14,17 @@ controllerObj.setup(id = '004', name='script04', description="JASMET Phase Calib #Verificar estas variables #Path donde estan los archivos HDF5 de meteoros -path = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/meteor') +path = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/meteor') #Path para los graficos -pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/graphics') +pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/graphics') #Path donde se almacenaran las fases calculadas -pathfile = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/phase') +pathfile = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/phase') #Fechas para busqueda de archivos -startDate = '2016/08/20' -endDate = '2016/08/30' +startDate = '2016/08/29' +endDate = '2016/09/11' #Horas para busqueda de archivos startTime = '00:00:00' endTime = '23:59:59' @@ -32,8 +32,8 @@ endTime = '23:59:59' #------------------------------------------------------------------------------------------------ readUnitConfObj = controllerObj.addReadUnit(datatype='ParamReader', path=path, - startDate='2016/06/02', - endDate='2017/06/03', + startDate=startDate, + endDate=endDate, startTime=startTime, endTime=endTime, walk=1) @@ -65,13 +65,4 @@ opObj33.addParameter(name='metadataList',value='type,outputInterval,timeZone',fo opObj33.addParameter(name='dataList',value='data_output,utctime',format='list') # # opObj25.addParameter(name='mode',value='1,0,0',format='intlist') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml("JASMET04.xml") -print "Leyendo el archivo XML" -controllerObj.readXml("JASMET04.xml") - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file +controllerObj.start() \ No newline at end of file diff --git a/schainpy/scripts/JASMET30_PreProc.py b/schainpy/scripts/JASMET30_PreProc.py deleted file mode 100644 index d02b505..0000000 --- a/schainpy/scripts/JASMET30_PreProc.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -Se debe verficar que el disco de datos se encuentra montado en el sistema -""" -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "Meteor Experiment Test" -filename = "meteor20130812.xml" - -controllerObj = Project() -controllerObj.setup(id = '191', name='meteor_test01', description=desc) - -path='/mnt/jars/2016_08/NOCHE/' -path='/mnt/jars/2016_08/DIA/' -path1 = '/media/soporte/Data/JASMET' - -readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path=path, - startDate='2016/09/28', - endDate='2016/09/28', - startTime='00:00:00', - endTime='10:50:00', - online=0, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -opObj11.addParameter(name='path', value=path1) -opObj11.addParameter(name='blocksPerFile', value='100', format='int') -opObj11.addParameter(name='profilesPerBlock', value='200', format='int') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/JASMET30_Winds.py b/schainpy/scripts/JASMET30_Winds.py index a58ae11..f489be5 100644 --- a/schainpy/scripts/JASMET30_Winds.py +++ b/schainpy/scripts/JASMET30_Winds.py @@ -14,23 +14,24 @@ controllerObj.setup(id = '005', name='script05', description="JASMET Wind Estima #Verificar estas variables #Path donde estan los archivos HDF5 de meteoros -path = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/meteor') +path = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/meteor') #Path para los graficos -pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/graphics') +pathfig = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/graphics') #Path donde se almacenaran las estimaciones de vientos -pathfile = os.path.join(os.environ['HOME'],'Pictures/JASMET30/201608/phase') +pathfile = os.path.join(os.environ['HOME'],'Pictures/JASMET30_mp/201608/phase') #Fechas para busqueda de archivos -startDate = '2016/08/20' -endDate = '2016/08/30' +startDate = '2016/08/29' +endDate = '2016/09/11' #Horas para busqueda de archivos startTime = '00:00:00' endTime = '23:59:59' #Offsets optimos obtenidos con OptimumOffset.py -phaseOffsets = '-2.84, -1.77, 11.94, 9.71' +phaseOffsets = '-2.84, -1.77, 11.94, 9.71' +phaseOffsets = '-5.86, -0.93, -7.29, 23.35' #------------------------------------------------------------------------------------------------ readUnitConfObj = controllerObj.addReadUnit(datatype='ParamReader', path=path, @@ -81,11 +82,4 @@ opObj33.addParameter(name='metadataList',value='type,outputInterval,timeZone',fo opObj33.addParameter(name='dataList',value='data_output,utctime',format='list') #-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml("JASMET05.xml") -print "Leyendo el archivo XML" -controllerObj.readXml("JASMET05.xml") - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file +controllerObj.start() \ No newline at end of file diff --git a/schainpy/scripts/NSM1.py b/schainpy/scripts/NSM1.py deleted file mode 100644 index b005c73..0000000 --- a/schainpy/scripts/NSM1.py +++ /dev/null @@ -1,138 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -# pathfile = '/home/joscanoa/data/HP_Meteor/MST' -path = '/home/joscanoa/data/HP_Meteor/MST' -# path = '/media/joscanoa/DATA/DATA/RAW_EXP/MST_meteors_153-155' -pathfig = '/home/joscanoa/Pictures/NonSpecular/CEDAR/DBS/graphic' -pathfile1 = '/home/joscanoa/Pictures/NonSpecular/CEDAR/DBS/meteor' - -xmax = '8' -xmin = '6' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2016/06/02', - endDate='2016/06/03', - startTime='21:00:00', - endTime='08:00:00', - online=0, - delay=20, - walk=1, - getblock=1, - blocktime=120) -# blocksize=4096) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -# opObj11 = procUnitConfObj0.addOperation(name='selectChannels') -# opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -# -# opObj11 = procUnitConfObj0.addOperation(name='selectHeights') -# opObj11.addParameter(name='minHei', value='60', format='float') -# # opObj11.addParameter(name='minHei', value='272.5', format='float') -# opObj11.addParameter(name='maxHei', value='130', format='float') -# -# opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -# -# opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') -# # opObj11.addParameter(name='n', value='16', format='int') -# -# #--------------------------------------------------------------------------------------------------- -# opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -# opObj11.addParameter(name='path', value=pathfile) -# opObj11.addParameter(name='blocksPerFile', value='120', format='int') -# opObj11.addParameter(name='profilesPerBlock', value='200', format='int') - -#--------------------------------------------------------------------------------------------------- - -# procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -# procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int') -# procUnitConfObj1.addParameter(name='nProfiles', value='64', format='int') -# -# opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -# opObj11.addParameter(name='n', value='15', format='int') -# # -# opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj14.addParameter(name='id', value='1', format='int') -# opObj14.addParameter(name='wintitle', value='spc', format='str') -# opObj14.addParameter(name='save', value='1', format='bool') -# opObj14.addParameter(name='figpath', value=pathFigure, format='str') -# # opObj14.addParameter(name='zmin', value='14', format='int') -# # opObj14.addParameter(name='zmax', value='60', format='int') -# opObj14.addParameter(name='xaxis', value='velocity', format='str') -# -# opObj15 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj15.addParameter(name='id', value='2', format='int') -# opObj15.addParameter(name='wintitle', value='RTI Plot', format='str') -# opObj15.addParameter(name='save', value='1', format='bool') -# opObj15.addParameter(name='figpath', value = pathFigure, format='str') -# # opObj15.addParameter(name='timerange', value='600', format='float') -# opObj15.addParameter(name='xmin', value=xmin, format='float') -# opObj15.addParameter(name='xmax', value=xmax, format='float') -# # opObj15.addParameter(name='zmin', value='14', format='int') -# # opObj15.addParameter(name='zmax', value='60', format='int') - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='lags', value='0,1,2', format='intlist') -procUnitConfObj1.addParameter(name='fullBuffer', value='1', format='bool') -procUnitConfObj1.addParameter(name='nAvg', value='32', format='int') - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -opObj20 = procUnitConfObj2.addOperation(name='NonSpecularMeteorDetection') -opObj20.addParameter(name='mode', value='DBS', format='str') -opObj20.addParameter(name='allData', value='0', format='bool') -# -opObj21 = procUnitConfObj2.addOperation(name='NSMeteorDetection2Plot',optype='other') -opObj21.addParameter(name='id', value='2', format='int') -opObj21.addParameter(name='wintitle', value='Non specular', format='str') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value = pathfig, format='str') -opObj21.addParameter(name='SNRmin', value='-10', format='int') -opObj21.addParameter(name='SNRmax', value='30', format='int') -opObj21.addParameter(name='vmin', value='-50', format='int') -opObj21.addParameter(name='vmax', value='50', format='int') -opObj21.addParameter(name='mode', value='DBS', format='str') - -opObj22 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -opObj22.addParameter(name='path', value=pathfile1) -opObj22.addParameter(name='blocksPerFile', value='80', format='int') -opObj22.addParameter(name='metadataList',value='type,heightList,abscissaList,paramInterval,timeZone,groupList',format='list') -opObj22.addParameter(name='dataList',value='data_param,utctime',format='list') -opObj22.addParameter(name='mode',value='2',format='int') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM11.py b/schainpy/scripts/NSM11.py deleted file mode 100644 index bd2092a..0000000 --- a/schainpy/scripts/NSM11.py +++ /dev/null @@ -1,90 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014051 20 Feb 2014 -path = '/home/joscanoa/Pictures/NonSpecular/CEDAR/DBS/meteor' - -pathfig = '/home/joscanoa/Pictures/NonSpecular/CEDAR/DBS/graphic' - -pathfile2 = '/home/joscanoa/Pictures/NonSpecular/CEDAR/DBS/wind' - - -tmin = '00:00:00' -tmax = '23:59:59' -xmin = '20' -xmax = '32' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='HDF5Reader', - path=path, - startDate='2016/06/02', - endDate='2016/06/03', - startTime=tmin, - endTime=tmax, - online=0, - delay=20, - walk=1) -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) -# -opObj21 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj21.addParameter(name='technique', value='Meteors1', format='str') -opObj21.addParameter(name='mode', value='DBS', format='str') - -opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -opObj23.addParameter(name='id', value='2', format='int') -opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathfig, format='str') -opObj23.addParameter(name='zmin', value='-140', format='int') -opObj23.addParameter(name='zmax', value='140', format='int') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') -opObj23.addParameter(name='ymin', value='84', format='float') -opObj23.addParameter(name='ymax', value='102', format='float') -# -# opObj21 = procUnitConfObj2.addOperation(name='NonSpecularMeteorsPlot',optype='other') -# opObj21.addParameter(name='id', value='2', format='int') -# opObj21.addParameter(name='wintitle', value='Non specular', format='str') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value = pathFigure, format='str') -# opObj21.addParameter(name='SNRmin', value='-10', format='float') -# opObj21.addParameter(name='SNRmax', value='20', format='float') -# opObj21.addParameter(name='cmin', value='0.5', format='float') -# opObj21.addParameter(name='vmax', value='100', format='float') -# opObj21.addParameter(name='vmin', value='-100', format='float') - -# opObj24 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj24.addParameter(name='path', value=pathfile2) -# opObj24.addParameter(name='blocksPerFile', value='60', format='int') -# opObj24.addParameter(name='metadataList',value='type,heightList,outputInterval,timeZone',format='list') -# opObj24.addParameter(name='dataList',value='data_output,utctime,utctimeInit',format='list') -# # # opObj12.addParameter(name='mode',value='2',format='int') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM2.py b/schainpy/scripts/NSM2.py deleted file mode 100644 index 93e45ff..0000000 --- a/schainpy/scripts/NSM2.py +++ /dev/null @@ -1,180 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014051 20 Feb 2014 -path = '/home/joscanoa/data/HP_Meteor/Met' -# path = '/media/joscanoa/DATA/DATA/RAW_EXP/MST_meteors_153-155' -pathfig = '/home/joscanoa/Pictures/NonSpecular/CEDAR/SA/notmedian/graphic' -pathfile1 = '/home/joscanoa/Pictures/NonSpecular/CEDAR/SA/notmedian/meteor' -# pathfile2 = '/home/joscanoa/Pictures/NonSpecular/CEDAR/test2/wind' -# pathfile = '/home/joscanoa/data/HP_Meteor/Met' - -tmin = '20:00:00' -tmax = '23:59:59' -xmin = '21' -xmax = '32' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2016/06/02', - endDate='2016/06/02', - startTime=tmin, - endTime=tmax, - online=0, - delay=20, - walk=1, - getblock=1, - blocktime=120) -# blocksize=12800) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj11 = procUnitConfObj0.addOperation(name='correctHeights') -opObj11.addParameter(name='value', value='-187.5', format='float') - -# -# opObj11 = procUnitConfObj0.addOperation(name='selectChannels') -# opObj11.addParameter(name='channelList', value='4,5,6', format='intlist') -# # -# opObj11 = procUnitConfObj0.addOperation(name='selectHeights') -# opObj11.addParameter(name='minHei', value='257.5', format='float') -# # opObj11.addParameter(name='minHei', value='272.5', format='float') -# opObj11.addParameter(name='maxHei', value='307.5', format='float') -# # -# opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -# opObj11.addParameter(name='code', value='1,1,1,1,1,-1,-1,1,1,-1,1,-1,1', format='intlist') -# opObj11.addParameter(name='nCode', value='1', format='int') -# opObj11.addParameter(name='nBaud', value='13', format='int') -# # -# opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') -# # opObj11.addParameter(name='n', value='16', format='int') -# -# #--------------------------------------------------------------------------------------------------- -# opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -# opObj11.addParameter(name='path', value=pathfile) -# opObj11.addParameter(name='blocksPerFile', value='120', format='int') -# opObj11.addParameter(name='profilesPerBlock', value='200', format='int') -#--------------------------------------------------------------------------------------------------- - -# procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -# procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int') -# procUnitConfObj1.addParameter(name='nProfiles', value='64', format='int') -# -# opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -# opObj11.addParameter(name='n', value='5', format='int') -# # -# opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj14.addParameter(name='id', value='1', format='int') -# opObj14.addParameter(name='wintitle', value='spc', format='str') -# opObj14.addParameter(name='save', value='1', format='bool') -# opObj14.addParameter(name='figpath', value=pathFigure, format='str') -# opObj14.addParameter(name='zmin', value='14', format='int') -# opObj14.addParameter(name='zmax', value='60', format='int') -# opObj14.addParameter(name='xaxis', value='velocity', format='str') -# -# opObj15 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj15.addParameter(name='id', value='2', format='int') -# opObj15.addParameter(name='wintitle', value='RTI Plot', format='str') -# opObj15.addParameter(name='save', value='1', format='bool') -# opObj15.addParameter(name='figpath', value = pathFigure, format='str') -# opObj15.addParameter(name='timerange', value='600', format='float') -# # opObj15.addParameter(name='xmin', value=xmin, format='float') -# # opObj15.addParameter(name='xmax', value=xmax, format='float') -# opObj15.addParameter(name='zmin', value='14', format='int') -# opObj15.addParameter(name='zmax', value='60', format='int') - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='pairsList', value='(0,1),(0,2),(1,2)', format='pairsList') -procUnitConfObj1.addParameter(name='lags', value='0,1,2', format='intlist') -procUnitConfObj1.addParameter(name='fullBuffer', value='1', format='bool') -procUnitConfObj1.addParameter(name='nAvg', value='16', format='int') - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -opObj20 = procUnitConfObj2.addOperation(name='NonSpecularMeteorDetection') -opObj20.addParameter(name='mode', value='SA', format='str') -opObj20.addParameter(name='SNRthresh', value='5', format='int') -opObj20.addParameter(name='allData', value='0', format='bool') - -opObj21 = procUnitConfObj2.addOperation(name='NSMeteorDetection1Plot',optype='other') -opObj21.addParameter(name='id', value='2', format='int') -opObj21.addParameter(name='save', value='0', format='bool') -opObj21.addParameter(name='wintitle', value='Non specular', format='str') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value = pathfig, format='str') -opObj21.addParameter(name='SNRmin', value='-10', format='int') -opObj21.addParameter(name='SNRmax', value='20', format='int') -opObj21.addParameter(name='cmin', value='0.5', format='float') - -# opObj22 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj22.addParameter(name='path', value=pathfile1) -# opObj22.addParameter(name='blocksPerFile', value='80', format='int') -# opObj22.addParameter(name='metadataList',value='type,heightList,abscissaList,paramInterval,timeZone,groupList',format='list') -# opObj22.addParameter(name='dataList',value='data_param,utctime',format='list') -# opObj22.addParameter(name='mode',value='2',format='int') - -# opObj21 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -# opObj21.addParameter(name='technique', value='Meteors1', format='str') -# -# opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -# opObj23.addParameter(name='id', value='2', format='int') -# opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -# opObj23.addParameter(name='save', value='1', format='bool') -# opObj23.addParameter(name='figpath', value = pathfig, format='str') -# opObj23.addParameter(name='zmin', value='-180', format='int') -# opObj23.addParameter(name='zmax', value='180', format='int') -# opObj23.addParameter(name='xmin', value=xmin, format='float') -# opObj23.addParameter(name='xmax', value=xmax, format='float') -# opObj23.addParameter(name='ymin', value='80', format='float') -# opObj23.addParameter(name='ymax', value='110', format='float') -# -# opObj21 = procUnitConfObj2.addOperation(name='NonSpecularMeteorsPlot',optype='other') -# opObj21.addParameter(name='id', value='2', format='int') -# opObj21.addParameter(name='wintitle', value='Non specular', format='str') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value = pathFigure, format='str') -# opObj21.addParameter(name='SNRmin', value='-10', format='float') -# opObj21.addParameter(name='SNRmax', value='20', format='float') -# opObj21.addParameter(name='cmin', value='0.5', format='float') -# opObj21.addParameter(name='vmax', value='100', format='float') -# opObj21.addParameter(name='vmin', value='-100', format='float') - -# opObj24 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj24.addParameter(name='path', value=pathfile2) -# opObj24.addParameter(name='blocksPerFile', value='60', format='int') -# opObj24.addParameter(name='metadataList',value='type,heightList,outputInterval,timeZone',format='list') -# opObj24.addParameter(name='dataList',value='data_output,utctime,utctimeInit',format='list') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM21.py b/schainpy/scripts/NSM21.py deleted file mode 100644 index c5b2b4e..0000000 --- a/schainpy/scripts/NSM21.py +++ /dev/null @@ -1,89 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014051 20 Feb 2014 -path = '/home/joscanoa/Pictures/NonSpecular/CEDAR/SA/notmedian/meteor' - -pathfig = '/home/joscanoa/Pictures/NonSpecular/CEDAR/SA/notmedian/graphic' - -pathfile2 = '/home/joscanoa/Pictures/NonSpecular/CEDAR/test1/wind' - - -tmin = '00:00:00' -tmax = '23:59:59' -xmin = '20' -xmax = '32' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='HDF5Reader', - path=path, - startDate='2016/06/02', - endDate='2016/06/03', - startTime=tmin, - endTime=tmax, - online=0, - delay=20, - walk=1) -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) -# -opObj21 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj21.addParameter(name='technique', value='Meteors1', format='str') - -opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -opObj23.addParameter(name='id', value='2', format='int') -opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathfig, format='str') -opObj23.addParameter(name='zmin', value='-140', format='int') -opObj23.addParameter(name='zmax', value='140', format='int') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') -opObj23.addParameter(name='ymin', value='84', format='float') -opObj23.addParameter(name='ymax', value='102', format='float') -# -# opObj21 = procUnitConfObj2.addOperation(name='NonSpecularMeteorsPlot',optype='other') -# opObj21.addParameter(name='id', value='2', format='int') -# opObj21.addParameter(name='wintitle', value='Non specular', format='str') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value = pathFigure, format='str') -# opObj21.addParameter(name='SNRmin', value='-10', format='float') -# opObj21.addParameter(name='SNRmax', value='20', format='float') -# opObj21.addParameter(name='cmin', value='0.5', format='float') -# opObj21.addParameter(name='vmax', value='100', format='float') -# opObj21.addParameter(name='vmin', value='-100', format='float') - -# opObj24 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj24.addParameter(name='path', value=pathfile2) -# opObj24.addParameter(name='blocksPerFile', value='60', format='int') -# opObj24.addParameter(name='metadataList',value='type,heightList,outputInterval,timeZone',format='list') -# opObj24.addParameter(name='dataList',value='data_output,utctime,utctimeInit',format='list') -# # # opObj12.addParameter(name='mode',value='2',format='int') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM_HDF5.py b/schainpy/scripts/NSM_HDF5.py deleted file mode 100644 index a6ede46..0000000 --- a/schainpy/scripts/NSM_HDF5.py +++ /dev/null @@ -1,77 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014051 20 Feb 2014 -path = '/home/joscanoa/Pictures/NonSpecular/test/data' -pathFigure = '/home/joscanoa/Pictures/NonSpecular' -pathfile = '/home/joscanoa/Pictures/NonSpecular' - -tmin = '00:00:00' -tmax = '23:59:59' -xmax = '24' -xmin = '0' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='HDF5Reader', - path=path, - startDate='2016/05/29', - endDate='2016/06/29', - startTime=tmin, - endTime=tmax, - online=0, - delay=20, - walk=1) -# blocksize=12800) - -# opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) -# opObj20 = procUnitConfObj2.addOperation(name='NonSpecularMeteorDetection') -# opObj20.addParameter(name='mode', value='SA', format='str') -# -opObj21 = procUnitConfObj2.addOperation(name='NonSpecularMeteorsPlot',optype='other') -opObj21.addParameter(name='id', value='2', format='int') -opObj21.addParameter(name='wintitle', value='Non specular', format='str') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value = pathFigure, format='str') -opObj21.addParameter(name='SNRmin', value='-10', format='float') -opObj21.addParameter(name='cmin', value='0.5', format='float') -opObj21.addParameter(name='vmax', value='100', format='float') -opObj21.addParameter(name='vmin', value='-100', format='float') - -# opObj22 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj22.addParameter(name='path', value=pathfile) -# opObj22.addParameter(name='blocksPerFile', value='1', format='int') -# opObj22.addParameter(name='metadataList',value='type,heightList,paramInterval,timeZone',format='list') -# opObj22.addParameter(name='dataList',value='data_param,utctime',format='list') -# # opObj12.addParameter(name='mode',value='2',format='int') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM_PreProc1.py b/schainpy/scripts/NSM_PreProc1.py deleted file mode 100644 index cca90dd..0000000 --- a/schainpy/scripts/NSM_PreProc1.py +++ /dev/null @@ -1,76 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014051 20 Feb 2014 -path = '/media/joscanoa/DATA/DATA/RAW_EXP/MST_meteors_153-155' -pathFigure = '/home/joscanoa/Pictures/NonSpecular' -pathfile = '/home/joscanoa/data/HP_Meteor/MST' - -xmax = '24' -xmin = '0' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2016/06/03', - endDate='2016/06/03', - startTime='00:00:00', - endTime='23:59:59', - online=0, - delay=20, - walk=1, - getblock=0, -# blocktime=10) - blocksize=4096) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='selectChannels') -opObj11.addParameter(name='channelList', value='1,2,3,4', format='intlist') - -opObj11 = procUnitConfObj0.addOperation(name='selectHeights') -opObj11.addParameter(name='minHei', value='60', format='float') -# opObj11.addParameter(name='minHei', value='272.5', format='float') -opObj11.addParameter(name='maxHei', value='120', format='float') - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='int') -#--------------------------------------------------------------------------------------------------- -opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -opObj11.addParameter(name='path', value=pathfile) -opObj11.addParameter(name='blocksPerFile', value='120', format='int') -opObj11.addParameter(name='profilesPerBlock', value='200', format='int') -#-------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/NSM_Preproc2.py b/schainpy/scripts/NSM_Preproc2.py deleted file mode 100644 index 22776dc..0000000 --- a/schainpy/scripts/NSM_Preproc2.py +++ /dev/null @@ -1,79 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos -path = '/media/joscanoa/DATA/DATA/RAW_EXP/MST_meteors_153-155' -pathFigure = '/home/joscanoa/Pictures/NonSpecular' -pathfile = '/home/joscanoa/data/HP_Meteor/Met' - -tmin = '00:00:00' -tmax = '23:59:59' -xmax = '0' -xmin = '24' - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2016/06/03', - endDate='2016/06/03', - startTime=tmin, - endTime=tmax, - online=0, - delay=20, - walk=1, - getblock=0, - blocktime=60) -# blocksize=12800) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -# -opObj11 = procUnitConfObj0.addOperation(name='selectChannels') -opObj11.addParameter(name='channelList', value='4,5,6', format='intlist') - -opObj11 = procUnitConfObj0.addOperation(name='selectHeights') -opObj11.addParameter(name='minHei', value='257.5', format='float') -# opObj11.addParameter(name='minHei', value='272.5', format='float') -opObj11.addParameter(name='maxHei', value='307.5', format='float') - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value='1,1,1,1,1,-1,-1,1,1,-1,1,-1,1', format='intlist') -opObj11.addParameter(name='nCode', value='1', format='int') -opObj11.addParameter(name='nBaud', value='13', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='int') -# #--------------------------------------------------------------------------------------------------- -opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -opObj11.addParameter(name='path', value=pathfile) -opObj11.addParameter(name='blocksPerFile', value='120', format='int') -opObj11.addParameter(name='profilesPerBlock', value='200', format='int') -#--------------------------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/PPD.py b/schainpy/scripts/PPD.py new file mode 100644 index 0000000..0c66244 --- /dev/null +++ b/schainpy/scripts/PPD.py @@ -0,0 +1,97 @@ +import argparse + +from schainpy.controller import Project, multiSchain + +desc = "HF_EXAMPLE" + +def fiber(cursor, skip, q, dt): + + controllerObj = Project() + + controllerObj.setup(id='191', name='test01', description=desc) + + readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader', + path='/home/nanosat/data/sp1_f0', + startDate=dt, + endDate=dt, + startTime="00:00:00", + endTime="23:59:59", + online=0, + #set=1426485881, + walk=1, + queue=q, + cursor=cursor, + skip=skip, + verbose=1 + #timezone=-5*3600 + ) + + # #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') + # + procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) + # procUnitConfObj2.addParameter(name='nipp', value='5', format='int') + + procUnitConfObj3 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) + opObj11 = procUnitConfObj3.addOperation(name='SpectralMoments', optype='other') + + # + # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') + # opObj11.addParameter(name='id', value='1000', format='int') + # opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') + # opObj11.addParameter(name='channelList', value='0', format='intlist') + # opObj11.addParameter(name='zmin', value='-120', format='float') + # opObj11.addParameter(name='zmax', value='-70', format='float') + # opObj11.addParameter(name='save', value='1', format='int') + # opObj11.addParameter(name='figpath', value=figpath, format='str') + + # opObj11 = procUnitConfObj3.addOperation(name='Parameters1Plot', optype='other') + # opObj11.addParameter(name='channelList', value='0', format='intList') + + # opObj11.addParameter(name='id', value='2000', format='int') + # # opObj11.addParameter(name='colormap', value='0', format='bool') + # opObj11.addParameter(name='onlySNR', value='1', format='bool') + # opObj11.addParameter(name='DOP', value='0', format='bool') + # # opObj11.addParameter(name='showSNR', value='1', format='bool') + # # opObj11.addParameter(name='SNRthresh', value='0', format='int') + # opObj11.addParameter(name='SNRmin', value='-10', format='int') + # opObj11.addParameter(name='SNRmax', value='30', format='int') + + # opObj11.addParameter(name='showSNR', value='1', format='int') + # # opObj11.addParameter(name='channelList', value='0', format='intlist') + # # opObj11.addParameter(name='xmin', value='0', format='float') + # opObj11.addParameter(name='xmin', value='0', format='float') + # opObj11.addParameter(name='xmax', value='24', format='float') + + # opObj11.addParameter(name='zmin', value='-110', format='float') + # opObj11.addParameter(name='zmax', value='-70', format='float') + # opObj11.addParameter(name='save', value='0', format='int') + # # opObj11.addParameter(name='figpath', value='/tmp/', format='str') + # + opObj12 = procUnitConfObj3.addOperation(name='PublishData', optype='other') + opObj12.addParameter(name='zeromq', value=1, format='int') + opObj12.addParameter(name='verbose', value=0, format='bool') + + + # opObj13 = procUnitConfObj3.addOperation(name='PublishData', optype='other') + # opObj13.addParameter(name='zeromq', value=1, format='int') + # opObj13.addParameter(name='server', value="juanca", format='str') + + opObj12.addParameter(name='delay', value=0, format='int') + + + # print "Escribiendo el archivo XML" + # controllerObj.writeXml(filename) + # print "Leyendo el archivo XML" + # controllerObj.readXml(filename) + + + # timeit.timeit('controllerObj.run()', number=2) + + controllerObj.start() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Set number of parallel processes') + parser.add_argument('--nProcess', default=1, type=int) + args = parser.parse_args() + multiSchain(fiber, nProcess=args.nProcess, startDate='2017/01/26', endDate='2017/01/26') diff --git a/schainpy/scripts/WindProfiler_DBS01.py b/schainpy/scripts/WindProfiler_DBS01.py deleted file mode 100644 index 59466e1..0000000 --- a/schainpy/scripts/WindProfiler_DBS01.py +++ /dev/null @@ -1,168 +0,0 @@ -# DIAS 19 Y 20 FEB 2014 -# Comprobacion de Resultados DBS con SA - -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#Experimentos - -#2014050 19 Feb 2014 -# path = '/home/soporte/Documents/MST_Data/DBS/d2014050' -# pathFigure = '/home/soporte/workspace/Graficos/DBS/d2014050p/' -# xmin = '15.5' -# xmax = '23.99999999' -# startTime = '17:25:00' -# filehdf5 = "DBS_2014050.hdf5" - -#2014051 20 Feb 2014 -path = '/media/joscanoa/84A65E64A65E5730/soporte/Data/MST/DBS/d2014051' -# path = '/media/joscanoa/disco4/Data/2014/DBS_SA JAN 2014/DBS_SA/250/d2014050' -pathfile1 = os.path.join(os.environ['HOME'],'Pictures/testHDF5/moments') -xmax = '1' -xmin = '0' -startTime = '00:00:00' -filehdf5 = "DBS_2014051.hdf5" - - - -#------------------------------------------------------------------------------------------------ -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2014/01/31', - endDate='2014/03/31', - startTime=startTime, - endTime='23:59:59', - online=0, - delay=5, - walk=0) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#------------------------------ Voltage Processing Unit ------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='256', format='int') -# opObj11.addParameter(name='n', value='16', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='selectHeightsByIndex') -opObj11.addParameter(name='minIndex', value='10', format='float') -opObj11.addParameter(name='maxIndex', value='60', format='float') - -# opObj12 = procUnitConfObj0.addOperation(name='selectChannels') -# opObj12.addParameter(name='channelList', value='0,1', format='intlist') - -#------------------------------ Spectra Processing Unit ------------------------------------- - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='64', format='int') -# procUnitConfObj1.addParameter(name='ippFactor', value='2', format='int') - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='5', format='int') - -opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj14.addParameter(name='id', value='1', format='int') -opObj14.addParameter(name='wintitle', value='Con interf', format='str') -opObj14.addParameter(name='save', value='0', format='bool') -opObj14.addParameter(name='figpath', value=pathFigure, format='str') -opObj14.addParameter(name='zmin', value='5', format='int') -opObj14.addParameter(name='zmax', value='90', format='int') - -opObj12 = procUnitConfObj1.addOperation(name='removeInterference') -opObj13 = procUnitConfObj1.addOperation(name='removeDC') -opObj13.addParameter(name='mode', value='1', format='int') - -opObj12 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj12.addParameter(name='id', value='2', format='int') -opObj12.addParameter(name='wintitle', value='RTI Plot', format='str') -opObj12.addParameter(name='save', value='1', format='bool') -opObj12.addParameter(name='figpath', value = pathFigure, format='str') -opObj12.addParameter(name='xmin', value=xmin, format='float') -opObj12.addParameter(name='xmax', value=xmax, format='float') -opObj12.addParameter(name='zmin', value='5', format='int') -opObj12.addParameter(name='zmax', value='90', format='int') - - -#------------------------------ Parameters Processing Unit ------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) - -opObj11 = procUnitConfObj2.addOperation(name='SpectralMoments', optype='other') - -# opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj12.addParameter(name='path', value=pathfile1) -# opObj12.addParameter(name='blocksPerFile', value='10', format='int') -# opObj12.addParameter(name='metadataList',value='type,inputUnit,heightList,paramInterval,timeZone',format='list') -# opObj12.addParameter(name='dataList',value='data_param,data_SNR,noise,utctime',format='list') -# opObj12.addParameter(name='mode',value='1',format='int') - -# opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other') -# opObj21.addParameter(name='id', value='3', format='int') -# opObj21.addParameter(name='wintitle', value='Moments Plot', format='str') -# opObj21.addParameter(name='save', value='0', format='bool') -# # opObj21.addParameter(name='figpath', value=pathFigure, format='str') -# opObj21.addParameter(name='zmin', value='5', format='int') -# opObj21.addParameter(name='zmax', value='90', format='int') -# -# opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -# opObj21.addParameter(name='id', value='5', format='int') -# opObj21.addParameter(name='wintitle', value='Radial Velocity Plot', format='str') -# opObj21.addParameter(name='save', value='0', format='bool') -# opObj21.addParameter(name='figpath', value=pathFigure, format='str') -# opObj21.addParameter(name='SNRmin', value='-10', format='int') -# opObj21.addParameter(name='SNRmax', value='60', format='int') -# opObj21.addParameter(name='channelList', value='0,2', format='intlist') -# opObj21.addParameter(name='SNR', value='1', format='bool') -# opObj21.addParameter(name='SNRthresh', value='0', format='float') -# opObj21.addParameter(name='xmin', value=xmin, format='float') -# opObj21.addParameter(name='xmax', value=xmax, format='float') - -opObj22 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj22.addParameter(name='technique', value='DBS', format='str') -opObj22.addParameter(name='correctAzimuth', value='51.06', format='float') -opObj22.addParameter(name='correctFactor', value='-1', format='float') -opObj22.addParameter(name='dirCosx', value='0.041016, 0, -0.054688', format='floatlist') -opObj22.addParameter(name='dirCosy', value='-0.041016, 0.025391, -0.023438', format='floatlist') - -opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -opObj23.addParameter(name='id', value='4', format='int') -opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -opObj23.addParameter(name='save', value='0', format='bool') -# opObj23.addParameter(name='figpath', value = pathFigure, format='str') -opObj23.addParameter(name='zmin', value='-10', format='int') -opObj23.addParameter(name='zmax', value='10', format='int') -opObj23.addParameter(name='zmin_ver', value='-80', format='float') -opObj23.addParameter(name='zmax_ver', value='80', format='float') -opObj23.addParameter(name='SNRmin', value='-10', format='int') -opObj23.addParameter(name='SNRmax', value='60', format='int') -opObj23.addParameter(name='SNRthresh', value='0', format='float') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') - -#-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/WindProfiler_SA01.py b/schainpy/scripts/WindProfiler_SA01.py deleted file mode 100644 index 9234f96..0000000 --- a/schainpy/scripts/WindProfiler_SA01.py +++ /dev/null @@ -1,129 +0,0 @@ -# DIAS 19 Y 20 FEB 2014 -# Comprobacion de Resultados DBS con SA - -import os, sys - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "SA Experiment Test" -filename = "SA2014050.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -#Experimentos - -#2014050 19 Feb 2014 -path = '/media/joscanoa/84A65E64A65E5730/soporte/Data/MST/SA/d2014050' -pathFigure = '/media/joscanoa/84A65E64A65E5730/soporte/workspace/Graficos/SA/prueba1/' -xmin = '15.5' -xmax = '24' -startTime = '15:30:00' -filehdf5 = "SA_2014050.hdf5" - -#2014051 20 Feb 2014 -# path = '/home/soporte/Data/MST/SA/d2014051' -# pathFigure = '/home/soporte/workspace/Graficos/SA/new/' -# xmin = '0.0' -# xmax = '8.0' -# startTime = '00:00:00' -# filehdf5 = "SA_2014051.hdf5" - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2014/01/01', - endDate='2014/03/31', - startTime=startTime, - endTime='23:59:59', - online=0, - delay=5, - walk=0, - getblock=1, - blocksize=32768) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - -#-------------------------------------------------------------------------------------------------- - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='600', format='int') -opObj11.addParameter(name='n', value='256', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='selectHeightsByIndex') -opObj11.addParameter(name='minIndex', value='10', format='float') -opObj11.addParameter(name='maxIndex', value='60', format='float') -#--------------------------------------------------------------------------------------------------- -procUnitConfObj1 = controllerObj.addProcUnit(datatype='CorrelationProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='pairsList', value='(0,0),(1,1),(2,2),(3,3),(1,0),(2,3)', format='pairsList') -# procUnitConfObj1.addParameter(name='removeDC', value='1', format='bool') -# #procUnitConfObj1.addParameter(name='lagT', value='0,1,2,3', format='intlist') -# -# opObj12 = procUnitConfObj1.addOperation(name='CorrelationPlot', optype='other') -# opObj12.addParameter(name='id', value='1', format='int') -# opObj12.addParameter(name='wintitle', value='CrossCorrelation Plot', format='str') -# opObj12.addParameter(name='save', value='1', format='bool') -# opObj12.addParameter(name='zmin', value='0', format='int') -# opObj12.addParameter(name='zmax', value='1', format='int') -# opObj12.addParameter(name='figpath', value = pathFigure, format='str') -# -# opObj12 = procUnitConfObj1.addOperation(name='removeNoise') -# opObj12.addParameter(name='mode', value='2', format='int') -# opObj12 = procUnitConfObj1.addOperation(name='calculateNormFactor') -# -# opObj12 = procUnitConfObj1.addOperation(name='CorrelationPlot', optype='other') -# opObj12.addParameter(name='id', value='2', format='int') -# opObj12.addParameter(name='wintitle', value='CrossCorrelation Plot', format='str') -# opObj12.addParameter(name='save', value='1', format='bool') -# opObj12.addParameter(name='zmin', value='0', format='int') -# opObj12.addParameter(name='zmax', value='1', format='int') -# opObj12.addParameter(name='figpath', value = pathFigure, format='str') -# -# #--------------------------------------------------------------------------------------------------- -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) - -opObj20 = procUnitConfObj2.addOperation(name='SALags', optype='other') -# -opObj21 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj21.addParameter(name='technique', value='SA', format='str') -# # opObj21.addParameter(name='correctFactor', value='-1', format='float') -opObj21.addParameter(name='positionX', value='36,0,36,0', format='floatlist') -opObj21.addParameter(name='positionY', value='36,0,0,36', format='floatlist') -opObj21.addParameter(name='azimuth', value='51.06', format='float') - -# opObj22 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -# opObj22.addParameter(name='id', value='4', format='int') -# opObj22.addParameter(name='wintitle', value='Wind Profiler', format='str') -# opObj22.addParameter(name='save', value='1', format='bool') -# opObj22.addParameter(name='figpath', value = pathFigure, format='str') -# opObj22.addParameter(name='zmin', value='-15', format='int') -# opObj22.addParameter(name='zmax', value='15', format='int') -# opObj22.addParameter(name='zmin_ver', value='-80', format='float') -# opObj22.addParameter(name='zmax_ver', value='80', format='float') -# opObj22.addParameter(name='SNRmin', value='-20', format='int') -# opObj22.addParameter(name='SNRmax', value='40', format='int') -# opObj22.addParameter(name='SNRthresh', value='-3.5', format='float') -# opObj22.addParameter(name='xmin', value=xmin, format='float') -# opObj22.addParameter(name='xmax', value=xmax, format='float') - -#----------------------------------------------------------------------------------- - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/__init__.py b/schainpy/scripts/__init__.py deleted file mode 100644 index 8feaeca..0000000 --- a/schainpy/scripts/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -''' -Created on Jul 2, 2014 - -@author: roj-idl71 -''' diff --git a/schainpy/scripts/amisr_EEJ.py b/schainpy/scripts/amisr_EEJ.py deleted file mode 100644 index 76880db..0000000 --- a/schainpy/scripts/amisr_EEJ.py +++ /dev/null @@ -1,123 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/eej') - -xmin = '7' -xmax = '15' - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2014/10/07', - endDate='2014/10/07', - startTime='07:00:00', - endTime='15:00:00', - walk=0, - timezone='lt', - all=0, - online=0) - -#AMISR Processing Unit -procUnitAMISRBeam0 = controllerObj.addProcUnit(datatype='AMISRProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitAMISRBeam0.addOperation(name='PrintInfo', optype='other') - -#Reshaper -opObj11 = procUnitAMISRBeam0.addOperation(name='ProfileToChannels', optype='other') - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=procUnitAMISRBeam0.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') - -# code = '1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1' -# code = '1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0' -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value='1', format='int') -opObj11.addParameter(name='nBaud', value='28', format='int') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='50', format='float') -# opObj12.addParameter(name='maxHei', value='150', format='float') -#Coherent Integration -#opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -#opObj11.addParameter(name='timeInterval', value='10', format='int') - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=64, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value=64, format='int') - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -# opObj11.addParameter(name='n', value='90', format='int') -opObj11.addParameter(name='timeInterval', value='30', format='float') - -#RemoveDc -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='280', format='float') - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -opObj11.addParameter(name='zmin', value='38', format='int') -opObj11.addParameter(name='zmax', value='68', format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') - -#RTIPlot -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value='38', format='int') -opObj11.addParameter(name='zmax', value='68', format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') - - - -#----------------------------------------------------------------------------------------------- - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_eej_proc_offline.py b/schainpy/scripts/amisr_eej_proc_offline.py deleted file mode 100644 index 19a263a..0000000 --- a/schainpy/scripts/amisr_eej_proc_offline.py +++ /dev/null @@ -1,194 +0,0 @@ -#! /usr/bin/python -#! /usr/bin/env python - -import os, sys -import time - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='eej_proc', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -path = '/media/soporte/E9F4-F053/AMISR/Data/EEJ' -path = '/mnt/data_amisr' -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/eej') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/JULIA/EEJ' -figpath = '/home/soporte/Data/EEJ' - -xmin = '07' -xmax = '18' -dbmin = '45' #'60'#'55' #'40' #noise esf eej -dbmax = '65' #'70' #'55' -show = '0' - -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -nCode = '1' -nBaud = '28' - - -today = time.strftime("%Y/%m/%d") - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate=today, #'2014/10/07', - endDate=today, #'2014/10/07', - startTime='07:01:30',#'07:00:00', - endTime='18:00:00',#'15:00:00', - walk=0, - code = code, - nCode = nCode, - nBaud = nBaud, - timezone='lt', - online=0) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') #changed on Dic 3, 15:40h -#opObj10.addParameter(name='frequency', value='435e6', format='float') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') - -# code = '1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1' -# code = '1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0' -#Noise--> no code - -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value=nCode, format='int') -opObj11.addParameter(name='nBaud', value=nBaud, format='int') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='50', format='float') -# opObj12.addParameter(name='maxHei', value='150', format='float') -#Coherent Integration -# opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') - -# opObj11 = procUnitConfObjBeam0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='121', format='int') - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=16, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='150', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - -# #procUnitConfObjSpectraBeam0.addParameter(name='pairsList', value='(0,0),(1,1),(2,2),(3,3),(4,4)', \ -# # format='pairsList') -# -# # procUnitConfObjSpectraBeam0.addParameter(name='pairsList', value='(0,0)', \ -# # format='pairsList') -# # -# # #RemoveDc -# # opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') -# -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='280', format='float') -#opObj11.addParameter(name='minHei', value='15', format='float') -#opObj11.addParameter(name='maxHei', value='20', format='float') -# # -# #SpectraPlot -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='1', format='int') -# opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -# #opObj11.addParameter(name='zmin', value='38', format='int') -# opObj11.addParameter(name='zmin', value=dbmin, format='int') -# opObj11.addParameter(name='zmax', value=dbmax, format='int') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value = figpath, format='str') -# # -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath+'/plots', format='str') -opObj11.addParameter(name='show', value = show, format='bool') - -# # # -# # # -# #Noise -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='ymin', value=dbmin, format='int') -opObj11.addParameter(name='ymax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath+'/plots', format='str') -opObj11.addParameter(name='show', value = show, format='bool') - - - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -opObj11.addParameter(name='path', value=figpath) -opObj11.addParameter(name='blocksPerFile', value='10', format='int') -opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved - - -# procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -# procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -# procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -# procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -# procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -# procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -# procUnitConfObj2.addParameter(name='period', value=5, format='int') -# procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -#----------------------------------------------------------------------------------------------- -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0.getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -opObj12.addParameter(name='path', value=figpath+'/param') -opObj12.addParameter(name='blocksPerFile', value='10', format='int') -opObj12.addParameter(name='metadataList',value='type,inputUnit,heightList',format='list') -opObj12.addParameter(name='dataList',value='data_param,data_SNR,utctime',format='list') -opObj12.addParameter(name='mode',value='1',format='int') - - - -# print "Escribiendo el archivo XML" -# controllerObj.writeXml(path +'/'+filename) -# print "Leyendo el archivo XML" -# controllerObj.readXml(path +'/'+filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_eej_proc_online.py b/schainpy/scripts/amisr_eej_proc_online.py deleted file mode 100644 index 1c3a1de..0000000 --- a/schainpy/scripts/amisr_eej_proc_online.py +++ /dev/null @@ -1,205 +0,0 @@ -#! /usr/bin/python -#! /usr/bin/env python - -import os, sys -import time - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='eej_proc', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -# path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -# path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -# path = '/media/soporte/E9F4-F053/AMISR/Data/EEJ' -path = '/mnt/data_amisr' -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/eej') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/JULIA/EEJ' -figpath = '/home/soporte/Data/EEJ' -remotefolder = "/home/wmaster/graficos" - -xmin = '07' -xmax = '18' -ymin ='30' -ymax ='300' -dbmin = '45' #'60'#'55' #'40' #noise esf eej -dbmax = '65' #'70' #'55' -show = '1' - -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -nCode = '1' -nBaud = '28' - - -today = time.strftime("%Y/%m/%d") - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate=today, #'2014/10/07', - endDate=today, #'2014/10/07', - startTime='07:01:30',#'07:00:00', - endTime='17:55:00',#'15:00:00', - walk=0, - code = code, - nCode = nCode, - nBaud = nBaud, - timezone='lt', - online=1) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') #changed on Dic 3, 15:40h -#opObj10.addParameter(name='frequency', value='440e6', format='float') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') - - -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value=nCode, format='int') -opObj11.addParameter(name='nBaud', value=nBaud, format='int') - - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=16, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='150', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - - - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='280', format='float') -#opObj11.addParameter(name='minHei', value='15', format='float') -#opObj11.addParameter(name='maxHei', value='20', format='float') - - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='EEJ AMISR', format='str') -opObj11.addParameter(name='ymin', value=ymin, format='int') -opObj11.addParameter(name='ymax', value=ymax, format='int') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='0', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -opObj11.addParameter(name='wintitle', value='EEJ AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='ymin', value=ymin, format='int') -opObj11.addParameter(name='ymax', value=ymax, format='int') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='show', value = show, format='bool') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -# #send to server -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -#procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='server', value='10.10.120.125', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=figpath, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value='300', format='int') -procUnitConfObj2.addParameter(name='protocol', value='ssh', format='str') - - -# #Noise -#title0 = 'RTI AMISR Beam 0' -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -# opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value='EEJ AMISR', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value=xmin, format='float') -# opObj11.addParameter(name='xmax', value=xmax, format='float') -# opObj11.addParameter(name='ymin', value=dbmin, format='int') -# opObj11.addParameter(name='ymax', value=dbmax, format='int') -# opObj11.addParameter(name='save', value='0', format='bool') -# opObj11.addParameter(name='figpath', value = figpath, format='str') -# opObj11.addParameter(name='show', value = show, format='bool') - - -# #For saving Pdata (doesn't work with amisr data yet!) -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value=figpath) -# opObj11.addParameter(name='blocksPerFile', value='10', format='int') -# opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved -# -# -# # procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -# # procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# # procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -# # procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -# # procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -# # procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -# # procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -# # procUnitConfObj2.addParameter(name='period', value=5, format='int') -# # procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -# #----------------------------------------------------------------------------------------------- -# procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0.getId()) -# opObj20 = procUnitConfObj2.addOperation(name='GetMoments') -# -# opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj12.addParameter(name='path', value=figpath+'/plots') -# opObj12.addParameter(name='blocksPerFile', value='10', format='int') -# opObj12.addParameter(name='metadataList',value='type,inputUnit,heightList',format='list') -# opObj12.addParameter(name='dataList',value='data_param,data_SNR,utctime',format='list') -# opObj12.addParameter(name='mode',value='1',format='int') - - - -# print "Escribiendo el archivo XML" -# controllerObj.writeXml(path +'/'+filename) -# print "Leyendo el archivo XML" -# controllerObj.readXml(path +'/'+filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_esf_proc_offline.py b/schainpy/scripts/amisr_esf_proc_offline.py deleted file mode 100644 index 853579c..0000000 --- a/schainpy/scripts/amisr_esf_proc_offline.py +++ /dev/null @@ -1,197 +0,0 @@ -import os, sys -import time -import datetime - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='esf_proc', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -# path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -# path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -# path = '/media/soporte/E9F4-F053/AMISR/Data/ESF' -path = '/mnt/data_amisr' - -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/esf') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/JULIA/ESF' -figpath = '/home/soporte/Data/ESF' -remotefolder = "/home/wmaster/graficos" - -xmin = '18' -xmax = '31' -dbmin = '60' #'60'#'55' #'40' #noise esf eej -dbmax = '75' #'70' #'55' -show = '0' - -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -nCode = '1' -nBaud = '28' -nosamp = '2' # oversample - -str = datetime.date.today() -str1 = str + datetime.timedelta(days=1) -str2 = str - datetime.timedelta(days=1) -today = str.strftime("%Y/%m/%d") -tomorrow = str1.strftime("%Y/%m/%d") -yesterday = str2.strftime("%Y/%m/%d") - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate=yesterday, #'2014/10/07', - endDate=today, #'2014/10/07', - startTime='18:01:30',#'07:00:00', - endTime='07:00:00',#'15:00:00', - walk=0, - code = code, - nCode = nCode, - nBaud = nBaud, - timezone='lt', - online=0) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') #chaned on Dec 3, 15:40h -#opObj10.addParameter(name='frequency', value='435e6', format='float') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') - -# code = '1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1' -# code = '1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0' -#Noise--> no code - -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value=nCode, format='int') -opObj11.addParameter(name='nBaud', value=nBaud, format='int') -opObj11.addParameter(name='osamp', value=nosamp, format='int') - - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='50', format='float') -# opObj12.addParameter(name='maxHei', value='150', format='float') -#Coherent Integration -# opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') - -# opObj11 = procUnitConfObjBeam0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='121', format='int') - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=32, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='60', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - - -# # #RemoveDc -# # opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='650', format='float') -opObj11.addParameter(name='maxHei', value='800', format='float') -#opObj11.addParameter(name='minHei', value='15', format='float') -#opObj11.addParameter(name='maxHei', value='20', format='float') - -# #SpectraPlot -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='1', format='int') -# opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -# #opObj11.addParameter(name='zmin', value='38', format='int') -# opObj11.addParameter(name='zmin', value=dbmin, format='int') -# opObj11.addParameter(name='zmax', value=dbmax, format='int') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value = figpath, format='str') - - -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -opObj11.addParameter(name='wintitle', value='ESF AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath+'/plots', format='str') -opObj11.addParameter(name='show', value = show, format='bool') -# # # -# # # -# #Noise -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -opObj11.addParameter(name='wintitle', value='ESF AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='ymin', value=dbmin, format='int') -opObj11.addParameter(name='ymax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath+'/plots', format='str') -opObj11.addParameter(name='show', value = show, format='bool') - - -#Generate *.pdata from AMISR data -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -opObj11.addParameter(name='path', value=figpath) -opObj11.addParameter(name='blocksPerFile', value='10', format='int') -opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved - -#generate moments -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0.getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -opObj12.addParameter(name='path', value=figpath+'/param') -opObj12.addParameter(name='blocksPerFile', value='10', format='int') -opObj12.addParameter(name='metadataList',value='type,inputUnit,heightList',format='list') -opObj12.addParameter(name='dataList',value='data_param,data_SNR,utctime',format='list') -opObj12.addParameter(name='mode',value='1',format='int') - - -# procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -# procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -# procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -# procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -# procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -# procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -# procUnitConfObj2.addParameter(name='period', value=5, format='int') -# procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -#----------------------------------------------------------------------------------------------- - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_esf_proc_online.py b/schainpy/scripts/amisr_esf_proc_online.py deleted file mode 100644 index fb5cf01..0000000 --- a/schainpy/scripts/amisr_esf_proc_online.py +++ /dev/null @@ -1,220 +0,0 @@ -import os, sys -import time -import datetime - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='esf_proc', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -# path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -# path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -# path = '/media/soporte/E9F4-F053/AMISR/Data/ESF' -path = '/mnt/data_amisr' - -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/esf') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/JULIA/ESF' -figpath = '/home/soporte/Data/ESF' -remotefolder = "/home/wmaster/graficos" - -xmin = '18' -xmax = '31' -dbmin = '60' #'60'#'55' #'40' #noise esf eej -dbmax = '75' #'70' #'55' -show = '1' - -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -nCode = '1' -nBaud = '28' -nosamp = '2' # oversample - -str = datetime.date.today() -str1 = str + datetime.timedelta(days=1) -today = str.strftime("%Y/%m/%d") -tomorrow = str1.strftime("%Y/%m/%d") - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate=today, #'2014/10/07', - endDate=tomorrow, #'2014/10/07', - startTime='18:01:30',#'07:00:00', - endTime='07:00:00',#'15:00:00', - walk=0, - code = code, - nCode = nCode, - nBaud = nBaud, - timezone='lt', - online=1) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') #changed on Dec 3, 15:40h -#opObj10.addParameter(name='frequency', value='435e6', format='float') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') - -# code = '1,1,-1,1,1,-1,1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,1,1,1,-1,-1,-1' -# code = '1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0' -#Noise--> no code - -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value=nCode, format='int') -opObj11.addParameter(name='nBaud', value=nBaud, format='int') -opObj11.addParameter(name='osamp', value=nosamp, format='int') - - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='50', format='float') -# opObj12.addParameter(name='maxHei', value='150', format='float') -#Coherent Integration -# opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') - -# opObj11 = procUnitConfObjBeam0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='121', format='int') - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=32, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='60', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - - -# # #RemoveDc -# # opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='280', format='float') -#opObj11.addParameter(name='minHei', value='15', format='float') -#opObj11.addParameter(name='maxHei', value='20', format='float') - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='ESF AMISR', format='str') -#opObj11.addParameter(name='zmin', value='38', format='int') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='0', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='4', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - - -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -opObj11.addParameter(name='wintitle', value='ESF AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='show', value = show, format='bool') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='4', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - -# #send to server -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -#procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='server', value='10.10.120.125', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=figpath, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value='300', format='int') -procUnitConfObj2.addParameter(name='protocol', value='ssh', format='str') - -# # # -# #Noise -#title0 = 'RTI AMISR Beam 0' -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -# opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value='ESF AMISR', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value=xmin, format='float') -# opObj11.addParameter(name='xmax', value=xmax, format='float') -# opObj11.addParameter(name='ymin', value=dbmin, format='int') -# opObj11.addParameter(name='ymax', value=dbmax, format='int') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value = figpath, format='str') -# opObj11.addParameter(name='show', value = show, format='bool') - - -#Generate *.pdata from AMISR data -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value=figpath) -# opObj11.addParameter(name='blocksPerFile', value='10', format='int') -# opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved -# -# #generate moments -# procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0.getId()) -# opObj20 = procUnitConfObj2.addOperation(name='GetMoments') -# -# opObj12 = procUnitConfObj2.addOperation(name='HDF5Writer', optype='other') -# opObj12.addParameter(name='path', value=figpath+'/plots') -# opObj12.addParameter(name='blocksPerFile', value='10', format='int') -# opObj12.addParameter(name='metadataList',value='type,inputUnit,heightList',format='list') -# opObj12.addParameter(name='dataList',value='data_param,data_SNR,utctime',format='list') -# opObj12.addParameter(name='mode',value='1',format='int') - - -# procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -# procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -# procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -# procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -# procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -# procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -# procUnitConfObj2.addParameter(name='period', value=5, format='int') -# procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -#----------------------------------------------------------------------------------------------- - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_proc.py b/schainpy/scripts/amisr_proc.py deleted file mode 100644 index 5839c7a..0000000 --- a/schainpy/scripts/amisr_proc.py +++ /dev/null @@ -1,92 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = os.path.join(os.environ['HOME'],'Development/amisr/data') -path = '/media/administrator/KINGSTON/amisr' -figpath = os.path.join(os.environ['HOME'],'Pictures/amisr') - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2014/10/21', - endDate='2014/10/21', - startTime='00:00:00', - endTime='23:59:59', - walk=1, - timezone='lt') - -#AMISR Processing Unit -procUnitAMISRBeam0 = controllerObj.addProcUnit(datatype='AMISRProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitAMISRBeam0.addOperation(name='PrintInfo', optype='other') - -#Reshaper -opObj11 = procUnitAMISRBeam0.addOperation(name='ProfileToChannels', optype='other') - - -#Beam Selector -#opObj11 = procUnitAMISRBeam0.addOperation(name='BeamSelector', optype='other') -#opObj11.addParameter(name='beam', value='0', format='int') - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=procUnitAMISRBeam0.getId()) -#Coherent Integration -opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='8', format='int') -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=32, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value=32, format='int') -#RemoveDc -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='5', format='float') -opObj11.addParameter(name='maxHei', value='20', format='float') - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -opObj11.addParameter(name='zmin', value='30', format='int') -opObj11.addParameter(name='zmax', value='80', format='int') - -#RTIPlot -#title0 = 'RTI AMISR Beam 0' -#opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -#opObj11.addParameter(name='id', value='200', format='int') -#opObj11.addParameter(name='wintitle', value=title0, format='str') -#opObj11.addParameter(name='showprofile', value='0', format='int') -##Setting RTI time using xmin,xmax -#opObj11.addParameter(name='xmin', value='15', format='int') -#opObj11.addParameter(name='xmax', value='23', format='int') -#Setting dB range with zmin, zmax -#opObj11.addParameter(name='zmin', value='45', format='int') -#opObj11.addParameter(name='zmax', value='70', format='int') -#Save RTI -#figfile0 = 'amisr_rti_beam0.png' -#opObj11.addParameter(name='figpath', value=figpath, format='str') -#opObj11.addParameter(name='figfile', value=figfile0, format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/amisr_reader.py b/schainpy/scripts/amisr_reader.py deleted file mode 100644 index 3a547ba..0000000 --- a/schainpy/scripts/amisr_reader.py +++ /dev/null @@ -1,39 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = os.path.join(os.environ['HOME'],'Documents/amisr') #'/home/signalchain/Documents/amisr' - -figpath = os.path.join(os.environ['HOME'],'Pictures/amisr') - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2014/08/18', - endDate='2014/08/18', - startTime='00:00:00', - endTime='23:59:59', - walk=1) - -procUnitAMISR = controllerObj.addProcUnit(datatype='AMISRProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitAMISR.addOperation(name='PrintInfo', optype='other') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/amisr_reader_exp.py b/schainpy/scripts/amisr_reader_exp.py deleted file mode 100644 index 02b3033..0000000 --- a/schainpy/scripts/amisr_reader_exp.py +++ /dev/null @@ -1,47 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment Test" -filename = "amisr.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/home/administrator/Documents/amisr' - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISR', - path=path, - startDate='2014/08/18', - endDate='2014/08/18', - startTime='00:00:00', - endTime='23:59:59', - walk=1) - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='AMISR', format='str') -opObj11.addParameter(name='type', value='iq', format='str') - -opObj11 = procUnitConfObjBeam1.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='profileRangeList', value='0,81', format='intlist') - -opObj11 = procUnitConfObj0.addOperation(name='PowerProfile', optype='other') -opObj11.addParameter(name='id', value='102', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Power Profile', format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/amisr_reader_exp_ex2.py b/schainpy/scripts/amisr_reader_exp_ex2.py deleted file mode 100644 index 666fd0a..0000000 --- a/schainpy/scripts/amisr_reader_exp_ex2.py +++ /dev/null @@ -1,404 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment Test" -filename = "amisr.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/home/administrator/Documents/amisr_bug' -path = '/media/administrator/New Volume/amisr' -#path = '/media/administrator/Toshiba/data' -figpath = '/home/administrator/Pictures/amisr' - -figfile0 = 'amisr_rti_beam0.png' -figfile1 = 'amisr_rti_beam1.png' -figfile2 = 'amisr_rti_beam2.png' -figfile3 = 'amisr_rti_beam3.png' -figfile4 = 'amisr_rti_beam4.png' -figfile5 = 'amisr_rti_beam5.png' -figfile6 = 'amisr_rti_beam6.png' - -title0 = 'RTI AMISR Beam 0' -title1 = 'RTI AMISR Beam 1' -title2 = 'RTI AMISR Beam 2' -title3 = 'RTI AMISR Beam 3' -title4 = 'RTI AMISR Beam 4' -title5 = 'RTI AMISR Beam 5' -title6 = 'RTI AMISR Beam 6' - -profileStrSelBeam0 = '0,101' -profileStrSelBeam1 = '614,741' -profileStrSelBeam2 = '358,485' -profileStrSelBeam3 = '742,869' -profileStrSelBeam4 = '230,357' -profileStrSelBeam5 = '486,613' -profileStrSelBeam6 = '102,229' - -nProfiles = '32' -nFFTPoints = '32' - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISR', - path=path, - startDate='2014/08/18', - endDate='2014/08/18', - startTime='00:00:00', - endTime='23:59:59', - walk=1) - - - -# procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# opObj11 = procUnitConfObjBeam0.addOperation(name='ProfileSelector', optype='other') -# opObj11.addParameter(name='profileRangeList', value=profileStrSelBeam0, format='intlist') - -# procUnitConfObjBeam1 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# procUnitConfObjBeam2 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# procUnitConfObjBeam3 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# procUnitConfObjBeam4 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# procUnitConfObjBeam5 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# procUnitConfObjBeam6 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -# procUnitAMISR = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -# opObj11 = procUnitAMISR.addOperation(name='BeamSelector', optype='other') -# opObj11.addParameter(name='beam', value='1', format='int') -# -# procUnitConfObjBeam1 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam0.getId()) -# -# opObj11 = procUnitConfObjBeam1.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='128', format='int') -# -# -# procUnitConfObjSpectraBeam1 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam1.getId()) -# procUnitConfObjSpectraBeam1.addParameter(name='nFFTPoints', value='32', format='int') -# procUnitConfObjSpectraBeam1.addParameter(name='nProfiles', value='32', format='int') -# -# opObj11 = procUnitConfObjSpectraBeam1.addOperation(name='getNoise') -# opObj11.addParameter(name='minHei', value='100', format='float') -# opObj11.addParameter(name='maxHei', value='450', format='float') -# -# opObj11 = procUnitConfObjSpectraBeam1.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='100', format='int') -# opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str') - - - - - - - -# ############################# Beam0 ############################# -procUnitAMISRBeam0 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) - -#opObj11 = procUnitAMISRBeam0.addOperation(name='PrintInfo', optype='other') - - -opObj11 = procUnitAMISRBeam0.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='0', format='int') - -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam0.getId()) - -opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') - - - - -# procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# opObj11 = procUnitConfObjBeam0.addOperation(name='ProfileSelector', optype='other') -# opObj11.addParameter(name='profileRangeList', value=profileStrSelBeam0, format='intlist') -# -# opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='102', format='int') -# -# procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam0.getId()) -# procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value='32', format='int') -# procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value='32', format='int') -# -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -# opObj11.addParameter(name='minHei', value='100', format='float') -# opObj11.addParameter(name='maxHei', value='450', format='float') -# -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='100', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# #opObj11.addParameter(name='timerange', value='7200', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile0, format='str') -# -# -# -# -# -# # - -# ############################# Beam1 ############################# -procUnitAMISRBeam1 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) - -#opObj11 = procUnitAMISRBeam1.addOperation(name='PrintInfo', optype='other') - - -opObj11 = procUnitAMISRBeam1.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='1', format='int') - -procUnitConfObjBeam1 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam1.getId()) - -opObj11 = procUnitConfObjBeam1.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - -procUnitConfObjSpectraBeam1 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam1.getId()) -procUnitConfObjSpectraBeam1.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam1.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam1.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 1', format='str') - -# -# opObj11 = procUnitConfObjSpectraBeam1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='201', format='int') -# opObj11.addParameter(name='wintitle', value=title1, format='str') -# #opObj11.addParameter(name='timerange', value='36000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile1, format='str') -# # -# # -# # -# # -# # -# ############################## Beam2 ############################# -procUnitAMISRBeam2 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -opObj11 = procUnitAMISRBeam2.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='2', format='int') - -procUnitConfObjBeam2 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam2.getId()) - -opObj11 = procUnitConfObjBeam2.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - - -procUnitConfObjSpectraBeam2 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam2.getId()) -procUnitConfObjSpectraBeam2.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam2.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam2.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam2.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='102', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 2', format='str') - -# -# opObj11 = procUnitConfObjSpectraBeam2.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='202', format='int') -# opObj11.addParameter(name='wintitle', value=title2, format='str') -# #opObj11.addParameter(name='timerange', value='18000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile2, format='str') -# -# -# -# -# -# -# ############################## Beam3 ############################# -procUnitAMISRBeam3 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -opObj11 = procUnitAMISRBeam3.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='3', format='int') - -procUnitConfObjBeam3 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam3.getId()) - -opObj11 = procUnitConfObjBeam3.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - - -procUnitConfObjSpectraBeam3 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam3.getId()) -procUnitConfObjSpectraBeam3.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam3.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam3.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam3.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='103', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 3', format='str') - -# -# opObj11 = procUnitConfObjSpectraBeam3.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='203', format='int') -# opObj11.addParameter(name='wintitle', value=title3, format='str') -# #opObj11.addParameter(name='timerange', value='18000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile3, format='str') -# # # -# # # -# # # -# # # -# # # -# # # -# ############################## Beam4 ############################# -procUnitAMISRBeam4 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -opObj11 = procUnitAMISRBeam4.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='4', format='int') - -procUnitConfObjBeam4 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam4.getId()) - -opObj11 = procUnitConfObjBeam4.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - - -procUnitConfObjSpectraBeam4 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam4.getId()) -procUnitConfObjSpectraBeam4.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam4.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam4.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam4.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='104', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 4', format='str') - -# opObj11 = procUnitConfObjSpectraBeam4.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='204', format='int') -# opObj11.addParameter(name='wintitle', value=title4, format='str') -# #opObj11.addParameter(name='timerange', value='18000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile4, format='str') -# # # # -# # # # -# # # # -# # # # -# # # # -# ############################## Beam5 ############################# -procUnitAMISRBeam5 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -opObj11 = procUnitAMISRBeam5.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='5', format='int') - -procUnitConfObjBeam5 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam5.getId()) - -opObj11 = procUnitConfObjBeam5.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - -procUnitConfObjSpectraBeam5 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam5.getId()) -procUnitConfObjSpectraBeam5.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam5.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam5.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam5.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='105', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 5', format='str') - -# opObj11 = procUnitConfObjSpectraBeam5.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='205', format='int') -# opObj11.addParameter(name='wintitle', value=title5, format='str') -# #opObj11.addParameter(name='timerange', value='18000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile5, format='str') -# # # -# # # # -# # # # -# # # # -# # # # -# ############################## Beam6 ############################# -procUnitAMISRBeam6 = controllerObj.addProcUnit(datatype='AMISR', inputId=readUnitConfObj.getId()) -opObj11 = procUnitAMISRBeam6.addOperation(name='BeamSelector', optype='other') -opObj11.addParameter(name='beam', value='6', format='int') - -procUnitConfObjBeam6 = controllerObj.addProcUnit(datatype='Voltage', inputId=procUnitAMISRBeam6.getId()) - -opObj11 = procUnitConfObjBeam6.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='128', format='int') - - -procUnitConfObjSpectraBeam6 = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjBeam6.getId()) -procUnitConfObjSpectraBeam6.addParameter(name='nFFTPoints', value=nFFTPoints, format='int') -procUnitConfObjSpectraBeam6.addParameter(name='nProfiles', value=nProfiles, format='int') - -opObj11 = procUnitConfObjSpectraBeam6.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='100', format='float') -opObj11.addParameter(name='maxHei', value='450', format='float') - -opObj11 = procUnitConfObjSpectraBeam6.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='106', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 6', format='str') -# -# opObj11 = procUnitConfObjSpectraBeam6.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='206', format='int') -# opObj11.addParameter(name='wintitle', value=title6, format='str') -# #opObj11.addParameter(name='timerange', value='18000', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='18', format='int') -# opObj11.addParameter(name='zmin', value='45', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile6, format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/amisr_spreadF.py b/schainpy/scripts/amisr_spreadF.py deleted file mode 100644 index 56a6712..0000000 --- a/schainpy/scripts/amisr_spreadF.py +++ /dev/null @@ -1,119 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = os.path.join(os.environ['HOME'],'amisr') -path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/spreadF/filt2') - -xmin = '18' -xmax = '31' - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2014/10/06', - endDate='2014/10/07', - startTime='18:00:00', - endTime='07:00:00', - walk=0, - timezone='lt', - all=0, - online=0) - -#AMISR Processing Unit -procUnitAMISRBeam0 = controllerObj.addProcUnit(datatype='AMISRProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitAMISRBeam0.addOperation(name='PrintInfo', optype='other') - -#Reshaper -opObj11 = procUnitAMISRBeam0.addOperation(name='ProfileToChannels', optype='other') - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=procUnitAMISRBeam0.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') - -opObj11 = procUnitConfObjBeam0.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='2', format='int') - -# code = '1,1,0,1,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0' -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -opObj11 = procUnitConfObjBeam0.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=code, format='floatlist') -opObj11.addParameter(name='nCode', value='1', format='int') -opObj11.addParameter(name='nBaud', value='28', format='int') - -# opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -# opObj12.addParameter(name='minHei', value='0', format='float') -# opObj12.addParameter(name='maxHei', value='10', format='float') -#Coherent Integration -# opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='timeInterval', value='30', format='int') -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=64, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value=64, format='int') - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='timeInterval', value='30', format='float') -# opObj11.addParameter(name='n', value='64', format='int') - -#RemoveDc -#opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='200', format='float') -opObj11.addParameter(name='maxHei', value='700', format='float') - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -opObj11.addParameter(name='zmin', value='54', format='int') -opObj11.addParameter(name='zmax', value='70', format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') - -#RTIPlot -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value='54', format='int') -opObj11.addParameter(name='zmax', value='70', format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') - - - -#----------------------------------------------------------------------------------------------- - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_windEstimation.py b/schainpy/scripts/amisr_windEstimation.py deleted file mode 100644 index ee0e461..0000000 --- a/schainpy/scripts/amisr_windEstimation.py +++ /dev/null @@ -1,147 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = os.path.join(os.environ['HOME'],'Development/amisr/data') -path = '/home/soporte/Data/AMISR' -figpath = os.path.join(os.environ['HOME'],'Pictures/amisr') - -pathFigure = '/home/operaciones/Documents/AMISR_windprofiler/20141023' -xmin = '8.0' -xmax = '12.0' - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2014/10/23', - endDate='2014/10/23', - startTime='00:00:00', - endTime='23:59:59', - walk=1, - timezone='lt') - -#AMISR Processing Unit -procUnitAMISRBeam0 = controllerObj.addProcUnit(datatype='AMISRProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitAMISRBeam0.addOperation(name='PrintInfo', optype='other') - -#Reshaper -opObj11 = procUnitAMISRBeam0.addOperation(name='ProfileToChannels', optype='other') - - -#Beam Selector -#opObj11 = procUnitAMISRBeam0.addOperation(name='BeamSelector', optype='other') -#opObj11.addParameter(name='beam', value='0', format='int') - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=procUnitAMISRBeam0.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') - -opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -opObj12.addParameter(name='minHei', value='0', format='float') -opObj12.addParameter(name='maxHei', value='10', format='float') -#Coherent Integration -opObj11 = procUnitConfObjBeam0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='8', format='int') -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=32, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='nProfiles', value=32, format='int') - -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='16', format='int') - -#RemoveDc -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') - -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='5', format='float') -opObj11.addParameter(name='maxHei', value='20', format='float') - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='AMISR Beam 0', format='str') -opObj11.addParameter(name='zmin', value='30', format='int') -opObj11.addParameter(name='zmax', value='80', format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = pathFigure, format='str') -#RTIPlot -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='200', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value='30', format='int') -opObj11.addParameter(name='zmax', value='80', format='int') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathFigure, format='str') - -# Save RTI -# figfile0 = 'amisr_rti_beam0.png' -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile0, format='str') - -#----------------------------------------------------------------------------------------------- -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0 .getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other') -opObj21.addParameter(name='id', value='3', format='int') -opObj21.addParameter(name='wintitle', value='Moments Plot', format='str') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value=pathFigure, format='str') -opObj21.addParameter(name='zmin', value='30', format='int') -opObj21.addParameter(name='zmax', value='80', format='int') - -opObj22 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj22.addParameter(name='technique', value='DBS', format='str') -opObj22.addParameter(name='correctAzimuth', value='51.06', format='float') -opObj22.addParameter(name='correctFactor', value='-1', format='float') -opObj22.addParameter(name='azimuth', value='0,-90,0,90,180', format='floatlist') -opObj22.addParameter(name='elevation', value='74.53,75.90.0,75.60,75.60', format='floatlist') -# opObj22.addParameter(name='horizontalOnly', value='1', format='bool') -# opObj22.addParameter(name='channelList', value='1,2', format='intlist') - -opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -opObj23.addParameter(name='id', value='4', format='int') -opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = pathFigure, format='str') -opObj23.addParameter(name='zmin', value='-20', format='int') -opObj23.addParameter(name='zmax', value='20', format='int') -opObj23.addParameter(name='zmin_ver', value='-100', format='float') -opObj23.addParameter(name='zmax_ver', value='100', format='float') -opObj23.addParameter(name='SNRmin', value='-20', format='int') -opObj23.addParameter(name='SNRmax', value='30', format='int') -opObj23.addParameter(name='SNRthresh', value='-50', format='float') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_winds_proc_offline.py b/schainpy/scripts/amisr_winds_proc_offline.py deleted file mode 100644 index 9f55242..0000000 --- a/schainpy/scripts/amisr_winds_proc_offline.py +++ /dev/null @@ -1,222 +0,0 @@ -#! /usr/bin/python -#! /usr/bin/env python - -import os, sys -import time - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='eej_proc', description=desc) - - -# path = os.path.join(os.environ['HOME'],'amisr') -# path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -# path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -# path = '/media/soporte/E9F4-F053/AMISR/Data/EEJ' -# path = '/mnt/data_amisr' -# path = '/media/soporte/E9F4-F053/AMISR/Data/winds' -path = '/mnt/data_amisr' - -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/esf') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/JULIA/ESF' -figpath = '/home/soporte/Data/winds' -remotefolder = "/home/wmaster/graficos" -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/eej') -#figpath = '/media/soporte/E9F4-F053/AMISR/Data/winds/plots' - -xmin = '08' -xmax = '18' -dbmin = '50' #'60'#'55' #'40' #noise esf eej -dbmax = '80' #'70' #'55' - -ippFactor = '5' - -code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -nCode = '1' -nBaud = '28' - - -today = time.strftime("%Y/%m/%d") - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2015/11/12', #'2014/10/07', - endDate='2015/11/12', #'2014/10/07', - startTime='00:00:00',#'07:00:00', - endTime='23:59:59',#'15:00:00', - walk=0, -# code = code, -# nCode = nCode, -# nBaud = nBaud, - timezone='lt', - online=1) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') - - - -opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -opObj12.addParameter(name='minHei', value='0', format='float') -opObj12.addParameter(name='maxHei', value='10', format='float') - - - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=64, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='ippFactor', value=ippFactor, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='64', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - - -# # #RemoveDc -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') -# -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='5', format='float') -opObj11.addParameter(name='maxHei', value='9', format='float') - - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='Winds AMISR', format='str') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -opObj11.addParameter(name='wintitle', value='Winds AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') -# -# -# #Noise -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='ymin', value=dbmin, format='int') -opObj11.addParameter(name='ymax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -#For saving Pdata (doesn't work with amisr data yet!) -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value=figpath) -# opObj11.addParameter(name='blocksPerFile', value='100', format='int') -# opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved - -# opObj22.addParameter(name='azimuth', value='0,-90,0,90,180', format='floatlist') -# opObj22.addParameter(name='elevation', value='75.6,75.6,90,75.60,75.6', format='floatlist') - -#Parameters Process -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObjSpectraBeam0.getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -opObj22 = procUnitConfObj2.addOperation(name='WindProfiler', optype='other') -opObj22.addParameter(name='technique', value='DBS', format='str') -opObj22.addParameter(name='correctAzimuth', value='51.06', format='float') -opObj22.addParameter(name='correctFactor', value='-1', format='float') -opObj22.addParameter(name='azimuth', value='0,-90,0,90,180', format='floatlist') -opObj22.addParameter(name='elevation', value='75.6,75.6,90,75.60,75.60', format='floatlist') - -#WindProfilerPlot -opObj23 = procUnitConfObj2.addOperation(name='WindProfilerPlot', optype='other') -opObj23.addParameter(name='id', value='4', format='int') -opObj23.addParameter(name='wintitle', value='Wind Profiler', format='str') -opObj23.addParameter(name='save', value='1', format='bool') -opObj23.addParameter(name='figpath', value = figpath, format='str') -opObj23.addParameter(name='zmin', value='-20', format='int') -opObj23.addParameter(name='zmax', value='20', format='int') -opObj23.addParameter(name='zmin_ver', value='-100', format='float') -opObj23.addParameter(name='zmax_ver', value='100', format='float') -opObj23.addParameter(name='SNRmin', value='-20', format='int') -opObj23.addParameter(name='SNRmax', value='30', format='int') -opObj23.addParameter(name='SNRthresh', value='-50', format='float') -opObj23.addParameter(name='xmin', value=xmin, format='float') -opObj23.addParameter(name='xmax', value=xmax, format='float') -opObj23.addParameter(name='ftp', value='1', format='int') -opObj23.addParameter(name='wr_period', value='2', format='int') -opObj23.addParameter(name='exp_code', value='21', format='int') -opObj23.addParameter(name='sub_exp_code', value='3', format='int') -opObj23.addParameter(name='ftp_wei', value='0', format='int') -opObj23.addParameter(name='plot_pos', value='0', format='int') - -#--------------------------------------------------------------------------------------------- - -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=figpath, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value=60, format='int') -procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -#----------------------------------------------------------------------------------------------- - - -# print "Escribiendo el archivo XML" -# controllerObj.writeXml(path +'/'+filename) -# print "Leyendo el archivo XML" -# controllerObj.readXml(path +'/'+filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/amisr_winds_proc_online.py b/schainpy/scripts/amisr_winds_proc_online.py deleted file mode 100644 index 4a67b51..0000000 --- a/schainpy/scripts/amisr_winds_proc_online.py +++ /dev/null @@ -1,176 +0,0 @@ -#! /usr/bin/python -#! /usr/bin/env python - -import os, sys -import time - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "AMISR Experiment" - -filename = "amisr_reader.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='eej_proc', description=desc) - - -# path = os.path.join(os.environ['HOME'],'amisr') -# path = '/media/signalchain/HD-PXU2/AMISR_JULIA_MODE' -# path = '/media/soporte/E9F4-F053/AMISR/Data/NoiseTest/EEJ' -# path = '/media/soporte/E9F4-F053/AMISR/Data/EEJ' -# path = '/mnt/data_amisr' -# path = '/media/soporte/E9F4-F053/AMISR/Data/winds' -path = '/mnt/data_amisr' -#path = '/media/soporte/AMISR_104' -#figpath = os.path.join(os.environ['HOME'],'Pictures/amisr/test/proc/eej') -figpath = '/home/soporte/Data/winds/plots' -remotefolder = "/home/wmaster/graficos" - -xmin = '08' -xmax = '18' -dbmin = '50' #'60'#'55' #'40' #noise esf eej -dbmax = '80' #'70' #'55' - -#to consider that each real IPP is actually original_IPP * nchannels -ippFactor = '5' - -# code = '1,-1,-1,-1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1' -# nCode = '1' -# nBaud = '28' - - -today = time.strftime("%Y/%m/%d") - - -readUnitConfObj = controllerObj.addReadUnit(datatype='AMISRReader', - path=path, - startDate='2016/10/28', #'2014/10/07', - endDate='2014/10/28', #'2014/10/07', - startTime='00:00:00',#'07:00:00', - endTime='23:59:59',#'15:00:00', - walk=0, -# code = code, -# nCode = nCode, -# nBaud = nBaud, - timezone='lt', - online=1) - -#AMISR Processing Unit - -#Voltage Processing Unit -procUnitConfObjBeam0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) -opObj10 = procUnitConfObjBeam0.addOperation(name='setRadarFrequency') -opObj10.addParameter(name='frequency', value='445e6', format='float') - - - -opObj12 = procUnitConfObjBeam0.addOperation(name='selectHeights') -opObj12.addParameter(name='minHei', value='0', format='float') -opObj12.addParameter(name='maxHei', value='10', format='float') - - - -#Spectra Unit Processing, getting spectras with nProfiles and nFFTPoints -procUnitConfObjSpectraBeam0 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjBeam0.getId()) -procUnitConfObjSpectraBeam0.addParameter(name='nFFTPoints', value=32, format='int') -procUnitConfObjSpectraBeam0.addParameter(name='ippFactor', value=ippFactor, format='int') -# -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='16', format='int') -#opObj11.addParameter(name='timeInterval', value='30', format='float') - - -# # #RemoveDc -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='removeDC') -# -#Noise Estimation -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='getNoise') -opObj11.addParameter(name='minHei', value='5', format='float') -opObj11.addParameter(name='maxHei', value='9', format='float') - - -#SpectraPlot -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1', format='int') -opObj11.addParameter(name='wintitle', value='Winds AMISR', format='str') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -# #RTIPlot -# #title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2', format='int') -opObj11.addParameter(name='wintitle', value='Winds AMISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='zmin', value=dbmin, format='int') -opObj11.addParameter(name='zmax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='21', format='int') -opObj11.addParameter(name='sub_exp_code', value='3', format='int') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') -# -# -# #Noise -#title0 = 'RTI AMISR Beam 0' -opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='Noise', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value=title0, format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value=xmin, format='float') -opObj11.addParameter(name='xmax', value=xmax, format='float') -opObj11.addParameter(name='ymin', value=dbmin, format='int') -opObj11.addParameter(name='ymax', value=dbmax, format='int') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value = figpath, format='str') - - -#For saving Pdata (doesn't work with amisr data yet!) -# opObj11 = procUnitConfObjSpectraBeam0.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value=figpath) -# opObj11.addParameter(name='blocksPerFile', value='100', format='int') -# opObj11.addParameter(name='datatype', value="4", format="int") #size of data to be saved - - -# procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -# procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -# procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -# procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -# procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -# procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -# procUnitConfObj2.addParameter(name='period', value=5, format='int') -# procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') -#----------------------------------------------------------------------------------------------- - - -# print "Escribiendo el archivo XML" -# controllerObj.writeXml(path +'/'+filename) -# print "Leyendo el archivo XML" -# controllerObj.readXml(path +'/'+filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - -#21 3 pm - - diff --git a/schainpy/scripts/beacon_phase.py b/schainpy/scripts/beacon_phase.py deleted file mode 100644 index 9f9d784..0000000 --- a/schainpy/scripts/beacon_phase.py +++ /dev/null @@ -1,56 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "Meteor Experiment Test" -filename = "jasmet20140415.xml" - -controllerObj = Project() -controllerObj.setup(id = '191', name='meteor_test01', description=desc) - -path = '/home/dsuarez/.gvfs/data on 10.10.20.13/Jasmet50/d2014104' - - -readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path=path, - startDate='2013/08/21', - endDate='2013/08/21', - startTime='00:00:00', - endTime='23:59:59', - online=0, - walk=0) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -procUnitConfObjBeacon = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj0.getId()) -procUnitConfObjBeacon.addParameter(name='nProfiles', value='200', format='int') -procUnitConfObjBeacon.addParameter(name='nFFTPoints', value='200', format='int') -procUnitConfObjBeacon.addParameter(name='pairsList', value='(0,5),(1,5),(2,5),(3,5),(4,5)', format='pairsList') - -opObj11 = procUnitConfObjBeacon.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='4', format='int') - -opObj11 = procUnitConfObjBeacon.addOperation(name='getBeaconSignal') - -opObj11 = procUnitConfObjBeacon.addOperation(name='BeaconPhase', optype='other') -opObj11.addParameter(name='id', value='301', format='int') -opObj11.addParameter(name='wintitle', value='Beacon Phase', format='str') -opObj11.addParameter(name='timerange', value='300', format='int') -opObj11.addParameter(name='ymin', value='-180', format='float') -opObj11.addParameter(name='ymax', value='180', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value='/home/dsuarez/Pictures/beacon_abril', format='str') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/hf_plot_pdata.py b/schainpy/scripts/hf_plot_pdata.py deleted file mode 100644 index b61e3a4..0000000 --- a/schainpy/scripts/hf_plot_pdata.py +++ /dev/null @@ -1,197 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "HF_EXAMPLE" -filename = "hf_test.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -#path='/media/APOLLO/HF_rawdata/d2015026/0/cspec' -#path='/media/APOLLO/HF_rawdata/cspec' -#path='/media/APOLLO/bistatico' -#path='/home/alex/Downloads/pdata_hf/sousy' -path='/home/alex/Downloads/pdata_hf' -#path='/media/APOLLO/bistatico' - - - -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f0" #f0=2.72e6 -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f1" #f0=3.64e6 -#path='/media/APOLLO/HF_rawdata/test' -#figpath='/home/alex/Pictures/hf2_16/last_data' -figpath='/home/alex/Pictures/pdata_plot' -pathFigure='/home/alex/Pictures/hf2_16/last_data' -#path='/home/alex/Downloads/ICA_LAST_TEST' - -readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader', - path=path, - startDate='2015/01/12', - endDate='2015/05/13', - startTime='00:00:00', - endTime='23:59:59', - online=0, - #set=1426485881, - delay=10, - walk=1 - #timezone=-5*3600 - ) - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='1000', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='zmin', value='-120', format='float') -opObj11.addParameter(name='zmax', value='-70', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile_spectra_name, format='str') -# opObj11.addParameter(name='wr_period', value='5', format='int') -#opObj11.addParameter(name='ftp_wei', value='0', format='int') -#opObj11.addParameter(name='exp_code', value='20', format='int') -#opObj11.addParameter(name='sub_exp_code', value='0', format='int') -#opObj11.addParameter(name='plot_pos', value='0', format='int') - - - -# # figfile_power_name="jro_power_image"+freq2+date+ext_img -# # print figfile_power_name -opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='2000', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='xmin', value='0', format='float') -opObj11.addParameter(name='xmax', value='24', format='float') -opObj11.addParameter(name='zmin', value='-110', format='float') -opObj11.addParameter(name='zmax', value='-50', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -#opObj11.addParameter(name='figfile', value=figfile_power_name, format='str') -#opObj11.addParameter(name='wr_period', value='5', format='int') - -# -# opObj11 = procUnitConfObj1.addOperation(name='PowerProfile', optype='other') -# opObj11.addParameter(name='id', value='2004', format='int') -# opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# #opObj11.addParameter(name='channelList', value='0', format='intlist') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# #opObj11.addParameter(name='xmin', value='10', format='int') -# #opObj11.addParameter(name='xmax', value='40', format='int') -# -# # figfile_phase_name="jro_phase_image"+freq1+date+ext_img -# # print figfile_phase_name -opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -opObj11.addParameter(name='id', value='3000', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -opObj11.addParameter(name='showprofile', value='1', format='int') -opObj11.addParameter(name='xmin', value='0', format='float') -opObj11.addParameter(name='xmax', value='24', format='float') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value=figpath, format='str') - # opObj11.addParameter(name='figfile', value=figfile_phase_name, format='str') - # opObj11.addParameter(name='wr_period', value='5', format='int') - -# opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='6005', format='int') -# opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# opObj11.addParameter(name='zmin', value='-110', format='float') -# opObj11.addParameter(name='zmax', value='-50', format='float') -# #opObj11.addParameter(name='xmin', value='0', format='float') -# #opObj11.addParameter(name='xmax', value='24', format='float') -# #opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# -# -# -# xmin = 0 -# xmax = 24 -# -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -# opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other') -# opObj21.addParameter(name='id', value='3', format='int') -# opObj21.addParameter(name='wintitle', value='Moments Plot', format='str') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value=pathFigure, format='str') -# opObj21.addParameter(name='zmin', value='5', format='int') -# opObj21.addParameter(name='zmax', value='90', format='int') -# -opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -opObj21.addParameter(name='id', value='4000', format='int') -opObj21.addParameter(name='wintitle', value='Radial Velocity Plot0', format='str') -opObj21.addParameter(name='channelList', value='0', format='intlist') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value=figpath, format='str') -opObj21.addParameter(name='SNR', value='1', format='bool') -opObj21.addParameter(name='SNRmin', value='-10', format='int') -opObj21.addParameter(name='SNRmax', value='50', format='int') -opObj21.addParameter(name='SNRthresh', value='0', format='float') -opObj21.addParameter(name='xmin', value=0, format='float') -opObj21.addParameter(name='xmax', value=24, format='float') -#opObj21.addParameter(name='parameterIndex', value=, format='int') - -# -opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -opObj21.addParameter(name='id', value='5000', format='int') -opObj21.addParameter(name='wintitle', value='Radial Velocity Plot1', format='str') -opObj21.addParameter(name='channelList', value='1', format='intlist') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value=figpath, format='str') -opObj21.addParameter(name='SNR', value='1', format='bool') -opObj21.addParameter(name='SNRmin', value='-20', format='int') -opObj21.addParameter(name='SNRmax', value='50', format='int') -opObj21.addParameter(name='SNRthresh', value='0', format='float') -opObj21.addParameter(name='xmin', value=0, format='float') -opObj21.addParameter(name='xmax', value=24, format='float') - -# -# -# opObj23 = procUnitConfObj2.addOperation(name='EWDriftsPlot', optype='other') -# opObj23.addParameter(name='id', value='4', format='int') -# opObj23.addParameter(name='wintitle', value='EW Drifts', format='str') -# opObj23.addParameter(name='save', value='1', format='bool') -# opObj23.addParameter(name='figpath', value = pathFigure, format='str') -# opObj23.addParameter(name='zminZonal', value='-150', format='int') -# opObj23.addParameter(name='zmaxZonal', value='150', format='int') -# opObj23.addParameter(name='zminVertical', value='-30', format='float') -# opObj23.addParameter(name='zmaxVertical', value='30', format='float') -# opObj23.addParameter(name='SNR_1', value='1', format='bool') -# opObj23.addParameter(name='SNRmax', value='5', format='int') -# # opObj23.addParameter(name='SNRthresh', value='-50', format='float') -# opObj23.addParameter(name='xmin', value=xmin, format='float') -# opObj23.addParameter(name='xmax', value=xmax, format='float') -# -# -# # opObj11 = procUnitConf.Obj1.addOperation(name='SendByFTP', optype='other') -# # opObj11.addParameter(name='ext', value='*.jpeg', format='str') -# # opObj11.addParameter(name='localfolder', value='/home/alex/Pictures/ftp', format='str') -# # opObj11.addParameter(name='remotefolder', value='/home/wmaster/web2/data/JRO/HFT/2015/03/11/figures/', format='str') -# # opObj11.addParameter(name='server', value='181.177.232.125', format='str') -# # opObj11.addParameter(name='username', value='wmaster', format='str') -# # opObj11.addParameter(name='password', value='mst2010vhf', format='str') -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/hf_test.py b/schainpy/scripts/hf_test.py deleted file mode 100644 index 0aff4c7..0000000 --- a/schainpy/scripts/hf_test.py +++ /dev/null @@ -1,236 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -#--------------------------------------- -freq1="_2.72MHz_" -freq2="_3.64MHz_" - -date="2015-03-12_N" -ext_img=".jpeg" - - -#--------------------------------------- - - - -desc = "HF_EXAMPLE" -filename = "hf_test.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -#-----------------------PATH------------------------------# -#path='/media/APOLLO/HF_rawdata/d2015026/0/cspec' -#path='/media/APOLLO/HF_rawdata/cspec' -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f0" #f0=2.72e6 -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f1" #f0=3.64e6 -#path='/media/APOLLO/HF_rawdata/test' -path='/media/APOLLO/HF_rawdata/HFT_miercoles/sp01_f0' -#---------------------------------------------------------# - -#---------------------PATH-FIGURE------------------------# -#figpath='/home/alex/Pictures/hf2_16/last_data' -figpath='/home/alex/Pictures/ftp' -pathFigure='/home/alex/Pictures/hf2_16/last_data' -#path='/home/alex/Downloads/ICA_LAST_TEST' -#---------------------------------------------------------# -readUnitConfObj = controllerObj.addReadUnit(datatype='HFReader', - path=path, - startDate='2013/01/1', - endDate='2015/05/13', - startTime='00:00:00', - endTime='23:59:59', - online=0, - #set=1426485881, - delay=10, - walk=1, - timezone=-5*3600) - - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -# opObj12 = procUnitConfObj0.addOperation(name='selectChannels',optype='self') -# opObj12.addParameter(name='channelList', value='0', format='intList') - -opObj12 = procUnitConfObj0.addOperation(name='setRadarFrequency') -opObj12.addParameter(name='frequency', value='3.64e6', format='float') - -opObj12 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj12.addParameter(name='n', value='4', format='int') - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='Voltage', format='str') -# opObj11.addParameter(name='ymin', value='-1e-8', format='float') -# opObj11.addParameter(name='ymax', value='1e-8', format='float') -# # -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='25', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='25', format='int') -procUnitConfObj1.addParameter(name='pairsList', value='(0,1)', format='pairsList') - - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='6', format='float') - -#opObj11 = procUnitConfObj1.addOperation(name='SpectraWriter', optype='other') -#opObj11.addParameter(name='path', value='/home/alex/Downloads/pdata_hf') -#opObj11.addParameter(name='blocksPerFile', value='1', format='int') -# -# -opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='2001', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='zmin', value='-120', format='float') -opObj11.addParameter(name='zmax', value='-70', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -# opObj11.addParameter(name='figfile', value=figfile_spectra_name, format='str') -# opObj11.addParameter(name='wr_period', value='5', format='int') -#opObj11.addParameter(name='ftp_wei', value='0', format='int') -#opObj11.addParameter(name='exp_code', value='20', format='int') -#opObj11.addParameter(name='sub_exp_code', value='0', format='int') -#opObj11.addParameter(name='plot_pos', value='0', format='int') - -# figfile_power_name="jro_power_image"+freq2+date+ext_img -# print figfile_power_name -opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='3002', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='xmin', value='0', format='float') -opObj11.addParameter(name='xmax', value='24', format='float') -opObj11.addParameter(name='zmin', value='-110', format='float') -opObj11.addParameter(name='zmax', value='-50', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -#opObj11.addParameter(name='figfile', value=figfile_power_name, format='str') -#opObj11.addParameter(name='wr_period', value='5', format='int') - - -#opObj11 = procUnitConfObj1.addOperation(name='PowerProfile', optype='other') -#opObj11.addParameter(name='id', value='2004', format='int') -#opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -#opObj11.addParameter(name='save', value='1', format='bool') -#opObj11.addParameter(name='figpath', value=figpath, format='str') -#opObj11.addParameter(name='xmin', value='10', format='int') -#opObj11.addParameter(name='xmax', value='40', format='int') - -# figfile_phase_name="jro_phase_image"+freq1+date+ext_img -# print figfile_phase_name -opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -opObj11.addParameter(name='id', value='3', format='int') -opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -opObj11.addParameter(name='showprofile', value='1', format='int') -opObj11.addParameter(name='xmin', value='0', format='float') -opObj11.addParameter(name='xmax', value='24', format='float') -#opObj11.addParameter(name='channelList', value='0', format='intlist') -opObj11.addParameter(name='save', value='1', format='bool') -opObj11.addParameter(name='figpath', value=figpath, format='str') - # opObj11.addParameter(name='figfile', value=figfile_phase_name, format='str') - # opObj11.addParameter(name='wr_period', value='5', format='int') - -#opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -#opObj11.addParameter(name='id', value='6005', format='int') -#opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -#opObj11.addParameter(name='zmin', value='-110', format='float') -#opObj11.addParameter(name='zmax', value='-50', format='float') -#opObj11.addParameter(name='xmin', value='0', format='float') -#opObj11.addParameter(name='xmax', value='24', format='float') -#opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -#opObj11.addParameter(name='save', value='1', format='bool') -#opObj11.addParameter(name='figpath', value=figpath, format='str') - - - -#xmin = 0 -#xmax = 24 - -procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -opObj20 = procUnitConfObj2.addOperation(name='GetMoments') - -#opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other') -#opObj21.addParameter(name='id', value='3', format='int') -#opObj21.addParameter(name='wintitle', value='Moments Plot', format='str') -#opObj21.addParameter(name='save', value='1', format='bool') -#opObj21.addParameter(name='figpath', value=pathFigure, format='str') -#opObj21.addParameter(name='zmin', value='5', format='int') -#opObj21.addParameter(name='zmax', value='90', format='int') - -opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -opObj21.addParameter(name='id', value='1', format='int') -opObj21.addParameter(name='wintitle', value='Radial Velocity Plot0', format='str') -opObj21.addParameter(name='channelList', value='0', format='intlist') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value=figpath, format='str') -opObj21.addParameter(name='SNR', value='1', format='bool') -opObj21.addParameter(name='SNRmin', value='-10', format='int') -opObj21.addParameter(name='SNRmax', value='50', format='int') -opObj21.addParameter(name='SNRthresh', value='0', format='float') -opObj21.addParameter(name='xmin', value=0, format='float') -opObj21.addParameter(name='xmax', value=24, format='float') -#opObj21.addParameter(name='parameterIndex', value=, format='int') - - -opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -opObj21.addParameter(name='id', value='2', format='int') -opObj21.addParameter(name='wintitle', value='Radial Velocity Plot1', format='str') -opObj21.addParameter(name='channelList', value='1', format='intlist') -opObj21.addParameter(name='save', value='1', format='bool') -opObj21.addParameter(name='figpath', value=figpath, format='str') -opObj21.addParameter(name='SNR', value='1', format='bool') -opObj21.addParameter(name='SNRmin', value='-20', format='int') -opObj21.addParameter(name='SNRmax', value='50', format='int') -opObj21.addParameter(name='SNRthresh', value='0', format='float') -opObj21.addParameter(name='xmin', value=0, format='float') -opObj21.addParameter(name='xmax', value=24, format='float') - - -# -# opObj23 = procUnitConfObj2.addOperation(name='EWDriftsPlot', optype='other') -# opObj23.addParameter(name='id', value='4', format='int') -# opObj23.addParameter(name='wintitle', value='EW Drifts', format='str') -# opObj23.addParameter(name='save', value='1', format='bool') -# opObj23.addParameter(name='figpath', value = pathFigure, format='str') -# opObj23.addParameter(name='zminZonal', value='-150', format='int') -# opObj23.addParameter(name='zmaxZonal', value='150', format='int') -# opObj23.addParameter(name='zminVertical', value='-30', format='float') -# opObj23.addParameter(name='zmaxVertical', value='30', format='float') -# opObj23.addParameter(name='SNR_1', value='1', format='bool') -# opObj23.addParameter(name='SNRmax', value='5', format='int') -# # opObj23.addParameter(name='SNRthresh', value='-50', format='float') -# opObj23.addParameter(name='xmin', value=xmin, format='float') -# opObj23.addParameter(name='xmax', value=xmax, format='float') - - -#opObj11 = procUnitConfObj1.addOperation(name='SendByFTP', optype='other') -#opObj11.addParameter(name='ext', value='*.jpeg', format='str') -#opObj11.addParameter(name='localfolder', value='/home/alex/Pictures/ftp', format='str') -#opObj11.addParameter(name='remotefolder', value='/home/wmaster/web2/data/JRO/HFT/2015/03/11/figures/', format='str') -#opObj11.addParameter(name='server', value='181.177.232.125', format='str') -#opObj11.addParameter(name='username', value='wmaster', format='str') -#opObj11.addParameter(name='password', value='mst2010vhf', format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/hf_write_pdata.py b/schainpy/scripts/hf_write_pdata.py deleted file mode 100644 index ea7631b..0000000 --- a/schainpy/scripts/hf_write_pdata.py +++ /dev/null @@ -1,237 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -#--------------------------------------- -freq1="_2.72MHz_" -freq2="_3.64MHz_" - -date="2015-03-12_N" -ext_img=".jpeg" - - -#--------------------------------------- - - - -desc = "HF_EXAMPLE" -filename = "hf_test.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -#-----------------------PATH------------------------------# -#path='/media/APOLLO/HF_rawdata/d2015026/0/cspec' -#path='/media/APOLLO/HF_rawdata/cspec' -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f0" #f0=2.72e6 -#path="/media/APOLLO/HF_rawdata/d2015059/sp01_f1" #f0=3.64e6 -#path='/media/APOLLO/HF_rawdata/test' -path='/media/APOLLO/HF_rawdata/HFT_miercoles/sp01_f0' -#---------------------------------------------------------# - -#---------------------PATH-FIGURE------------------------# -#figpath='/home/alex/Pictures/hf2_16/last_data' -figpath='/home/alex/Pictures/ftp' -pathFigure='/home/alex/Pictures/hf2_16/last_data' -#path='/home/alex/Downloads/ICA_LAST_TEST' -#---------------------------------------------------------# -readUnitConfObj = controllerObj.addReadUnit(datatype='HFReader', - path=path, - startDate='2013/01/1', - endDate='2015/05/13', - startTime='00:00:00', - endTime='23:59:59', - online=0, - #set=850, - delay=10, - walk=1, - timezone=-5*3600) - - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -# opObj12 = procUnitConfObj0.addOperation(name='selectChannels',optype='self') -# opObj12.addParameter(name='channelList', value='0', format='intList') - -opObj12 = procUnitConfObj0.addOperation(name='setRadarFrequency') -opObj12.addParameter(name='frequency', value='3.64e6', format='float') - -opObj12 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj12.addParameter(name='n', value='4', format='int') - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='Voltage', format='str') -# opObj11.addParameter(name='ymin', value='-1e-8', format='float') -# opObj11.addParameter(name='ymax', value='1e-8', format='float') -# # -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObj0.getId()) -procUnitConfObj1.addParameter(name='nFFTPoints', value='25', format='int') -procUnitConfObj1.addParameter(name='nProfiles', value='25', format='int') -procUnitConfObj1.addParameter(name='pairsList', value='(0,1)', format='pairsList') - - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='6', format='float') - -opObj11 = procUnitConfObj1.addOperation(name='SpectraWriter', optype='other') -opObj11.addParameter(name='path', value='/home/alex/Downloads/pdata_hf') -opObj11.addParameter(name='blocksPerFile', value='1', format='int') -# -# -# # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# # opObj11.addParameter(name='id', value='2001', format='int') -# # opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') -# # #opObj11.addParameter(name='channelList', value='0', format='intlist') -# # opObj11.addParameter(name='zmin', value='-120', format='float') -# # opObj11.addParameter(name='zmax', value='-70', format='float') -# # opObj11.addParameter(name='save', value='1', format='int') -# # opObj11.addParameter(name='figpath', value=figpath, format='str') -# # # opObj11.addParameter(name='figfile', value=figfile_spectra_name, format='str') -# # # opObj11.addParameter(name='wr_period', value='5', format='int') -# # #opObj11.addParameter(name='ftp_wei', value='0', format='int') -# # #opObj11.addParameter(name='exp_code', value='20', format='int') -# # #opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# # #opObj11.addParameter(name='plot_pos', value='0', format='int') -# # -# # figfile_power_name="jro_power_image"+freq2+date+ext_img -# # print figfile_power_name -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='3002', format='int') -# opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='channelList', value='0', format='intlist') -# opObj11.addParameter(name='xmin', value='0', format='float') -# opObj11.addParameter(name='xmax', value='24', format='float') -# opObj11.addParameter(name='zmin', value='-110', format='float') -# opObj11.addParameter(name='zmax', value='-50', format='float') -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# #opObj11.addParameter(name='figfile', value=figfile_power_name, format='str') -# #opObj11.addParameter(name='wr_period', value='5', format='int') -# -# -# #opObj11 = procUnitConfObj1.addOperation(name='PowerProfile', optype='other') -# #opObj11.addParameter(name='id', value='2004', format='int') -# #opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# ##opObj11.addParameter(name='channelList', value='0', format='intlist') -# #opObj11.addParameter(name='save', value='1', format='bool') -# #opObj11.addParameter(name='figpath', value=figpath, format='str') -# ##opObj11.addParameter(name='xmin', value='10', format='int') -# ##opObj11.addParameter(name='xmax', value='40', format='int') -# -# # figfile_phase_name="jro_phase_image"+freq1+date+ext_img -# # print figfile_phase_name -# opObj11 = procUnitConfObj1.addOperation(name='CoherenceMap', optype='other') -# opObj11.addParameter(name='id', value='3', format='int') -# opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# opObj11.addParameter(name='showprofile', value='1', format='int') -# opObj11.addParameter(name='xmin', value='0', format='float') -# opObj11.addParameter(name='xmax', value='24', format='float') -# #opObj11.addParameter(name='channelList', value='0', format='intlist') -# opObj11.addParameter(name='save', value='1', format='bool') -# opObj11.addParameter(name='figpath', value=figpath, format='str') -# # # opObj11.addParameter(name='figfile', value=figfile_phase_name, format='str') -# # # opObj11.addParameter(name='wr_period', value='5', format='int') -# -# # opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -# # opObj11.addParameter(name='id', value='6005', format='int') -# # opObj11.addParameter(name='wintitle', value='HF_Jicamarca', format='str') -# # opObj11.addParameter(name='zmin', value='-110', format='float') -# # opObj11.addParameter(name='zmax', value='-50', format='float') -# # #opObj11.addParameter(name='xmin', value='0', format='float') -# # #opObj11.addParameter(name='xmax', value='24', format='float') -# # #opObj11.addParameter(name='channelList', value='0,1,2,3', format='intlist') -# # opObj11.addParameter(name='save', value='1', format='bool') -# # opObj11.addParameter(name='figpath', value=figpath, format='str') -# -# -# -# # xmin = 0 -# # xmax = 24 -# #------------------------------------------------------------------ -# # -# procUnitConfObj2 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=procUnitConfObj1.getId()) -# opObj20 = procUnitConfObj2.addOperation(name='GetMoments') -# -# # opObj21 = procUnitConfObj2.addOperation(name='MomentsPlot', optype='other') -# # opObj21.addParameter(name='id', value='3', format='int') -# # opObj21.addParameter(name='wintitle', value='Moments Plot', format='str') -# # opObj21.addParameter(name='save', value='1', format='bool') -# # opObj21.addParameter(name='figpath', value=pathFigure, format='str') -# #opObj21.addParameter(name='zmin', value='5', format='int') -# #opObj21.addParameter(name='zmax', value='90', format='int') -# -# opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -# opObj21.addParameter(name='id', value='1', format='int') -# opObj21.addParameter(name='wintitle', value='Radial Velocity Plot0', format='str') -# opObj21.addParameter(name='channelList', value='0', format='intlist') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value=figpath, format='str') -# opObj21.addParameter(name='SNR', value='1', format='bool') -# opObj21.addParameter(name='SNRmin', value='-10', format='int') -# opObj21.addParameter(name='SNRmax', value='50', format='int') -# opObj21.addParameter(name='SNRthresh', value='0', format='float') -# opObj21.addParameter(name='xmin', value=0, format='float') -# opObj21.addParameter(name='xmax', value=24, format='float') -# #opObj21.addParameter(name='parameterIndex', value=, format='int') -# -# -# opObj21 = procUnitConfObj2.addOperation(name='ParametersPlot', optype='other') -# opObj21.addParameter(name='id', value='2', format='int') -# opObj21.addParameter(name='wintitle', value='Radial Velocity Plot1', format='str') -# opObj21.addParameter(name='channelList', value='1', format='intlist') -# opObj21.addParameter(name='save', value='1', format='bool') -# opObj21.addParameter(name='figpath', value=figpath, format='str') -# opObj21.addParameter(name='SNR', value='1', format='bool') -# opObj21.addParameter(name='SNRmin', value='-20', format='int') -# opObj21.addParameter(name='SNRmax', value='50', format='int') -# opObj21.addParameter(name='SNRthresh', value='0', format='float') -# opObj21.addParameter(name='xmin', value=0, format='float') -# opObj21.addParameter(name='xmax', value=24, format='float') -# -# -# -# # opObj23 = procUnitConfObj2.addOperation(name='EWDriftsPlot', optype='other') -# # opObj23.addParameter(name='id', value='4', format='int') -# # opObj23.addParameter(name='wintitle', value='EW Drifts', format='str') -# # opObj23.addParameter(name='save', value='1', format='bool') -# # opObj23.addParameter(name='figpath', value = pathFigure, format='str') -# # opObj23.addParameter(name='zminZonal', value='-150', format='int') -# # opObj23.addParameter(name='zmaxZonal', value='150', format='int') -# # opObj23.addParameter(name='zminVertical', value='-30', format='float') -# # opObj23.addParameter(name='zmaxVertical', value='30', format='float') -# # opObj23.addParameter(name='SNR_1', value='1', format='bool') -# # opObj23.addParameter(name='SNRmax', value='5', format='int') -# # # opObj23.addParameter(name='SNRthresh', value='-50', format='float') -# # opObj23.addParameter(name='xmin', value=xmin, format='float') -# # opObj23.addParameter(name='xmax', value=xmax, format='float') -# -# -# opObj11 = procUnitConfObj1.addOperation(name='SendByFTP', optype='other') -# opObj11.addParameter(name='ext', value='*.jpeg', format='str') -# opObj11.addParameter(name='localfolder', value='/home/alex/Pictures/ftp', format='str') -# opObj11.addParameter(name='remotefolder', value='/home/wmaster/web2/data/JRO/HFT/2015/03/11/figures/', format='str') -# opObj11.addParameter(name='server', value='181.177.232.125', format='str') -# opObj11.addParameter(name='username', value='wmaster', format='str') -# opObj11.addParameter(name='password', value='mst2010vhf', format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/jacktotalrunner.py b/schainpy/scripts/jacktotalrunner.py deleted file mode 100644 index 8dd6afa..0000000 --- a/schainpy/scripts/jacktotalrunner.py +++ /dev/null @@ -1,143 +0,0 @@ -import os, sys -from pytz import timezone -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) - -print path -sys.path.insert(0, path) # Para usar las librerias del eclipse. - -from schainpy.controller import Project - -# from __main__ import time -#path = os.path.split(os.getcwd())[0] -#sys.path.append(path) -# import scipy.io as sio -# import pprint -# import numpy -# import time -# import os -# import h5py -# import re -# import tables -# -# from model.data.jrodata import * -# from model.proc.jroproc_base import ProcessingUnit, Operation -# from model.io.jroIO_base import * - - -# controllerObj = Project() - -# controllerObj.setup(id = '191', name='test01', description=desc) - - -#from controller import * - -desc = "DBS Experiment Test" -filename = "DBStest.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#path = 'F:\CIRI Data\processed' -#path='/media/4B514E8903EBC487/CIRI Data/processed' -#path='/home/ciri/ciri_online' -#offline program -#path='/home/ciri/.gvfs/SFTP for radar on 192.168.1.161/media/dataswap/huancayo/20150701/processed' -#online program -path='/home/ciri/.gvfs/SFTP for radar on 192.168.1.161/media/dataswap/huancayo/processed' -#pathFigure = 'C:\Users\jdk5273\Documents\LiClipseWorkspace' -pathFigure='/home/ciri/Pictures/ciri' -xmin = '0' -xmax = '24' -startTime = '00:00:00' -remotefolder = "/home/wmaster/graficos" - -readUnitConfObj = controllerObj.addReadUnit(datatype='matoffReader', - path=path, - startDate='2015/05/30', - endDate='2015/05/30', - startTime=startTime, - endTime='23:59:59', - online=1, - delay=5, - walk=0) - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=readUnitConfObj.getId()) - -# opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -# opObj14.addParameter(name='id', value='1', format='int') -# opObj14.addParameter(name='wintitle', value='Con interf', format='str') -# opObj14.addParameter(name='save', value='0', format='bool') -# opObj14.addParameter(name='figpath', value=pathFigure, format='str') - -opObj11 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='60', format='int') - -opObj14 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj14.addParameter(name='id', value='2', format='int') -opObj14.addParameter(name='wintitle', value='Con interf', format='str') -opObj14.addParameter(name='save', value='1', format='bool') -opObj14.addParameter(name='figpath', value=pathFigure, format='str') -opObj14.addParameter(name='zmin', value='-30', format='int') -opObj14.addParameter(name='zmax', value='0', format='int') -opObj14.addParameter(name='exp_code', value='29', format='int') -opObj14.addParameter(name='wr_period', value='1', format='int') -opObj14.addParameter(name='save', value='1', format='int') - -opObj14.addParameter(name='ftp', value='1', format='int') - -opObj14 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') -opObj14.addParameter(name='id', value='4', format='int') -opObj14.addParameter(name='wintitle', value='Con interf', format='str') -opObj14.addParameter(name='phase_cmap', value='jet', format='str') -opObj14.addParameter(name='save', value='1', format='bool') -opObj14.addParameter(name='figpath', value=pathFigure, format='str') -opObj14.addParameter(name='zmin', value='-30', format='int') -opObj14.addParameter(name='zmax', value='0', format='int') -opObj14.addParameter(name='exp_code', value='29', format='int') -opObj14.addParameter(name='wr_period', value='1', format='int') -opObj14.addParameter(name='save', value='1', format='int') - -opObj14.addParameter(name='ftp', value='1', format='int') - -opObj12 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj12.addParameter(name='id', value='3', format='int') -opObj12.addParameter(name='wintitle', value='RTI Plot', format='str') -opObj12.addParameter(name='save', value='1', format='bool') -opObj12.addParameter(name='figpath', value = pathFigure, format='str') -opObj12.addParameter(name='xmin', value=xmin, format='float') -opObj12.addParameter(name='xmax', value=xmax, format='float') -opObj12.addParameter(name='zmin', value='-30', format='int') -opObj12.addParameter(name='zmax', value='0', format='int') -opObj12.addParameter(name='exp_code', value='29', format='int') -opObj12.addParameter(name='wr_period', value='1', format='int') -opObj12.addParameter(name='save', value='1', format='int') - -opObj12.addParameter(name='ftp', value='1', format='int') - -# -procUnitConfObj2 = controllerObj.addProcUnit(name='SendToServer') -procUnitConfObj2.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -procUnitConfObj2.addParameter(name='username', value='wmaster', format='str') -procUnitConfObj2.addParameter(name='password', value='mst2010vhf', format='str') -procUnitConfObj2.addParameter(name='localfolder', value=pathFigure, format='str') -procUnitConfObj2.addParameter(name='remotefolder', value=remotefolder, format='str') -procUnitConfObj2.addParameter(name='ext', value='.png', format='str') -procUnitConfObj2.addParameter(name='period', value=5, format='int') -procUnitConfObj2.addParameter(name='protocol', value='ftp', format='str') - - - - -#-------------------------------------------------------------------------------------------------- -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() - - diff --git a/schainpy/scripts/jasmet50_16april.py b/schainpy/scripts/jasmet50_16april.py deleted file mode 100644 index 92d85c4..0000000 --- a/schainpy/scripts/jasmet50_16april.py +++ /dev/null @@ -1,79 +0,0 @@ -""" -Se debe verficar que el disco de datos se encuentra montado en el sistema -""" -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "Meteor Experiment Test" -filename = "meteor20130812.xml" - -controllerObj = Project() -controllerObj.setup(id = '191', name='meteor_test01', description=desc) - -path = '/home/dsuarez/.gvfs/data on 10.10.20.13/Jasmet50' - - -readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path=path, - startDate='2014/04/16', - endDate='2014/04/16', - startTime='00:00:00', - endTime='23:59:59', - online=0, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj0.addOperation(name='setRadarFrequency') -opObj11.addParameter(name='frequency', value='30.15e6', format='float') - -opObj11 = procUnitConfObj0.addOperation(name='Decoder', optype='other') - - -opObj11 = procUnitConfObj0.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='int') - -opObj11 = procUnitConfObj0.addOperation(name='VoltageWriter', optype='other') -opObj11.addParameter(name='path', value='/media/datos/jasmet50_abril') -opObj11.addParameter(name='blocksPerFile', value='100', format='int') -opObj11.addParameter(name='profilesPerBlock', value='200', format='int') - - -""" -########################################### BEACON ########################################## -""" - -procUnitConfObjBeacon = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObj0.getId()) -procUnitConfObjBeacon.addParameter(name='nProfiles', value='200', format='int') -procUnitConfObjBeacon.addParameter(name='nFFTPoints', value='200', format='int') -procUnitConfObjBeacon.addParameter(name='pairsList', value='(2,0),(2,1),(2,3),(2,4)', format='pairsList') - -opObj11 = procUnitConfObjBeacon.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='4', format='int') - -opObj11 = procUnitConfObjBeacon.addOperation(name='getBeaconSignal') - -opObj11 = procUnitConfObjBeacon.addOperation(name='BeaconPhase', optype='other') -opObj11.addParameter(name='id', value='301', format='int') -opObj11.addParameter(name='wintitle', value='Beacon Phase', format='str') -opObj11.addParameter(name='xmin', value='0', format='float') -opObj11.addParameter(name='xmax', value='24', format='float') -opObj11.addParameter(name='ymin', value='-180', format='float') -opObj11.addParameter(name='ymax', value='180', format='float') -opObj11.addParameter(name='figpath', value='/media/datos/jasmet50_phase', format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/julia_mp.py b/schainpy/scripts/julia_mp.py index 875df5f..2a8eaf1 100644 --- a/schainpy/scripts/julia_mp.py +++ b/schainpy/scripts/julia_mp.py @@ -1,77 +1,94 @@ -#!/usr/bin/env python -''' -Created on Jul 7, 2014 +import argparse -@author: roj-idl71 -''' -import os, sys -from datetime import datetime, timedelta -import multiprocessing -from schainpy.controller import Project +from schainpy.controller import Project, multiSchain -def main(date): +desc = "HF_EXAMPLE" + +def fiber(cursor, skip, q, dt): controllerObj = Project() - controllerObj.setup(id = '191', name='test01', description='') + controllerObj.setup(id='191', name='test01', description=desc) - readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path='/data/workspace/data/zeus/', - startDate=date, - endDate=date, - startTime='00:00:00', - endTime='23:59:59', + readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader', + path='/home/nanosat/data/julia', + startDate=dt, + endDate=dt, + startTime="00:00:00", + endTime="23:59:59", online=0, + #set=1426485881, + delay=10, walk=1, - expLabel='') + queue=q, + cursor=cursor, + skip=skip, + #timezone=-5*3600 + ) - procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - #opObj11 = procUnitConfObj1.addOperation(name='removeDC') - #opObj11.addParameter(name='mode', value='1', format='int') + # #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') + # + procUnitConfObj2 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) + # procUnitConfObj2.addParameter(name='nipp', value='5', format='int') - #opObj11 = procUnitConfObj1.addOperation(name='removeInterference') + # procUnitConfObj3 = controllerObj.addProcUnit(datatype='ParametersProc', inputId=readUnitConfObj.getId()) + # opObj11 = procUnitConfObj3.addOperation(name='SpectralMoments', optype='other') + # + opObj11 = procUnitConfObj2.addOperation(name='RTIPlot', optype='other') + opObj11.addParameter(name='id', value='1000', format='int') + opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') + opObj11.addParameter(name='xmin', value='0', format='int') + opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='10', format='int') -# opObj11.addParameter(name='wintitle', value='150Km', format='str') -# opObj11.addParameter(name='colormap', value='jro', format='str') -# opObj11.addParameter(name='xaxis', value='time', format='str') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='23', format='int') -# #opObj11.addParameter(name='ymin', value='100', format='int') -# #opObj11.addParameter(name='ymax', value='150', format='int') -# opObj11.addParameter(name='zmin', value='10', format='int') -# opObj11.addParameter(name='zmax', value='35', format='int') + # opObj11 = procUnitConfObj3.addOperation(name='Parameters1Plot', optype='other') + # opObj11.addParameter(name='channelList', value='0', format='intList') + # + # opObj11.addParameter(name='id', value='2000', format='int') + # # opObj11.addParameter(name='colormap', value='0', format='bool') + # opObj11.addParameter(name='onlySNR', value='1', format='bool') + # opObj11.addParameter(name='DOP', value='0', format='bool') + # opObj11.addParameter(name='showSNR', value='1', format='bool') + # opObj11.addParameter(name='SNRthresh', value='0', format='int') + # opObj11.addParameter(name='SNRmin', value='-10', format='int') + # opObj11.addParameter(name='SNRmax', value='30', format='int') - + # opObj11.addParameter(name='showSNR', value='1', format='int') + # # opObj11.addParameter(name='channelList', value='0', format='intlist') + # # opObj11.addParameter(name='xmin', value='0', format='float') + # opObj11.addParameter(name='xmin', value='0', format='float') + # opObj11.addParameter(name='xmax', value='24', format='float') + # opObj11.addParameter(name='zmin', value='-110', format='float') + # opObj11.addParameter(name='zmax', value='-70', format='float') + # opObj11.addParameter(name='save', value='0', format='int') + # # opObj11.addParameter(name='figpath', value='/tmp/', format='str') + # + # opObj12 = procUnitConfObj2.addOperation(name='PublishData', optype='other') + # opObj12.addParameter(name='zeromq', value=1, format='int') + # opObj12.addParameter(name='server', value='tcp://10.10.10.82:7000', format='str') - opObj11 = procUnitConfObj1.addOperation(name='PlotRTIData', optype='other') - opObj11.addParameter(name='id', value='12', format='int') - opObj11.addParameter(name='wintitle', value='150Km', format='str') - opObj11.addParameter(name='colormap', value='jro', format='str') - opObj11.addParameter(name='xaxis', value='time', format='str') - opObj11.addParameter(name='xmin', value='0', format='int') - opObj11.addParameter(name='xmax', value='23', format='int') - #opObj11.addParameter(name='ymin', value='100', format='int') - #opObj11.addParameter(name='ymax', value='150', format='int') - opObj11.addParameter(name='zmin', value='10', format='int') - opObj11.addParameter(name='zmax', value='35', format='int') - #opObj11.addParameter(name='pause', value='1', format='bool') - opObj11.addParameter(name='show', value='0', format='bool') - opObj11.addParameter(name='save', value='/tmp', format='str') + + # opObj13 = procUnitConfObj3.addOperation(name='PublishData', optype='other') + # opObj13.addParameter(name='zeromq', value=1, format='int') + # opObj13.addParameter(name='server', value="juanca", format='str') + + # opObj12.addParameter(name='delay', value=1, format='int') + # print "Escribiendo el archivo XML" + # controllerObj.writeXml(filename) + # print "Leyendo el archivo XML" + # controllerObj.readXml(filename) + + + # timeit.timeit('controllerObj.run()', number=2) + controllerObj.start() -if __name__=='__main__': - - dt = datetime(2017, 1, 12) - - dates = [(dt+timedelta(x)).strftime('%Y/%m/%d') for x in range(20)] - - p = multiprocessing.Pool(4) - p.map(main, dates) - - \ No newline at end of file + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Set number of parallel processes') + parser.add_argument('--nProcess', default=1, type=int) + args = parser.parse_args() + multiSchain(fiber, nProcess=args.nProcess, startDate='2016/08/19', endDate='2016/08/19') diff --git a/schainpy/scripts/mst_isr_eej_blocks.py b/schainpy/scripts/mst_isr_eej_blocks.py deleted file mode 100644 index f495ad9..0000000 --- a/schainpy/scripts/mst_isr_eej_blocks.py +++ /dev/null @@ -1,225 +0,0 @@ -import os, sys -#import timeit - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "MST-ISR-EEJ Experiment Test" -filename = "mst_isr_eej_blocks.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/Volumes/HD-PXU2/mst_isr_eej' - -figpath = '/Users/dsuarez/Pictures/mst_isr_eej/' - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2014/05/01', - endDate='2014/05/30', - startTime='00:00:00', - endTime='23:59:59', - online=0, - delay=10, - walk=0, - getblock=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') -# ################ EEJ #################################### -procUnitConfObjEEJ = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjEEJ.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -opObj11 = procUnitConfObjEEJ.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value='1,-1', format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -opObj11.addParameter(name='nBaud', value='1', format='int') -opObj11.addParameter(name='mode', value='3', format='int') -opObj11.addParameter(name='times', value='32', format='int') - -# opObj11 = procUnitConfObjEEJ.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') - -procUnitConfObjEEJSpecta = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjEEJ.getId()) -procUnitConfObjEEJSpecta.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObjEEJSpecta.addParameter(name='nProfiles', value='64', format='int') - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='IncohInt', optype='other') -#opObj11.addParameter(name='timeInterval', value='10', format='float') -opObj11.addParameter(name='n', value='36', format='float') - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='60', format='int')# opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - -# opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SendByFTP', optype='other') -# opObj11.addParameter(name='ext', value='*.png', format='str') -# opObj11.addParameter(name='localfolder', value=figpath, format='str') -# opObj11.addParameter(name='remotefolder', value='/home/wmaster/graficos', format='str') -# opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# opObj11.addParameter(name='username', value='wmaster', format='str') -# opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# opObj11.addParameter(name='period', value='5', format='int') - - -################ MST #################################### -procUnitConfObjMST = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjMST.addOperation(name='ProfileSelector', optype='other') -profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119' -#profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19' -opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -opObj11 = procUnitConfObjMST.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='mode',value='3',format='int') -opObj11.addParameter(name='times',value='10',format='int') - -opObj11 = procUnitConfObjMST.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='20', format='int') -opObj11.addParameter(name='byblock', value='1', format='bool') - -procUnitConfObjMSTSpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjMST.getId()) -procUnitConfObjMSTSpectra.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObjMSTSpectra.addParameter(name='nProfiles', value='64', format='int') - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='float') - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='200', format='int') -opObj11.addParameter(name='wintitle', value='MST', format='str') -# # opObj11.addParameter(name='zmin', value='35', format='int') -# # opObj11.addParameter(name='zmax', value='60', format='int') -# # opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# # opObj11.addParameter(name='ftp', value='1', format='int') -# # opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# # opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# # opObj11.addParameter(name='username', value='wmaster', format='str') -# # opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# # opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -# # opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# # opObj11.addParameter(name='plot_pos', value='0', format='int') -# # -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='201', format='int') -opObj11.addParameter(name='wintitle', value='MST', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -# # opObj11.addParameter(name='xmin', value='0', format='int') -# # opObj11.addParameter(name='xmax', value='24', format='int') -# # opObj11.addParameter(name='zmin', value='35', format='int') -# # opObj11.addParameter(name='zmax', value='60', format='int') -# # opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# # opObj11.addParameter(name='ftp', value='1', format='int') -# # opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# # opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# # opObj11.addParameter(name='username', value='wmaster', format='str') -# # opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# # opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -# # opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# # opObj11.addParameter(name='plot_pos', value='0', format='int') - -# ################ ISR #################################### -procUnitConfObjISR = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjISR.addOperation(name='ProfileSelector', optype='other') -# profileIndex = '20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99' -# opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') -opObj11.addParameter(name='profileRangeList', value='20,99', format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -# opObj11 = procUnitConfObjISR.addOperation(name='ProfileConcat', optype='other') -# opObj11.addParameter(name='m', value='5', format='int') - -opObj11 = procUnitConfObjISR.addOperation(name='Reshaper', optype='other') #Esta Operacion opera sobre bloques y reemplaza el ProfileConcat que opera sobre perfiles -opObj11.addParameter(name='shape', value='4,16,6750', format='intlist') # shape = (nchannels, nprofiles, nhieghts) - -opObj11 = procUnitConfObjISR.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='20', format='int') -opObj11.addParameter(name='axis', value='2', format='int') - -barker3x1 = '1,1,-1,-1,-1,1' -#barker3x5 = '1,1,1,1,1, 1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1' - -opObj11 = procUnitConfObjISR.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=barker3x1, format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -#opObj11.addParameter(name='nBaud', value='15', format='int') -opObj11.addParameter(name='nBaud', value='3', format='int') -opObj11.addParameter(name='mode', value='3', format='int') -opObj11.addParameter(name='times', value='8', format='int') -opObj11.addParameter(name='osamp', value='5', format='int') - - -procUnitConfObjISRSpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjISR.getId()) -procUnitConfObjISRSpectra.addParameter(name='nFFTPoints', value='16', format='int') -procUnitConfObjISRSpectra.addParameter(name='nProfiles', value='16', format='int') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='36', format='float') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='300', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='301', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() -#print fib(5) \ No newline at end of file diff --git a/schainpy/scripts/mst_isr_eej_processing.py b/schainpy/scripts/mst_isr_eej_processing.py deleted file mode 100644 index af0fb15..0000000 --- a/schainpy/scripts/mst_isr_eej_processing.py +++ /dev/null @@ -1,271 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "EWDrifts Experiment Test" -filename = "mst_isr_eej.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path='/remote/ewdrifts/RAW_EXP/EW_DRIFT_FARADAY/EW_Drift' - -path1 = '/media/New Volume/DATA/MST_ISR' - -path2 = '/media/DATA/DATA/RAW_EXP/MST-EEJ' - -path = path1 + ',' + path2 - -path = '/home/dsuarez/.gvfs/data on 10.10.20.13/MST_ISR_EEJ' -gpath = '/media/datos/pictures/mstisr_mayo2014' - -path = '/Volumes/New Volume/mst_isr_eej' -gpath = '/Users/dsuarez/Pictures/poster' - -readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path=path, - startDate='2014/05/15', - endDate='2014/05/15', - startTime='08:00:00', - endTime='16:00:00', - delay=3, - set=0, - online=0, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -######################################################### -################ MST #################################### -######################################################### - -# procUnitConfObjMST = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# -# opObj11 = procUnitConfObjMST.addOperation(name='ProfileSelector', optype='other') -# profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119' -# -# opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') -# -# opObj11 = procUnitConfObjMST.addOperation(name='Decoder', optype='other') -# -# opObj11 = procUnitConfObjMST.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='20', format='int') -# -# procUnitConfObjMSTSpectra = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjMST.getId()) -# procUnitConfObjMSTSpectra.addParameter(name='nFFTPoints', value='64', format='int') -# procUnitConfObjMSTSpectra.addParameter(name='nProfiles', value='64', format='int') -# -# opObj11 = procUnitConfObjMSTSpectra.addOperation(name='IncohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='float') - -# opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value='/media/datos/mst2014') -# opObj11.addParameter(name='blocksPerFile', value='10', format='int') - - -# opObj11 = procUnitConfObjMSTSpectra.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='1000', format='int') -# opObj11.addParameter(name='wintitle', value='MST', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11.addParameter(name='ymin', value='120', format='int') -# opObj11.addParameter(name='ymax', value='190', format='int') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='50', format='int') - - -# opObj11 = procUnitConfObjMSTSpectra.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='101', format='int') -# opObj11.addParameter(name='wintitle', value='MST', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='channelList', value='3', format='intlist') -# #opObj11.addParameter(name='timerange', value='300', format='float') -# opObj11.addParameter(name='xmin', value='8', format='float') -# opObj11.addParameter(name='xmax', value='16', format='float') -# opObj11.addParameter(name='ymin', value='120', format='float') -# opObj11.addParameter(name='ymax', value='190', format='float') -# opObj11.addParameter(name='zmin', value='20', format='float') -# opObj11.addParameter(name='zmax', value='45', format='float') -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figfile', value='rti_mst.pdf', format='str') -# opObj11.addParameter(name='figpath', value='/Users/dsuarez/Pictures/poster', format='str') - - -# opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='1001', format='int') -# opObj11.addParameter(name='wintitle', value='MST', format='str') -# opObj11.addParameter(name='ymin', value='120', format='int') -# opObj11.addParameter(name='ymax', value='190', format='int') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='45', format='int') - -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figpath', value=gpath, format='str') -# opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp', value='1', format='int') -# opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# opObj11.addParameter(name='username', value='wmaster', format='str') -# opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -# opObj11.addParameter(name='exp_code', value='19', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - - -######################################################## -############### ISR #################################### -######################################################## - -procUnitConfObjISR = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjISR.addOperation(name='ProfileSelector', optype='other') - -profileIndex = '20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99' - -opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') - -opObj11 = procUnitConfObjISR.addOperation(name='ProfileConcat', optype='other') -opObj11.addParameter(name='m', value='5', format='int') - -opObj11 = procUnitConfObjISR.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='20', format='int') - -barker3x1 = '1,1,-1,-1,-1,1' -barker3x5 = '1,1,1,1,1, 1,1,1,1,1,-1,-1,-1,-1,-1,' + \ - '-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1' - - -opObj11 = procUnitConfObjISR.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=barker3x5, format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -opObj11.addParameter(name='nBaud', value='15', format='int') - - -procUnitConfObjISRSpectra = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjISR.getId()) -procUnitConfObjISRSpectra.addParameter(name='nFFTPoints', value='16', format='int') -procUnitConfObjISRSpectra.addParameter(name='nProfiles', value='16', format='int') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='36', format='float') - -# opObj11 = procUnitConfObjISRSpectra.addOperation(name='SpectraWriter', optype='other') -# opObj11.addParameter(name='path', value='/media/datos/isr2014') -# opObj11.addParameter(name='blocksPerFile', value='120', format='int') - - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='channelList', value='3', format='intlist') -#opObj11.addParameter(name='timerange', value='300', format='float') -opObj11.addParameter(name='xmin', value='8', format='float') -opObj11.addParameter(name='xmax', value='16', format='float') -# opObj11.addParameter(name='ymin', value='120', format='float') -# opObj11.addParameter(name='ymax', value='190', format='float') -opObj11.addParameter(name='zmin', value='20', format='float') -opObj11.addParameter(name='zmax', value='55', format='float') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figfile', value='rti_mst_isr.pdf', format='str') -opObj11.addParameter(name='figpath', value='/Users/dsuarez/Pictures/poster', format='str') - - -# opObj11 = procUnitConfObjISRSpectra.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='2000', format='int') -# opObj11.addParameter(name='wintitle', value='ISR', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11.addParameter(name='zmin', value='30', format='int') -# opObj11.addParameter(name='zmax', value='70', format='int') -# -# opObj11 = procUnitConfObjISRSpectra.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='2001', format='int') -# opObj11.addParameter(name='wintitle', value='ISR', format='str') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='60', format='int') -# -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figpath', value=gpath, format='str') -# opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp', value='1', format='int') -# opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# opObj11.addParameter(name='username', value='wmaster', format='str') -# opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -# opObj11.addParameter(name='exp_code', value='20', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - -# -# ######################################################### -# ################ EEJ #################################### -# ######################################################### -# ######################################################### -# -# procUnitConfObjEEJ = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# -# opObj11 = procUnitConfObjEEJ.addOperation(name='ProfileSelector', optype='other') -# opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist') -# -# opObj11 = procUnitConfObjEEJ.addOperation(name='Decoder', optype='other') -# opObj11.addParameter(name='code', value='1,-1', format='floatlist') -# opObj11.addParameter(name='nCode', value='2', format='int') -# opObj11.addParameter(name='nBaud', value='1', format='int') -# -# procUnitConfObjEEJSpecta = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjEEJ.getId()) -# procUnitConfObjEEJSpecta.addParameter(name='nFFTPoints', value='64', format='int') -# procUnitConfObjEEJSpecta.addParameter(name='nProfiles', value='64', format='int') -# -# opObj11 = procUnitConfObjEEJSpecta.addOperation(name='IncohInt', optype='other') -# opObj11.addParameter(name='n', value='36', format='float') -# -# # opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SpectraWriter', optype='other') -# # opObj11.addParameter(name='path', value='/media/datos/eej2014') -# # opObj11.addParameter(name='blocksPerFile', value='10', format='int') -# -# -# opObj11 = procUnitConfObjEEJSpecta.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='3000', format='int') -# opObj11.addParameter(name='wintitle', value='EEJ', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='xmin', value='0', format='int') -# opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='50', format='int') -# -# opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SpectraPlot', optype='other') -# opObj11.addParameter(name='id', value='3001', format='int') -# opObj11.addParameter(name='wintitle', value='EEJ', format='str') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='50', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figpath', value=gpath, format='str') -# opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp', value='1', format='int') -# opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# opObj11.addParameter(name='username', value='wmaster', format='str') -# opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -# opObj11.addParameter(name='exp_code', value='22', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() diff --git a/schainpy/scripts/optimun_offset.py b/schainpy/scripts/optimun_offset.py index 8ebcba0..fa6e660 100644 --- a/schainpy/scripts/optimun_offset.py +++ b/schainpy/scripts/optimun_offset.py @@ -93,7 +93,11 @@ def filterOffsets(offsets0, stdvLimit): #---------------------- Setup --------------------------- +<<<<<<< HEAD +path = '/home/nanosat/Pictures/JASMET30_mp/201608/phase' +======= path = '/home/jespinoza/Pictures/JASMET30/201608/phase' +>>>>>>> master stdvLimit = 0.5 #---------------------- Script --------------------------- diff --git a/schainpy/scripts/plot_eej.py b/schainpy/scripts/plot_eej.py deleted file mode 100644 index 47ae5b5..0000000 --- a/schainpy/scripts/plot_eej.py +++ /dev/null @@ -1,91 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "EWDrifts+Imaging+Faraday Experiments" -filename = "eej_plots.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = '/media/DATA/eej2014' -figpath = '/home/operaciones/Pictures/eej_mayo2014' - -readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path=path, - startDate='2014/01/08', - endDate='2014/01/08', - startTime='10:00:00', - endTime='14:59:59', - delay=10, - online=1, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -opObj11.addParameter(name='zmin', value='15', format='int') -opObj11.addParameter(name='zmax', value='50', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='wr_period', value='3', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') -# -# -# -opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='50', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - -# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='105', format='int') -# opObj11.addParameter(name='wintitle', value='EEJ', format='str') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='timerange', value='300', format='int') -# opObj11.addParameter(name='zmin', value='15', format='int') -# opObj11.addParameter(name='zmax', value='30', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='figpath', value='/home/operaciones/Pictures/eej_mayo2014', format='str') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/plot_isr.py b/schainpy/scripts/plot_isr.py deleted file mode 100644 index bba05f9..0000000 --- a/schainpy/scripts/plot_isr.py +++ /dev/null @@ -1,79 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "EWDrifts+Imaging+Faraday Experiments" -filename = "isr_plots.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = '/media/DATA/isr2014' -figpath = '/home/operaciones/Pictures/isr_mayo2014' -readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path=path, - startDate='2014/01/08', - endDate='2014/01/08', - startTime='10:00:00', - endTime='14:59:59', - delay=40, - online=1, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='200', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='zmin', value='30', format='int') -opObj11.addParameter(name='zmax', value='70', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='wr_period', value='3', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - -opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='201', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='zmin', value='30', format='int') -opObj11.addParameter(name='zmax', value='70', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/plot_mst.py b/schainpy/scripts/plot_mst.py deleted file mode 100644 index 72ab023..0000000 --- a/schainpy/scripts/plot_mst.py +++ /dev/null @@ -1,88 +0,0 @@ -import os, sys - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -desc = "EWDrifts+Imaging+Faraday Experiments" -filename = "mst_plots.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - - -path = '/media/DATA/isr2014' -figpath = '/home/operaciones/Pictures/isr_mayo2014' -readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path=path, - startDate='2014/01/08', - endDate='2014/01/08', - startTime='10:00:00', - endTime='14:59:59', - delay=20, - online=1, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObjMSTSpectra = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - - - - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='215', format='int') -opObj11.addParameter(name='wintitle', value='MST', format='str') -opObj11.addParameter(name='ymin', value='120', format='int') -opObj11.addParameter(name='ymax', value='190', format='int') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='50', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value='/home/dsuarez/Pictures/mst_mayo2014', format='str') -opObj11.addParameter(name='wr_period', value='1', format='int') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='301', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='ymin', value='120', format='int') -opObj11.addParameter(name='ymax', value='190', format='int') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='50', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value='/home/dsuarez/Pictures/mst_mayo2014', format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -opObj11.addParameter(name='sub_exp_code', value='0', format='int') -opObj11.addParameter(name='plot_pos', value='0', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/schain b/schainpy/scripts/schain deleted file mode 100644 index 820a401..0000000 --- a/schainpy/scripts/schain +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 7, 2014 - -@author: roj-idl71 -''' -import os, sys - -from schainpy import controller_api -from optparse import OptionParser - -USAGE = """This script executes Signal Chain using parameters stored in [filename]. - -$ schain --file=[filename] -""" - -def main(filename): - - controllerObj = controller_api.ControllerThread() - if not controllerObj.readXml(filename): - return - - #Configure use of external plotter before start - plotterObj = controllerObj.useExternalPlotter() - ######################################## - - controllerObj.start() - plotterObj.start() - - print "Finishing all processes ..." - - controllerObj.join(5) - - print "End of script" - -if __name__ == '__main__': - - parser = OptionParser(usage=USAGE) - - parser.add_option("-f", "--file", type="string", default="", - help="File containing schain parameters") - - (op, args) = parser.parse_args() - - if not op.file: - parser.print_help() - sys.exit(0) - - main(op.file) \ No newline at end of file diff --git a/schainpy/scripts/schain.xml b/schainpy/scripts/schain.xml new file mode 100644 index 0000000..80c9912 --- /dev/null +++ b/schainpy/scripts/schain.xml @@ -0,0 +1 @@ + diff --git a/schainpy/scripts/schain_paralel.py b/schainpy/scripts/schain_paralel.py deleted file mode 100644 index d1e2e98..0000000 --- a/schainpy/scripts/schain_paralel.py +++ /dev/null @@ -1,93 +0,0 @@ -from mpi4py import MPI -import datetime -import os, sys -#import timeit - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * - -def conversion(x1,x2): - a=[x1,x2] - for x in a: - m,s = divmod(x,60) - h,m = divmod(m,60) - if x==x1: - startime= str("%02d:%02d:%02d" % (h, m, s)) - if x==x2: - endtime =str("%02d:%02d:%02d" % (h, m, s)) - return startime,endtime - - - -def loop(startime,endtime,rank): - desc = "HF_EXAMPLE"+str(rank) - path= "/home/alex/Documents/hysell_data/pdata/sp1_f0" - figpath= "/home/alex/Pictures/pdata_plot"+str(rank) - - filename = "hf_test"+str(rank)+".xml" - - controllerObj = Project() - - controllerObj.setup(id = '191', name='test01'+str(rank), description=desc) - - readUnitConfObj = controllerObj.addReadUnit(datatype='SpectraReader', - path=path, - startDate='2015/09/26', - endDate='2015/09/26', - startTime=startime, - endTime=endtime, - online=0, - #set=1426485881, - delay=10, - walk=1 - #timezone=-5*3600 - ) - - #opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', inputId=readUnitConfObj.getId()) - - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') - opObj11.addParameter(name='id', value='1000', format='int') - opObj11.addParameter(name='wintitle', value='HF_Jicamarca_Spc', format='str') - #opObj11.addParameter(name='channelList', value='0', format='intlist') - opObj11.addParameter(name='zmin', value='-120', format='float') - opObj11.addParameter(name='zmax', value='-70', format='float') - opObj11.addParameter(name='save', value='1', format='int') - opObj11.addParameter(name='figpath', value=figpath, format='str') - - - print "Escribiendo el archivo XML" - controllerObj.writeXml(filename) - print "Leyendo el archivo XML" - controllerObj.readXml(filename) - - controllerObj.createObjects() - controllerObj.connectObjects() - - #timeit.timeit('controllerObj.run()', number=2) - - controllerObj.run() - - - -def parallel(): - - comm = MPI.COMM_WORLD - rank = comm.Get_rank() - size = comm.Get_size() - totalStartTime = time.time() - print "Hello world from process %d/%d"%(rank,size) - # First just for one day :D! - num_hours = 4/size - time1,time2 = rank*num_hours*3600,(rank+1)*num_hours*3600-60 - #print time1,time2 - startime,endtime =conversion(time1,time2) - print startime,endtime - loop(startime,endtime,rank) - print "Total time %f seconds" %(time.time() -totalStartTime) - -if __name__=='__main__': - parallel() \ No newline at end of file diff --git a/schainpy/scripts/sousy.py b/schainpy/scripts/sousy.py deleted file mode 100644 index a0d1ec9..0000000 --- a/schainpy/scripts/sousy.py +++ /dev/null @@ -1,105 +0,0 @@ -#!python -''' -Created on Jul 7, 2015 - -@author: Miguel Urco -''' -import os, sys - -path = os.path.dirname(os.getcwd()) -path = os.path.dirname(path) -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "Sousy_test" -filename = "sousy_processing.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='Test_sousy', description=desc) - -#path = '/media/data/data/vientos/57.2063km/echoes/NCO_Woodman' -#path2= '/media/' -#path2='/media/New Volume/LowTroposphere' -#path1='/media/New Volume/LT_shortpulse' -#path = path1 + ',' + path2 -path='G:\\LowTroposphere' - -path = '/media/signalchain/FVillanuevaR/LowTroposphere' -wr_path = '/media/signalchain/datos/sousy' -figures_path = '/home/signalchain/Pictures/sousy' - -readUnitConfObj = controllerObj.addReadUnit(datatype='Voltage', - path=path, - startDate='2014/07/08', - endDate='2014/07/08', - startTime='10:00:00', - endTime='17:59:59', - delay=0, - set=0, - online=0, - walk=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') -######################################################### -################ SOUSY################################### -######################################################### -# -procUnitConfObjSousy = controllerObj.addProcUnit(datatype='Voltage', inputId=readUnitConfObj.getId()) -# -# codigo64='1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0,'+\ -# '1,1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,0,1,0,0,0,1,1,1,0,1' -opObj11 = procUnitConfObjSousy.addOperation(name='setRadarFrequency') -opObj11.addParameter(name='frequency', value='53.5e6', format='float') - - - -opObj11 = procUnitConfObjSousy.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='2', format='int') - -codigo='1,-1' -opObj11 = procUnitConfObjSousy.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=codigo, format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -opObj11.addParameter(name='nBaud', value='1', format='int') - -opObj11 = procUnitConfObjSousy.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='2048', format='int') - -procUnitConfObjSousySpectra = controllerObj.addProcUnit(datatype='Spectra', inputId=procUnitConfObjSousy.getId()) -procUnitConfObjSousySpectra.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObjSousySpectra.addParameter(name='nProfiles', value='64', format='int') - -opObj13 = procUnitConfObjSousySpectra.addOperation(name='removeDC') -opObj13.addParameter(name='mode', value='2', format='int') - -opObj11 = procUnitConfObjSousySpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='1', format='float') -# -# opObj11 = procUnitConfObjSousySpectra.addOperation(name='RTIPlot', optype='other') -# opObj11.addParameter(name='id', value='101', format='int') -# opObj11.addParameter(name='wintitle', value='Sousy_RTIPlot', format='str') -# opObj11.addParameter(name='zmin', value='30', format='int') -# opObj11.addParameter(name='zmax', value='100', format='int') -# opObj11.addParameter(name='ymin', value='0', format='int') -# opObj11.addParameter(name='ymax', value='10', format='int') -# opObj11.addParameter(name='xmin', value='10', format='float') -# opObj11.addParameter(name='xmax', value='18', format='float') -# opObj11.addParameter(name='showprofile', value='0', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -# #opObj11.addParameter(name='figfile', value='rti0_sousy.png', format='str') -# opObj11.addParameter(name='figpath', value=figures_path, format='str') - -opObj11 = procUnitConfObjSousySpectra.addOperation(name='SpectraWriter', optype='other') -opObj11.addParameter(name='path', value=wr_path) -opObj11.addParameter(name='blocksPerFile', value='100', format='int') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() -controllerObj.run() \ No newline at end of file diff --git a/schainpy/scripts/testDigitalRF.py b/schainpy/scripts/testDigitalRF.py new file mode 100644 index 0000000..9188ac9 --- /dev/null +++ b/schainpy/scripts/testDigitalRF.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +''' +Created on Jul 7, 2014 + +@author: roj-idl71 +''' +import os +import sys + +from schainpy.controller import Project + + +def main(): + + desc = "Testing USRP data reader" + filename = "schain.xml" + figpath = "./" + remotefolder = "/home/wmaster/graficos" + + # this controller object save all user configuration and then execute each module + # with their parameters. + controllerObj = Project() + + controllerObj.setup(id='191', name='test01', description=desc) + + # Creating a reader object with its parameters + # schainpy.model.io.jroIO_usrp.USRPReader.setup() + readUnitConfObj = controllerObj.addReadUnit(datatype='DigitalRF', + path='/home/nanosat/data', + startDate='2000/07/03', + endDate='2017/07/03', + startTime='00:00:00', + endTime='23:59:59', + online=0) + + # procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', + # inputId=readUnitConfObj.getId()) + +# opObj10 = procUnitConfObj0.addOperation(name='selectHeights') +# opObj10.addParameter(name='minHei', value='0', format='float') +# opObj10.addParameter(name='maxHei', value='8', format='float') + +# opObj10 = procUnitConfObj0.addOperation(name='setH0') +# opObj10.addParameter(name='h0', value='5.4', format='float') + +# opObj10 = procUnitConfObj0.addOperation(name='Decoder', optype='external') +# opObj10.addParameter(name='code', value='1,-1', format='intlist') +# opObj10.addParameter(name='nCode', value='2', format='float') +# opObj10.addParameter(name='nBaud', value='1', format='float') + + # opObj10 = procUnitConfObj0.addOperation(name='CohInt', optype='external') + # opObj10.addParameter(name='n', value='128', format='float') + + # opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='external') + # opObj11.addParameter(name='id', value='121', format='int') + # opObj11.addParameter(name='wintitle', value='Scope', format='str') + + # procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', + # inputId=procUnitConfObj0.getId()) + + # #Creating a processing object with its parameters + # #schainpy.model.proc.jroproc_spectra.SpectraProc.run() + # #If you need to add more parameters can use the "addParameter method" + # procUnitConfObj1.addParameter(name='nFFTPoints', value='8', format='int') + # procUnitConfObj1.addParameter(name='pairsList', value='(0,1)', format='pairslist') + +# opObj10 = procUnitConfObj1.addOperation(name='IncohInt', optype='external') +# opObj10.addParameter(name='n', value='2', format='float') +# + # Using internal methods + # schainpy.model.proc.jroproc_spectra.SpectraProc.selectChannels() +# opObj10 = procUnitConfObj1.addOperation(name='selectChannels') +# opObj10.addParameter(name='channelList', value='0,1', format='intlist') + + # Using internal methods + # schainpy.model.proc.jroproc_spectra.SpectraProc.selectHeights() +# opObj10 = procUnitConfObj1.addOperation(name='selectHeights') +# opObj10.addParameter(name='minHei', value='90', format='float') +# opObj10.addParameter(name='maxHei', value='180', format='float') + + # Using external methods (new modules) +# #schainpy.model.proc.jroproc_spectra.IncohInt.setup() +# opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') +# opObj12.addParameter(name='n', value='1', format='int') + + # Using external methods (new modules) + # schainpy.model.graphics.jroplot_spectra.SpectraPlot.setup() + # opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external') + # opObj11.addParameter(name='id', value='11', format='int') + # opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str') +# opObj11.addParameter(name='zmin', value='0', format='int') +# opObj11.addParameter(name='zmax', value='90', format='int') +# opObj11.addParameter(name='save', value='1', format='int') +# opObj11.addParameter(name='xmin', value='-20', format='float') +# opObj11.addParameter(name='xmax', value='20', format='float') + + # Using external methods (new modules) + # schainpy.model.graphics.jroplot_spectra.RTIPlot.setup() +# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') +# opObj11.addParameter(name='id', value='30', format='int') +# opObj11.addParameter(name='wintitle', value='RTI', format='str') +# # opObj11.addParameter(name='zmin', value='0', format='int') +# # opObj11.addParameter(name='zmax', value='90', format='int') +# opObj11.addParameter(name='showprofile', value='1', format='int') +# opObj11.addParameter(name='timerange', value=str(2*60*60), format='int') +# opObj11.addParameter(name='xmin', value='19.5', format='float') +# opObj11.addParameter(name='xmax', value='20', format='float') + + # opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') + # opObj11.addParameter(name='id', value='3', format='int') + # opObj11.addParameter(name='wintitle', value='CrossSpectraPlot', format='str') +# opObj11.addParameter(name='zmin', value='30', format='int') +# opObj11.addParameter(name='zmax', value='120', format='int') +# opObj11.addParameter(name='pairsList', value='(0,1)', format='pairslist') + + controllerObj.start() + + +if __name__ == '__main__': + main() diff --git a/schainpy/scripts/testDigitalRFWriter.py b/schainpy/scripts/testDigitalRFWriter.py new file mode 100644 index 0000000..ee8ed56 --- /dev/null +++ b/schainpy/scripts/testDigitalRFWriter.py @@ -0,0 +1,91 @@ +import os +import sys +import sys + +from schainpy.controller import Project + +controllerObj = Project() +desc = '' +controllerObj.setup(id='191', name='test01', description=desc) + +readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', + path='/home/nanosat/data/jasmet', + startDate='2010/10/28', + endDate='2017/10/28', + startTime='00:00:00', + endTime='23:59:59', + walk=1, + online=0) + +procUnitConfObj0 = controllerObj.addProcUnit( + datatype='VoltageProc', inputId=readUnitConfObj.getId()) + +# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='external') +# opObj11.addParameter(name='id', value='121', format='int') +# opObj11.addParameter(name='wintitle', value='Scope', format='str') +# opObj10 = procUnitConfObj0.addOperation(name='DigitalRFWriter', optype='other') +# opObj10.addParameter( +# name='path', value='/home/nanosat/data/digitalrf', format='str') +# opObj10.addParameter( +# name='fileCadence', value='1000000', format='int') +# opObj10.addParameter(name='minHei', value='0', format='float') +# opObj10.addParameter(name='maxHei', value='8', format='float') + +# opObj10 = procUnitConfObj0.addOperation(name='filterByHeights') +# opObj10.addParameter(name='window', value='2', format='float') + +# opObj10 = procUnitConfObj0.addOperation(name='Decoder', optype='external') +# opObj10.addParameter(name='nCode', value='2', format='float') +# opObj10.addParameter(name='nBaud', value='1', format='float') + +# opObj10 = procUnitConfObj0.addOperation(name='CohInt', optype='external') +# opObj10.addParameter(name='n', value='1296', format='float') + +# Creating a processing object with its parameters +# schainpy.model.proc.jroproc_spectra.SpectraProc.run() +# If you need to add more parameters can use the "addParameter method" +# schainpy.model.proc.jroproc_spectra.SpectraProc.run() +# If you need to add more parameters can use the "addParameter method" +# procUnitConfObj1.addParameter(name='nFFTPoints', value='128', format='int') + +# Using internal methods +# schainpy.model.proc.jroproc_spectra.SpectraProc.selectChannels() +# Using internal methods +# schainpy.model.proc.jroproc_spectra.SpectraProc.selectChannels() + +# Using internal methods +# schainpy.model.proc.jroproc_spectra.SpectraProc.selectHeights() +# Using internal methods +# schainpy.model.proc.jroproc_spectra.SpectraProc.selectHeights() +# opObj10 = procUnitConfObj1.addOperation(name='selectHeights') + +# Using external methods (new modules) + +# Using external methods (new modules) +# #schainpy.model.proc.jroproc_spectra.IncohInt.setup() + +# Using external methods (new modules) +# schainpy.model.graphics.jroplot_spectra.SpectraPlot.setup() +# Using external methods (new modules) +# schainpy.model.graphics.jroplot_spectra.SpectraPlot.setup() +# opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external') +# opObj11.addParameter(name='id', value='11', format='int') +# opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str') +# opObj11.addParameter(name='zmin', value='-60', format='int') + +# opObj11.addParameter(name='save', value='1', format='int') + +# #Using external methods (new modules) +# #schainpy.model.graphics.jroplot_spectra.RTIPlot.setup() +# opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') +# opObj11.addParameter(name='id', value='30', format='int') +# opObj11.addParameter(name='wintitle', value='RTI', format='str') +# opObj11.addParameter(name='zmin', value='-60', format='int') +# opObj11.addParameter(name='zmax', value='-10', format='int') +# opObj11.addParameter(name='showprofile', value='1', format='int') +# opObj11.addParameter(name='xmax', value='23.9', format='float') +# opObj11.addParameter(name='xmin', value='14', format='float') + +# opObj11.addParameter(name='save', value='1', format='int') + +controllerObj.start() diff --git a/schainpy/scripts/testPlotter.py b/schainpy/scripts/testPlotter.py deleted file mode 100644 index 57ca1fe..0000000 --- a/schainpy/scripts/testPlotter.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 7, 2014 - -@author: roj-idl71 -''' -import os, sys -from Queue import Queue -from time import sleep - -from schainpy.controller_api import ControllerThread -from schainpy.model.graphics.jroplotter import PlotManager - -def main(): - desc = "Segundo Test" - filename = "schain.xml" - - controllerObj = ControllerThread() - - controllerObj.setup(id = '191', name='test01', description=desc) - - readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path='../data/pdata/', - startDate='2010/12/18', - endDate='2015/12/22', - startTime='00:00:00', - endTime='23:59:59', - online=0, - walk=0, - expLabel='') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - - opObj10 = procUnitConfObj1.addOperation(name='selectChannels') - opObj10.addParameter(name='channelList', value='0,1', format='intlist') - - opObj10 = procUnitConfObj1.addOperation(name='selectHeights') - opObj10.addParameter(name='minHei', value='90', format='float') - opObj10.addParameter(name='maxHei', value='180', format='float') - - opObj10 = procUnitConfObj1.addOperation(name='removeDC') - - opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') - opObj12.addParameter(name='n', value='1', format='int') - - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') - opObj11.addParameter(name='id', value='1', format='int') - opObj11.addParameter(name='wintitle', value='SpectraPlot0', format='str') - opObj11.addParameter(name='showprofile', value='1', format='int') - opObj11.addParameter(name='save', value='0', format='int') - opObj11.addParameter(name='figpath', value='/Users/miguel/Data/JULIA/pdata/graphs') - - opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') - opObj11.addParameter(name='id', value='10', format='int') - opObj11.addParameter(name='wintitle', value='RTI', format='str') - opObj11.addParameter(name='xmin', value='21', format='float') - opObj11.addParameter(name='xmax', value='22', format='float') - opObj11.addParameter(name='zmin', value='12', format='int') - opObj11.addParameter(name='zmax', value='32', format='int') - opObj11.addParameter(name='showprofile', value='1', format='int') - opObj11.addParameter(name='timerange', value=str(2*60*60), format='int') - - ######################################## - #Configure use of external plotter before start - plotterObj = controllerObj.useExternalPlotter() - ######################################## - - controllerObj.start() - - plotterObj.start() - -if __name__ == '__main__': - import time - start_time = time.time() - main() - print("--- %s seconds ---" % (time.time() - start_time)) diff --git a/schainpy/scripts/testProcData.py b/schainpy/scripts/testProcData.py deleted file mode 100644 index c39be23..0000000 --- a/schainpy/scripts/testProcData.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 7, 2014 - -@author: roj-idl71 -''' -import os, sys - -from schainpy.controller import Project - -def main(): - desc = "Segundo Test" - filename = "schain.xml" - - controllerObj = Project() - - controllerObj.setup(id = '191', name='test01', description=desc) - - readUnitConfObj = controllerObj.addReadUnit(datatype='Spectra', - path='../data/pdata/', - startDate='2010/12/18', - endDate='2015/12/22', - startTime='00:00:00', - endTime='23:59:59', - online=0, - walk=0, - expLabel='') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', inputId=readUnitConfObj.getId()) - - opObj10 = procUnitConfObj1.addOperation(name='selectChannels') - opObj10.addParameter(name='channelList', value='0,1', format='intlist') - - opObj10 = procUnitConfObj1.addOperation(name='selectHeights') - opObj10.addParameter(name='minHei', value='90', format='float') - opObj10.addParameter(name='maxHei', value='180', format='float') - - opObj10 = procUnitConfObj1.addOperation(name='removeDC') - - opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') - opObj12.addParameter(name='n', value='1', format='int') - - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='other') - opObj11.addParameter(name='id', value='1', format='int') - opObj11.addParameter(name='wintitle', value='SpectraPlot0', format='str') - opObj11.addParameter(name='showprofile', value='1', format='int') - opObj11.addParameter(name='save', value='0', format='int') - opObj11.addParameter(name='figpath', value='/Users/miguel/Data/JULIA/pdata/graphs') - - opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') - opObj11.addParameter(name='id', value='10', format='int') - opObj11.addParameter(name='wintitle', value='RTI', format='str') -# opObj11.addParameter(name='xmin', value='21', format='float') -# opObj11.addParameter(name='xmax', value='22', format='float') - opObj11.addParameter(name='zmin', value='12', format='int') - opObj11.addParameter(name='zmax', value='32', format='int') - opObj11.addParameter(name='showprofile', value='1', format='int') - opObj11.addParameter(name='timerange', value=str(2*60*60), format='int') - - controllerObj.start() - -if __name__ == '__main__': - import time - start_time = time.time() - main() - print("--- %s seconds ---" % (time.time() - start_time)) diff --git a/schainpy/scripts/testRawData.py b/schainpy/scripts/testRawData.py deleted file mode 100644 index 2359277..0000000 --- a/schainpy/scripts/testRawData.py +++ /dev/null @@ -1,93 +0,0 @@ -import os, sys - -from schainpy.controller import Project - -if __name__ == '__main__': - - desc = "Segundo Test" - filename = "schain.xml" - - controllerObj = Project() - - controllerObj.setup(id = '191', name='test01', description=desc) - - readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path='/Volumes/SOUSY/', - startDate='2014/10/28', - endDate='2014/10/28', - startTime='15:40:00', - endTime='16:20:00', - online=0, - walk=1) - - opObj00 = readUnitConfObj.addOperation(name='printNumberOfBlock') - - procUnitConfObj0 = controllerObj.addProcUnit(datatype='VoltageProc', - inputId=readUnitConfObj.getId()) - - opObj10 = procUnitConfObj0.addOperation(name='selectHeights') - opObj10.addParameter(name='minHei', value='0', format='float') - opObj10.addParameter(name='maxHei', value='8', format='float') - - opObj10 = procUnitConfObj0.addOperation(name='filterByHeights') - opObj10.addParameter(name='window', value='2', format='float') - - opObj10 = procUnitConfObj0.addOperation(name='Decoder', optype='external') - opObj10.addParameter(name='code', value='1,-1', format='intlist') - opObj10.addParameter(name='nCode', value='2', format='float') - opObj10.addParameter(name='nBaud', value='1', format='float') - - - opObj10 = procUnitConfObj0.addOperation(name='CohInt', optype='external') - opObj10.addParameter(name='n', value='1296', format='float') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='SpectraProc', - inputId=procUnitConfObj0.getId()) - - #Creating a processing object with its parameters - #schainpy.model.proc.jroproc_spectra.SpectraProc.run() - #If you need to add more parameters can use the "addParameter method" - procUnitConfObj1.addParameter(name='nFFTPoints', value='128', format='int') - - opObj10 = procUnitConfObj1.addOperation(name='IncohInt', optype='external') - opObj10.addParameter(name='n', value='2', format='float') - - #Using internal methods - #schainpy.model.proc.jroproc_spectra.SpectraProc.selectChannels() -# opObj10 = procUnitConfObj1.addOperation(name='selectChannels') -# opObj10.addParameter(name='channelList', value='0,1', format='intlist') - - #Using internal methods - #schainpy.model.proc.jroproc_spectra.SpectraProc.selectHeights() -# opObj10 = procUnitConfObj1.addOperation(name='selectHeights') -# opObj10.addParameter(name='minHei', value='90', format='float') -# opObj10.addParameter(name='maxHei', value='180', format='float') - - #Using external methods (new modules) -# #schainpy.model.proc.jroproc_spectra.IncohInt.setup() -# opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -# opObj12.addParameter(name='n', value='1', format='int') - - #Using external methods (new modules) - #schainpy.model.graphics.jroplot_spectra.SpectraPlot.setup() - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external') - opObj11.addParameter(name='id', value='11', format='int') - opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str') - opObj11.addParameter(name='zmin', value='-60', format='int') - opObj11.addParameter(name='zmax', value='10', format='int') - opObj11.addParameter(name='save', value='1', format='int') - - #Using external methods (new modules) - #schainpy.model.graphics.jroplot_spectra.RTIPlot.setup() - opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') - opObj11.addParameter(name='id', value='30', format='int') - opObj11.addParameter(name='wintitle', value='RTI', format='str') - opObj11.addParameter(name='zmin', value='-60', format='int') - opObj11.addParameter(name='zmax', value='-10', format='int') - opObj11.addParameter(name='showprofile', value='1', format='int') -# opObj11.addParameter(name='timerange', value=str(5*60*60*60), format='int') - opObj11.addParameter(name='xmin', value='14', format='float') - opObj11.addParameter(name='xmax', value='23.9', format='float') - opObj11.addParameter(name='save', value='1', format='int') - - controllerObj.start() diff --git a/schainpy/scripts/testUSRPData.py b/schainpy/scripts/testUSRPData.py deleted file mode 100644 index 2601444..0000000 --- a/schainpy/scripts/testUSRPData.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 7, 2014 - -@author: roj-idl71 -''' -import os, sys - -from schainpy.controller import Project - -def main(): - - desc = "Testing USRP data reader" - filename = "schain.xml" - figpath = "./" - remotefolder = "/home/wmaster/graficos" - - #this controller object save all user configuration and then execute each module - #with their parameters. - controllerObj = Project() - - controllerObj.setup(id = '191', name='test01', description=desc) - - #Creating a reader object with its parameters - #schainpy.model.io.jroIO_usrp.USRPReader.setup() - readUnitConfObj = controllerObj.addReadUnit(datatype='USRP', - path='../data/haystack/', - startDate='2000/07/03', - endDate='2015/07/03', - startTime='00:00:00', - endTime='23:59:59', - online=0, - ippKm = 60) - - procUnitConfObj0 = controllerObj.addProcUnit(datatype='Voltage', - inputId=readUnitConfObj.getId()) - -# opObj10 = procUnitConfObj0.addOperation(name='selectHeights') -# opObj10.addParameter(name='minHei', value='0', format='float') -# opObj10.addParameter(name='maxHei', value='8', format='float') - -# opObj10 = procUnitConfObj0.addOperation(name='setH0') -# opObj10.addParameter(name='h0', value='5.4', format='float') - -# opObj10 = procUnitConfObj0.addOperation(name='Decoder', optype='external') -# opObj10.addParameter(name='code', value='1,-1', format='intlist') -# opObj10.addParameter(name='nCode', value='2', format='float') -# opObj10.addParameter(name='nBaud', value='1', format='float') - - opObj10 = procUnitConfObj0.addOperation(name='CohInt', optype='external') - opObj10.addParameter(name='n', value='1', format='float') - -# opObj11 = procUnitConfObj0.addOperation(name='Scope', optype='external') -# opObj11.addParameter(name='id', value='121', format='int') -# opObj11.addParameter(name='wintitle', value='Scope', format='str') - - procUnitConfObj1 = controllerObj.addProcUnit(datatype='Spectra', - inputId=procUnitConfObj0.getId()) - - #Creating a processing object with its parameters - #schainpy.model.proc.jroproc_spectra.SpectraProc.run() - #If you need to add more parameters can use the "addParameter method" - procUnitConfObj1.addParameter(name='nFFTPoints', value='8', format='int') - procUnitConfObj1.addParameter(name='pairsList', value='(0,1)', format='pairslist') - -# opObj10 = procUnitConfObj1.addOperation(name='IncohInt', optype='external') -# opObj10.addParameter(name='n', value='2', format='float') -# - #Using internal methods - #schainpy.model.proc.jroproc_spectra.SpectraProc.selectChannels() -# opObj10 = procUnitConfObj1.addOperation(name='selectChannels') -# opObj10.addParameter(name='channelList', value='0,1', format='intlist') - - #Using internal methods - #schainpy.model.proc.jroproc_spectra.SpectraProc.selectHeights() -# opObj10 = procUnitConfObj1.addOperation(name='selectHeights') -# opObj10.addParameter(name='minHei', value='90', format='float') -# opObj10.addParameter(name='maxHei', value='180', format='float') - - #Using external methods (new modules) -# #schainpy.model.proc.jroproc_spectra.IncohInt.setup() -# opObj12 = procUnitConfObj1.addOperation(name='IncohInt', optype='other') -# opObj12.addParameter(name='n', value='1', format='int') - - #Using external methods (new modules) - #schainpy.model.graphics.jroplot_spectra.SpectraPlot.setup() - opObj11 = procUnitConfObj1.addOperation(name='SpectraPlot', optype='external') - opObj11.addParameter(name='id', value='11', format='int') - opObj11.addParameter(name='wintitle', value='SpectraPlot', format='str') -# opObj11.addParameter(name='zmin', value='0', format='int') -# opObj11.addParameter(name='zmax', value='90', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -# opObj11.addParameter(name='xmin', value='-20', format='float') -# opObj11.addParameter(name='xmax', value='20', format='float') - - #Using external methods (new modules) - #schainpy.model.graphics.jroplot_spectra.RTIPlot.setup() - opObj11 = procUnitConfObj1.addOperation(name='RTIPlot', optype='other') - opObj11.addParameter(name='id', value='30', format='int') - opObj11.addParameter(name='wintitle', value='RTI', format='str') -# opObj11.addParameter(name='zmin', value='0', format='int') -# opObj11.addParameter(name='zmax', value='90', format='int') - opObj11.addParameter(name='showprofile', value='1', format='int') - opObj11.addParameter(name='timerange', value=str(2*60*60), format='int') -# opObj11.addParameter(name='xmin', value='19.5', format='float') -# opObj11.addParameter(name='xmax', value='20', format='float') - - opObj11 = procUnitConfObj1.addOperation(name='CrossSpectraPlot', optype='other') - opObj11.addParameter(name='id', value='3', format='int') - opObj11.addParameter(name='wintitle', value='CrossSpectraPlot', format='str') -# opObj11.addParameter(name='zmin', value='30', format='int') -# opObj11.addParameter(name='zmax', value='120', format='int') -# opObj11.addParameter(name='pairsList', value='(0,1)', format='pairslist') - - controllerObj.start() - -if __name__ == '__main__': - main() diff --git a/schainpy/scripts/test_eej_blocks.py b/schainpy/scripts/test_eej_blocks.py deleted file mode 100644 index d6385ad..0000000 --- a/schainpy/scripts/test_eej_blocks.py +++ /dev/null @@ -1,117 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * -dt1 = datetime.datetime.now() -desc = "MST-ISR-EEJ Experiment Test" -filename = "eej_blocks.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/media/signalchain/HD-PXU2/mst_isr_eej' -path = '/media/data/DATA/MST_ISR_EEJ' - -figpath = '/home/signalchain/Pictures/mst_isr_eej/eej' -figpath = '/media/DATA/mst_isr_eej/eej' - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/01', - endDate='2015/12/30', - startTime='00:00:00', - endTime='23:59:59', - online=1, - delay=10, - walk=1, - getblock=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') -# ################ EEJ #################################### -procUnitConfObjEEJ = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjEEJ.addOperation(name='ProfileSelector', optype='other') -opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -opObj11 = procUnitConfObjEEJ.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value='1,-1', format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -opObj11.addParameter(name='nBaud', value='1', format='int') -opObj11.addParameter(name='mode', value='3', format='int') -opObj11.addParameter(name='times', value='32', format='int') - -# opObj11 = procUnitConfObjEEJ.addOperation(name='CohInt', optype='other') -# opObj11.addParameter(name='n', value='2', format='int') - -procUnitConfObjEEJSpecta = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjEEJ.getId()) -procUnitConfObjEEJSpecta.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObjEEJSpecta.addParameter(name='nProfiles', value='64', format='int') - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='IncohInt', optype='other') -#opObj11.addParameter(name='timeInterval', value='10', format='float') -opObj11.addParameter(name='n', value='36', format='float') - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='100', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='40', format='int')# opObj11.addParameter(name='ftp', value='1', format='int') -# opObj11.addParameter(name='zmin', value='20', format='int') -# opObj11.addParameter(name='zmax', value='60', format='int')# opObj11.addParameter(name='ftp', value='1', format='int') -opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='101', format='int') -opObj11.addParameter(name='wintitle', value='EEJ', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -#opObj11.addParameter(name='zmin', value='20', format='int') -#opObj11.addParameter(name='zmax', value='40', format='int') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -# opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='22', format='int') -# opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# opObj11.addParameter(name='plot_pos', value='0', format='int') - -opObj11 = procUnitConfObjEEJSpecta.addOperation(name='SendByFTP', optype='other') -opObj11.addParameter(name='ext', value='*.png', format='str') -opObj11.addParameter(name='localfolder', value=figpath, format='str') -opObj11.addParameter(name='remotefolder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='period', value='5', format='int') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() -#print fib(5) - -dt2 = datetime.datetime.now() -print "=======================" -print dt2-dt1 -print "=======================" \ No newline at end of file diff --git a/schainpy/scripts/test_isr_blocks.py b/schainpy/scripts/test_isr_blocks.py deleted file mode 100644 index ae65206..0000000 --- a/schainpy/scripts/test_isr_blocks.py +++ /dev/null @@ -1,124 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -sys.path.append(path) - -from controller import * -dt1 = datetime.datetime.now() -desc = "MST-ISR-EEJ Experiment Test" -filename = "isr_blocks.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -path = '/media/signalchain/HD-PXU2/mst_isr_eej' -path = '/media/data/DATA/MST_ISR_EEJ' - -figpath = '/home/signalchain/Pictures/mst_isr_eej/isr' -figpath = '/media/DATA/mst_isr_eej/isr' - - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/01', - endDate='2015/12/30', - startTime='00:00:00', - endTime='23:59:59', - online=1, - delay=10, - walk=1, - getblock=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObjISR = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjISR.addOperation(name='ProfileSelector', optype='other') -# profileIndex = '20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99' -# opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') -opObj11.addParameter(name='profileRangeList', value='20,99', format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -# opObj11 = procUnitConfObjISR.addOperation(name='ProfileConcat', optype='other') -# opObj11.addParameter(name='m', value='5', format='int') - -opObj11 = procUnitConfObjISR.addOperation(name='Reshaper', optype='other') #Esta Operacion opera sobre bloques y reemplaza el ProfileConcat que opera sobre perfiles -opObj11.addParameter(name='shape', value='4,16,6750', format='intlist') # shape = (nchannels, nprofiles, nhieghts) - -opObj11 = procUnitConfObjISR.addOperation(name='filterByHeights') -opObj11.addParameter(name='window', value='20', format='int') -#opObj11.addParameter(name='axis', value='2', format='int') - -barker3x1 = '1,1,-1,-1,-1,1' -#barker3x5 = '1,1,1,1,1, 1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1' - -opObj11 = procUnitConfObjISR.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='code', value=barker3x1, format='floatlist') -opObj11.addParameter(name='nCode', value='2', format='int') -#opObj11.addParameter(name='nBaud', value='15', format='int') -opObj11.addParameter(name='nBaud', value='3', format='int') -opObj11.addParameter(name='mode', value='3', format='int') -opObj11.addParameter(name='times', value='8', format='int') -opObj11.addParameter(name='osamp', value='5', format='int') - - -procUnitConfObjISRSpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjISR.getId()) -procUnitConfObjISRSpectra.addParameter(name='nFFTPoints', value='16', format='int') -procUnitConfObjISRSpectra.addParameter(name='nProfiles', value='16', format='int') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='36', format='float') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='300', format='int') -opObj11.addParameter(name='zmin', value='23', format='int') -opObj11.addParameter(name='zmax', value='40', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='301', format='int') -opObj11.addParameter(name='xmin', value='00', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='zmin', value='23', format='int') -opObj11.addParameter(name='zmax', value='40', format='int') -opObj11.addParameter(name='wintitle', value='ISR', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='2', format='int') -opObj11.addParameter(name='exp_code', value='20', format='int') - - -opObj11 = procUnitConfObjISRSpectra.addOperation(name='SendByFTP', optype='other') -opObj11.addParameter(name='ext', value='*.png', format='str') -opObj11.addParameter(name='localfolder', value=figpath, format='str') -opObj11.addParameter(name='remotefolder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='period', value='5', format='int') - - - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() -#print fib(5) - -dt2 = datetime.datetime.now() -print "=======================" -print dt2-dt1 -print "=======================" diff --git a/schainpy/scripts/test_mst_blocks.py b/schainpy/scripts/test_mst_blocks.py deleted file mode 100644 index 8fe366b..0000000 --- a/schainpy/scripts/test_mst_blocks.py +++ /dev/null @@ -1,122 +0,0 @@ -import os, sys -#import timeit -import datetime - -path = os.path.split(os.getcwd())[0] -path = os.path.split(path)[0] - -sys.path.insert(0, path) - -from schainpy.controller import Project - -desc = "MST-ISR-EEJ Experiment Test" -filename = "mst_blocks.xml" - -controllerObj = Project() - -controllerObj.setup(id = '191', name='test01', description=desc) - -#path = '/home/operaciones/mst_data/MST_ISR_EEJ/' -path ='/home/operaciones/mst_data' -path = '/media/data/DATA/MST_ISR_EEJ' - -figpath = '/home/operaciones/Pictures/mst_isr_eej/mst' -figpath = '/media/DATA/mst_isr_eej/mst' - - -readUnitConfObj = controllerObj.addReadUnit(datatype='VoltageReader', - path=path, - startDate='2015/01/01', - endDate='2015/12/30', - startTime='00:00:00', - endTime='23:59:59', - online=1, - delay=10, - walk=1, - getblock=1) - -opObj11 = readUnitConfObj.addOperation(name='printNumberOfBlock') - -procUnitConfObjMST = controllerObj.addProcUnit(datatype='VoltageProc', inputId=readUnitConfObj.getId()) - -opObj11 = procUnitConfObjMST.addOperation(name='ProfileSelector', optype='other') -profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119' -#profileIndex = '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19' -opObj11.addParameter(name='profileList', value=profileIndex, format='intlist') -opObj11.addParameter(name='byblock', value='1', format='bool') - -opObj11 = procUnitConfObjMST.addOperation(name='Decoder', optype='other') -opObj11.addParameter(name='mode',value='3',format='int') -opObj11.addParameter(name='times',value='10',format='int') - -opObj11 = procUnitConfObjMST.addOperation(name='CohInt', optype='other') -opObj11.addParameter(name='n', value='20', format='int') -opObj11.addParameter(name='byblock', value='1', format='bool') - -procUnitConfObjMSTSpectra = controllerObj.addProcUnit(datatype='SpectraProc', inputId=procUnitConfObjMST.getId()) -procUnitConfObjMSTSpectra.addParameter(name='nFFTPoints', value='64', format='int') -procUnitConfObjMSTSpectra.addParameter(name='nProfiles', value='64', format='int') - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='IncohInt', optype='other') -opObj11.addParameter(name='n', value='2', format='float') - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SpectraPlot', optype='other') -opObj11.addParameter(name='id', value='401', format='int') -opObj11.addParameter(name='wintitle', value='MST', format='str') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='40', format='int') -# # opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='5', format='int') -# # opObj11.addParameter(name='ftp', value='1', format='int') -# # opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# # opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# # opObj11.addParameter(name='username', value='wmaster', format='str') -# # opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# # opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -# # opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# # opObj11.addParameter(name='plot_pos', value='0', format='int') -# # -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='RTIPlot', optype='other') -opObj11.addParameter(name='id', value='402', format='int') -opObj11.addParameter(name='wintitle', value='MST', format='str') -opObj11.addParameter(name='showprofile', value='0', format='int') -opObj11.addParameter(name='xmin', value='0', format='int') -opObj11.addParameter(name='xmax', value='24', format='int') -opObj11.addParameter(name='zmin', value='20', format='int') -opObj11.addParameter(name='zmax', value='40', format='int') -# # opObj11.addParameter(name='save', value='1', format='int') -opObj11.addParameter(name='figpath', value=figpath, format='str') -opObj11.addParameter(name='wr_period', value='2', format='int') -# # opObj11.addParameter(name='ftp', value='1', format='int') -# # opObj11.addParameter(name='server', value='jro-app.igp.gob.pe', format='str') -# # opObj11.addParameter(name='folder', value='/home/wmaster/graficos', format='str') -# # opObj11.addParameter(name='username', value='wmaster', format='str') -# # opObj11.addParameter(name='password', value='mst2010vhf', format='str') -# # opObj11.addParameter(name='ftp_wei', value='0', format='int') -opObj11.addParameter(name='exp_code', value='19', format='int') -# # opObj11.addParameter(name='sub_exp_code', value='0', format='int') -# # opObj11.addParameter(name='plot_pos', value='0', format='int') - -opObj11 = procUnitConfObjMSTSpectra.addOperation(name='SendByFTP', optype='other') -opObj11.addParameter(name='ext', value='*.png', format='str') -opObj11.addParameter(name='localfolder', value=figpath, format='str') -opObj11.addParameter(name='remotefolder', value='/home/wmaster/graficos', format='str') -opObj11.addParameter(name='server', value='10.10.120.125', format='str') -opObj11.addParameter(name='username', value='wmaster', format='str') -opObj11.addParameter(name='password', value='mst2010vhf', format='str') -opObj11.addParameter(name='period', value='2', format='int') - -print "Escribiendo el archivo XML" -controllerObj.writeXml(filename) -print "Leyendo el archivo XML" -controllerObj.readXml(filename) - -controllerObj.createObjects() -controllerObj.connectObjects() - -#timeit.timeit('controllerObj.run()', number=2) - -controllerObj.run() -#print fib(5) diff --git a/schainpy/scripts/zerorpc_client.py b/schainpy/scripts/zerorpc_client.py deleted file mode 100644 index e77f37a..0000000 --- a/schainpy/scripts/zerorpc_client.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 11, 2014 - -@author: roj-idl71 -''' -import time -from gevent import sleep - -import os, sys - -path = os.path.dirname(os.getcwd()) -path = os.path.join(path, 'source') -sys.path.insert(0, path) - -import zerorpc -from schainpy.model import * -from schainpy.model.serializer.data import serial2Obj, serial2Dict -# import schainpy.model.io.jroIO_usrp - -def createObjVolt(): - ''' - This function creates a processing object "VoltProc" with some operations. - such as: "CohInt", "Scope", etc - These class are found inside schainpy.model.proc and schainpy.model.graphics - ''' - procObj = VoltageProc() - - opObj = CohInt() - procObj.addOperation(opObj, 1) - - opObj = Scope() - procObj.addOperation(opObj, 2) - - return procObj - -def createObjSpec(): - ''' - This function creates a processing object "SpecProc" with some operation objects - such as: "IncohInt", "SpectraPlot", "RTIPlot", etc - These class are found inside schainpy.model.proc and schainpy.model.graphics - ''' - - procObj = SpectraProc() - - opObj = IncohInt() - procObj.addOperation(opObj, objId = 1) - - opObj = SpectraPlot() - procObj.addOperation(opObj, objId = 2) - - opObj = RTIPlot() - procObj.addOperation(opObj, objId = 3) - - opObj = SpectraPlot() - procObj.addOperation(opObj, objId = 4) - - opObj = RTIPlot() - procObj.addOperation(opObj, objId = 5) - - return procObj - -def processingSpec(procObj, dataInObj): - - procObj.setInput(dataInObj) - procObj.run(nFFTPoints = 16) - - procObj.call(opType = "external", - opId = 1, - n=1) - - procObj.call(opType = "external", - opId = 2, - id=191, -# zmin=-100, -# zmax=-40 - ) - - procObj.call(opType = "external", - opId = 3, - id=192, -# zmin=-100, -# zmax=-40, - timerange=10*60) - -def printSpeed(deltaTime, mySerial): - - #################### - size = len(mySerial)/1024. - vel = 1.0*size / deltaTime - - print "Index [", replayerObj.getProfileIndex(), "]: ", - print "Total time %5.2f ms, Data size %5.2f KB, Speed %5.2f MB/s" %(deltaTime, size, vel) - #################### - -if __name__ == '__main__': - - procObj = createObjSpec() - - replayerObj = zerorpc.Client() - replayerObj.connect("tcp://127.0.0.1:4242") - - serializer = replayerObj.getSerializer() - - ini = time.time() - mySerialMetadata = replayerObj.getSerialMetaData() - deltaTime = (time.time() - ini)*1024 - - printSpeed(deltaTime, mySerialMetadata) - - myMetaDict = serial2Dict(mySerialMetadata, - serializer = serializer) -# print myMetaDict - while True: - ini = time.time() - mySerialData = replayerObj.getSerialData() - deltaTime = (time.time() - ini)*1024 - - if not mySerialData: - print "No more data" - break - -# myDataDict = SERIALIZER.loads(mySerialData) -# print myDataDict -# continue - - printSpeed(deltaTime, mySerialData) - - dataInObj = serial2Obj(mySerialData, - metadataDict=myMetaDict, - serializer = serializer) - processingSpec(procObj, dataInObj) - sleep(1e-1) \ No newline at end of file diff --git a/schainpy/scripts/zerorpc_server.py b/schainpy/scripts/zerorpc_server.py deleted file mode 100644 index ccbdbf2..0000000 --- a/schainpy/scripts/zerorpc_server.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -''' -Created on Jul 11, 2014 - -@author: roj-idl71 -''' -# import sys -import datetime -import zerorpc - -import os, sys - -path = os.path.dirname(os.getcwd()) -path = os.path.join(path, 'source') -sys.path.insert(0, path) - -# from gevent import sleep - -from schainpy.model.io.jroIO_usrp_api import USRPReaderAPI -# from schainpy.serializer.DataTranslate import serial2Obj - -if __name__ == '__main__': - - replayerObj = USRPReaderAPI(serializer='msgpack') - - replayerObj.setup(path='../data/haystack/', - startDate=datetime.date(2000,1,1), - endDate=datetime.date(2016,1,1), - startTime=datetime.time(0,0,0), - endTime=datetime.time(23,59,59), - online=0, - nSamples=50, - buffer_size = 8, - channelList = [0]) - - replayerObj.start() - - print "\nInitializing 'zerorpc' server" - s = zerorpc.Server(replayerObj) - s.bind("tcp://0.0.0.0:4242") - s.run() - - print "End" \ No newline at end of file diff --git a/schainpy/utils/__init__.py b/schainpy/utils/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/schainpy/utils/__init__.py diff --git a/schainpy/utils/log.py b/schainpy/utils/log.py new file mode 100644 index 0000000..d06396e --- /dev/null +++ b/schainpy/utils/log.py @@ -0,0 +1,57 @@ +''' +SCHAINPY - LOG + Simple helper for log standarization + Usage: + from schainpy.utils import log + log.error('A kitten died beacuse of you') + log.warning('You are doing it wrong but what the heck, I'll allow it) + log.succes('YOU ROCK!') + To create your own logger inside your class do it like this: + from schainpy.utils import log + awesomeLogger = log.makelogger("never gonna", bg="red", fg="white") + awesomeLogger('give you up') + which will look like this: + [NEVER GONNA] - give you up + with color red as background and white as foreground. +''' + +import click + + +def warning(message, tag='Warning', nl=True): + if tag: + click.echo(click.style('[{}] {}'.format(tag, message), fg='yellow'), nl=nl) + else: + click.echo(click.style('{}'.format(message), fg='yellow'), nl=nl) + pass + + +def error(message, tag='Error', nl=True): + if tag: + click.echo(click.style('[{}] {}'.format(tag, message), fg='red'), nl=nl) + else: + click.echo(click.style('{}'.format(message), fg='red'), nl=nl) + pass + + +def success(message, tag='Success', nl=True): + if tag: + click.echo(click.style('[{}] {}'.format(tag, message), fg='green'), nl=nl) + else: + click.echo(click.style('{}'.format(message), fg='green'), nl=nl) + pass + + +def log(message, tag='Info', nl=True): + if tag: + click.echo('[{}] {}'.format(tag, message), nl=nl) + else: + click.echo('{}'.format(message), nl=nl) + pass + + +def makelogger(tag, bg='reset', fg='reset'): + def func(message): + click.echo(click.style('[{}] {}'.format( + tag.upper(), message), bg=bg, fg=fg)) + return func diff --git a/schainpy/utils/paramsFinder.py b/schainpy/utils/paramsFinder.py new file mode 100644 index 0000000..0efaf1c --- /dev/null +++ b/schainpy/utils/paramsFinder.py @@ -0,0 +1,80 @@ +import schainpy +from schainpy.model import Operation, ProcessingUnit +from pydoc import locate + +def clean_modules(module): + noEndsUnder = [x for x in module if not x.endswith('__')] + noStartUnder = [x for x in noEndsUnder if not x.startswith('__')] + noFullUpper = [x for x in noStartUnder if not x.isupper()] + return noFullUpper + +def check_module(possible, instance): + def check(x): + try: + instancia = locate('schainpy.model.{}'.format(x)) + return isinstance(instancia(), instance) + except Exception as e: + return False + clean = clean_modules(possible) + return [x for x in clean if check(x)] + + +def getProcs(): + module = dir(schainpy.model) + procs = check_module(module, ProcessingUnit) + try: + procs.remove('ProcessingUnit') + except Exception as e: + pass + return procs + +def getOperations(): + module = dir(schainpy.model) + noProcs = [x for x in module if not x.endswith('Proc')] + operations = check_module(noProcs, Operation) + try: + operations.remove('Operation') + except Exception as e: + pass + return operations + +def getArgs(op): + module = locate('schainpy.model.{}'.format(op)) + args = module().getAllowedArgs() + try: + args.remove('self') + except Exception as e: + pass + try: + args.remove('dataOut') + except Exception as e: + pass + return args + +def getAll(): + allModules = dir(schainpy.model) + modules = check_module(allModules, Operation) + modules.extend(check_module(allModules, ProcessingUnit)) + return modules + +def formatArgs(op): + args = getArgs(op) + + argsAsKey = ["\t'{}'".format(x) for x in args] + argsFormatted = ": 'string',\n".join(argsAsKey) + + print op + print "parameters = { \n" + argsFormatted + ": 'string',\n }" + print '\n' + + +if __name__ == "__main__": + getAll() + [formatArgs(x) for x in getAll()] + + ''' + parameters = { + 'id': , + 'wintitle': , + } + ''' \ No newline at end of file diff --git a/schainpy/utils/trash b/schainpy/utils/trash new file mode 100644 index 0000000..384299d --- /dev/null +++ b/schainpy/utils/trash @@ -0,0 +1 @@ +You should install "digital_rf_hdf5" module if you want to read USRP data diff --git a/setup.py b/setup.py index 7af7198..3701f0b 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,8 @@ Created on Jul 16, 2014 @author: Miguel Urco ''' + +import os from setuptools import setup, Extension from setuptools.command.build_ext import build_ext as _build_ext from schainpy import __version__ @@ -15,45 +17,54 @@ class build_ext(_build_ext): import numpy self.include_dirs.append(numpy.get_include()) - -setup(name="schainpy", - version=__version__, - description="Python tools to read, write and process Jicamarca data", - author="Miguel Urco", - author_email="miguel.urco@jro.igp.gob.pe", - url="http://jro.igp.gob.pe", - packages = {'schainpy', - 'schainpy.model', - 'schainpy.model.data', - 'schainpy.model.graphics', - 'schainpy.model.io', - 'schainpy.model.proc', - 'schainpy.model.serializer', - 'schainpy.model.utils', - 'schainpy.gui', - 'schainpy.gui.figures', - 'schainpy.gui.viewcontroller', - 'schainpy.gui.viewer', - 'schainpy.gui.viewer.windows'}, - ext_package='schainpy', - py_modules=[''], - package_data={'': ['schain.conf.template'], - 'schainpy.gui.figures': ['*.png','*.jpg'], - }, - include_package_data=False, - scripts =['schainpy/gui/schainGUI', - 'schainpy/scripts/schain'], - ext_modules=[ - Extension("cSchain", ["schainpy/model/proc/extensions.c"] - )], - cmdclass={'build_ext':build_ext}, - setup_requires=["numpy >= 1.11.2"], - install_requires=[ - "scipy >= 0.14.0", - "h5py >= 2.2.1", - "matplotlib >= 1.4.2", - "pyfits >= 3.4", - "paho-mqtt >= 1.2", - "zmq", - ], - ) \ No newline at end of file +setup(name = "schainpy", + version = __version__, + description = "Python tools to read, write and process Jicamarca data", + author = "Miguel Urco", + author_email = "miguel.urco@jro.igp.gob.pe", + url = "http://jro.igp.gob.pe", + packages = {'schainpy', + 'schainpy.model', + 'schainpy.model.data', + 'schainpy.model.graphics', + 'schainpy.model.io', + 'schainpy.model.proc', + 'schainpy.model.serializer', + 'schainpy.model.utils', + 'schainpy.utils', + 'schainpy.gui', + 'schainpy.gui.figures', + 'schainpy.gui.viewcontroller', + 'schainpy.gui.viewer', + 'schainpy.gui.viewer.windows', + 'schainpy.cli'}, + ext_package = 'schainpy', + package_data = {'': ['schain.conf.template'], + 'schainpy.gui.figures': ['*.png', '*.jpg'], + 'schainpy.files': ['*.oga'] + }, + include_package_data = False, + scripts = ['schainpy/gui/schainGUI'], + ext_modules = [ + Extension("cSchain", ["schainpy/model/proc/extensions.c"]) + ], + entry_points = { + 'console_scripts': [ + 'schain = schainpy.cli.cli:main', + ], + }, + cmdclass = {'build_ext': build_ext}, + setup_requires = ["numpy >= 1.11.2"], + install_requires = [ + "scipy >= 0.14.0", + "h5py >= 2.2.1", + "matplotlib >= 2.0.0", + "pyfits >= 3.4", + "paramiko >= 2.1.2", + "paho-mqtt >= 1.2", + "zmq", + "fuzzywuzzy", + "click", + "python-Levenshtein" + ], +)