diff --git a/experiment_project.py b/experiment_project.py
new file mode 100644
index 0000000..5bb268a
--- /dev/null
+++ b/experiment_project.py
@@ -0,0 +1,34 @@
+from schainpy.controller import Project
+
+desc = "A schain project"
+
+controller = Project()
+controller.setup(id='191', name="project", description=desc)
+
+readUnitConf = controller.addReadUnit(datatype='VoltageReader',
+ path="/home/nanosat/schain",
+ startDate="1970/01/01",
+ endDate="2017/12/31",
+ startTime="00:00:00",
+ endTime="23:59:59",
+ online=0,
+ verbose=1,
+ walk=1,
+ )
+
+procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
+
+opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
+opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
+
+opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
+opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', 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='figpath', value="/home/nanosat/schain/figs", format='str')
+opObj11.addParameter(name='wr_period', value='5', format='int')
+opObj11.addParameter(name='exp_code', value='22', format='int')
+
+
+controller.start()
diff --git a/schain.xml b/schain.xml
new file mode 100644
index 0000000..b67ac71
--- /dev/null
+++ b/schain.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/schaincli/README.md b/schaincli/README.md
new file mode 100644
index 0000000..ced14bb
--- /dev/null
+++ b/schaincli/README.md
@@ -0,0 +1,9 @@
+# schaing
+
+Command Line Interface for SIGNAL CHAIN - jro
+
+# Usage
+
+To use it:
+
+ $ schain-cli --help
diff --git a/schaincli/__init__.py b/schaincli/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/schaincli/__init__.py
diff --git a/schaincli/asdasd.py b/schaincli/asdasd.py
new file mode 100644
index 0000000..ca5629d
--- /dev/null
+++ b/schaincli/asdasd.py
@@ -0,0 +1,34 @@
+from schainpy.controller import Project
+
+desc = "asdasddsad"
+
+controller = Project()
+controller.setup(id='191', name="asdasd", description=desc)
+
+readUnitConf = controller.addReadUnit(datatype='VoltageReader',
+ path="/home/nanosat/schain/schain-cli",
+ startDate="1970/01/01",
+ endDate="2017/12/31",
+ startTime="00:00:00",
+ endTime="23:59:59",
+ online=0,
+ verbose=1,
+ walk=1,
+ )
+
+procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
+
+opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
+opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
+
+opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
+opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', 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='figpath', value="/home/nanosat/schain/schain-cli/figs", format='str')
+opObj11.addParameter(name='wr_period', value='5', format='int')
+opObj11.addParameter(name='exp_code', value='22', format='int')
+
+
+controller.start()
diff --git a/schaincli/cli.py b/schaincli/cli.py
new file mode 100644
index 0000000..fdf7531
--- /dev/null
+++ b/schaincli/cli.py
@@ -0,0 +1,188 @@
+import click
+import schainpy
+import subprocess
+import os
+import sys
+import glob
+save_stdout = sys.stdout
+sys.stdout = open('trash', 'w')
+from multiprocessing import cpu_count
+from schaincli import templates
+from schainpy import controller_api
+from schainpy.model import Operation, ProcessingUnit
+from schainpy.utils import log
+from importlib import import_module
+from pydoc import locate
+from fuzzywuzzy import process
+sys.stdout = save_stdout
+
+
+def print_version(ctx, param, value):
+ if not value or ctx.resilient_parsing:
+ return
+ click.echo(schainpy.__version__)
+ ctx.exit()
+
+
+cliLogger = log.makelogger('schain cli')
+PREFIX = 'experiment'
+
+
+@click.command()
+@click.option('--version', '-v', is_flag=True, callback=print_version, help='SChain version', type=str)
+@click.option('--xml', '-x', default=None, help='run an XML file', type=click.Path(exists=True, resolve_path=True))
+@click.argument('command', default='run', required=True)
+@click.argument('nextcommand', default=None, required=False, type=str)
+def main(command, nextcommand, version, xml):
+ """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY \n
+ Available commands.\n
+ --xml: runs a schain XML generated file\n
+ run: runs any python script starting 'experiment_'\n
+ generate: generates a template schain script\n
+ search: return avilable operations, procs or arguments of the give operation/proc\n"""
+ if xml is not None:
+ runFromXML(xml)
+ elif command == 'generate':
+ generate()
+ elif command == 'test':
+ test()
+ elif command == 'run':
+ runschain(nextcommand)
+ elif command == 'search':
+ search(nextcommand)
+ else:
+ log.error('Command {} is not defined'.format(command))
+
+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 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 search(nextcommand):
+ if nextcommand is None:
+ log.error('There is no Operation/ProcessingUnit to search')
+ elif nextcommand == 'procs':
+ module = dir(import_module('schainpy.model'))
+ procs = check_module(module, ProcessingUnit)
+ try:
+ procs.remove('ProcessingUnit')
+ except Exception as e:
+ pass
+ log.success('Current ProcessingUnits are:\n\033[1m{}\033[0m'.format('\n'.join(procs)))
+
+ elif nextcommand == 'operations':
+ module = dir(import_module('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
+ log.success('Current Operations are:\n\033[1m{}\033[0m'.format('\n'.join(operations)))
+ else:
+ try:
+ module = locate('schainpy.model.{}'.format(nextcommand))
+ args = module().getAllowedArgs()
+ log.warning('Use this feature with caution. It may not return all the allowed arguments')
+ try:
+ args.remove('self')
+ except Exception as e:
+ pass
+ try:
+ args.remove('dataOut')
+ except Exception as e:
+ pass
+ if len(args) == 0:
+ log.success('{} has no arguments'.format(nextcommand))
+ else:
+ log.success('Showing arguments of {} are:\n\033[1m{}\033[0m'.format(nextcommand, '\n'.join(args)))
+ except Exception as e:
+ log.error('Module {} does not exists'.format(nextcommand))
+ allModules = dir(import_module('schainpy.model'))
+ module = check_module(allModules, Operation)
+ module.extend(check_module(allModules, ProcessingUnit))
+ similar = process.extractOne(nextcommand, module)[0]
+ log.success('Searching {} instead'.format(similar))
+ search(similar)
+
+
+def runschain(nextcommand):
+ if nextcommand is None:
+ currentfiles = glob.glob('./{}_*.py'.format(PREFIX))
+ numberfiles = len(currentfiles)
+ if numberfiles > 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 = controller_api.ControllerThread()
+ if not controller.readXml(filename):
+ return
+
+ plotterObj = controller.useExternalPlotter()
+
+ controller.start()
+ plotterObj.start()
+
+ cliLogger("Finishing all processes")
+
+ controller.join(5)
+
+ cliLogger("End of script")
+ return
diff --git a/schaincli/templates.py b/schaincli/templates.py
new file mode 100644
index 0000000..ce08f4c
--- /dev/null
+++ b/schaincli/templates.py
@@ -0,0 +1,75 @@
+basic = '''from schainpy.controller import Project
+
+desc = "{desc}"
+
+controller = Project()
+controller.setup(id='191', name="{name}", description=desc)
+
+readUnitConf = controller.addReadUnit(datatype='VoltageReader',
+ path="{path}",
+ startDate="{startDate}",
+ endDate="{endDate}",
+ startTime="{startHour}",
+ endTime="{endHour}",
+ online=0,
+ verbose=1,
+ walk=1,
+ )
+
+procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
+
+opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
+opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
+
+opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
+opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', 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='figpath', value="{figpath}", format='str')
+opObj11.addParameter(name='wr_period', value='5', format='int')
+opObj11.addParameter(name='exp_code', value='22', format='int')
+
+
+controller.start()
+'''
+
+multiprocess = '''from schainpy.controller import Project, multiSchain
+
+desc = "{desc}"
+
+def fiber(cursor, skip, q, day):
+ controller = Project()
+ controller.setup(id='191', name="{name}", description=desc)
+
+ readUnitConf = controller.addReadUnit(datatype='SpectraReader',
+ path="{path}",
+ startDate=day,
+ endDate=day,
+ startTime="{startHour}",
+ endTime="{endHour}",
+ online=0,
+ queue=q,
+ cursor=cursor,
+ skip=skip,
+ verbose=1,
+ walk=1,
+ )
+
+ procUnitConf1 = controller.addProcUnit(datatype='Spectra', inputId=readUnitConf.getId())
+
+ procUnitConf2 = controller.addProcUnit(datatype='ParametersProc', inputId=readUnitConf.getId())
+ opObj11 = procUnitConf2.addOperation(name='SpectralMoments', optype='other')
+
+ opObj12 = procUnitConf2.addOperation(name='PublishData', optype='other')
+ opObj12.addParameter(name='zeromq', value=1, format='int')
+ opObj12.addParameter(name='verbose', value=0, format='bool')
+
+ controller.start()
+
+
+if __name__ == '__main__':
+ multiSchain(fiber, nProcess={nProcess}, startDate="{startDate}", endDate="{endDate}")
+
+
+'''
diff --git a/schaincli/tests/__init__.py b/schaincli/tests/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/schaincli/tests/__init__.py
@@ -0,0 +1 @@
+
diff --git a/schaincli/tests/test_cli.py b/schaincli/tests/test_cli.py
new file mode 100644
index 0000000..62e4f30
--- /dev/null
+++ b/schaincli/tests/test_cli.py
@@ -0,0 +1,29 @@
+import pytest
+from click.testing import CliRunner
+from schaincli 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 21bc640..c1d4836 100644
--- a/schainpy/controller.py
+++ b/schainpy/controller.py
@@ -61,7 +61,7 @@ def multiSchain(child, nProcess=cpu_count(), startDate=None, endDate=None, by_da
process.terminate()
process.join()
print traceback.print_tb(trace)
-
+
sys.excepthook = beforeExit
for process in processes:
@@ -1315,9 +1315,9 @@ class Project():
print "Process finished"
- def start(self):
+ def start(self, filename=None):
- self.writeXml()
+ self.writeXml(filename)
self.createObjects()
self.connectObjects()
self.run()
diff --git a/schainpy/controller_api.py b/schainpy/controller_api.py
index 2c9efd1..d8d87b9 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 = "plotter"
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/model/data/jrodata.py b/schainpy/model/data/jrodata.py
index c58715e..f7260e7 100644
--- a/schainpy/model/data/jrodata.py
+++ b/schainpy/model/data/jrodata.py
@@ -114,10 +114,6 @@ class GenericData(object):
flagNoData = True
- def __init__(self):
-
- raise NotImplementedError
-
def copy(self, inputObj=None):
if inputObj == None:
@@ -231,10 +227,6 @@ class JROData(GenericData):
profileIndex = None
- def __init__(self):
-
- raise NotImplementedError
-
def getNoise(self):
raise NotImplementedError
@@ -1216,7 +1208,10 @@ class Parameters(Spectra):
def getTimeInterval(self):
- return self.timeInterval1
+ if hasattr(self, 'timeInterval1'):
+ return self.timeInterval1
+ else:
+ return self.paramInterval
def getNoise(self):
diff --git a/schainpy/model/graphics/jroplot_data.py b/schainpy/model/graphics/jroplot_data.py
index b01484e..01f20ce 100644
--- a/schainpy/model/graphics/jroplot_data.py
+++ b/schainpy/model/graphics/jroplot_data.py
@@ -14,7 +14,7 @@ from multiprocessing import Process
from schainpy.model.proc.jroproc_base import Operation
-plt.ioff()
+plt.ion()
func = lambda x, pos: ('%s') %(datetime.datetime.fromtimestamp(x).strftime('%H:%M'))
@@ -58,6 +58,8 @@ class PlotData(Operation, Process):
self.__MAXNUMY = kwargs.get('decimation', 80)
self.throttle_value = 5
self.times = []
+ #self.interactive = self.kwargs['parent']
+
def fill_gaps(self, x_buffer, y_buffer, z_buffer):
@@ -94,16 +96,22 @@ class PlotData(Operation, Process):
print 'plotting...{}'.format(self.CODE)
if self.show:
- print 'showing'
self.figure.show()
self.figure2.show()
self.plot()
plt.tight_layout()
- self.figure.canvas.manager.set_window_title('{} {} - Date:{}'.format(self.title, self.CODE.upper(),
- datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')))
- self.figure2.canvas.manager.set_window_title('{} {} - Date:{}'.format(self.title, self.CODE.upper(),
- datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')))
+
+# self.figure.canvas.manager.set_window_title('{} {} - Date:{}'.format(self.title, self.CODE.upper(),
+# datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')))
+# self.figure2.canvas.manager.set_window_title('{} {} - Date:{}'.format(self.title, self.CODE.upper(),
+# datetime.datetime.fromtimestamp(self.max_time).strftime('%y/%m/%d %H:%M:%S')))
+# =======
+ self.figure.canvas.manager.set_window_title('{} {} - {}'.format(self.title, self.CODE.upper(),
+ datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
+ self.figure2.canvas.manager.set_window_title('{} {} - {}'.format(self.title, self.CODE.upper(),
+ datetime.datetime.fromtimestamp(self.max_time).strftime('%Y/%m/%d')))
+
if self.save:
figname = os.path.join(self.save, '{}_{}.png'.format(self.CODE,
@@ -126,12 +134,19 @@ class PlotData(Operation, Process):
def run(self):
print '[Starting] {}'.format(self.name)
+
context = zmq.Context()
receiver = context.socket(zmq.SUB)
receiver.setsockopt(zmq.SUBSCRIBE, '')
receiver.setsockopt(zmq.CONFLATE, self.CONFLATE)
- receiver.connect("ipc:///tmp/zmq.plots")
+
+ if 'server' in self.kwargs['parent']:
+ receiver.connect('ipc:///tmp/{}.plots'.format(self.kwargs['parent']['server']))
+ else:
+ receiver.connect("ipc:///tmp/zmq.plots")
+
seconds_passed = 0
+
while True:
try:
self.data = receiver.recv_pyobj(flags=zmq.NOBLOCK)#flags=zmq.NOBLOCK
@@ -637,6 +652,7 @@ class PlotNoiseData(PlotData):
class PlotWindProfilerData(PlotRTIData):
+
CODE = 'wind'
colormap = 'seismic'
@@ -646,7 +662,7 @@ class PlotWindProfilerData(PlotRTIData):
self.width = 10
self.height = 2.2*self.nrows
self.ylabel = 'Height [Km]'
- self.titles = ['Zonal' ,'Meridional', 'Vertical']
+ self.titles = ['Zonal Wind' ,'Meridional Wind', 'Vertical Wind']
self.clabels = ['Velocity (m/s)','Velocity (m/s)','Velocity (cm/s)']
self.windFactor = [1, 1, 100]
@@ -670,13 +686,13 @@ class PlotWindProfilerData(PlotRTIData):
self.z = []
for ch in range(self.nrows):
- self.z.append([self.data[self.CODE][t][ch] for t in self.times])
+ self.z.append([self.data['output'][t][ch] for t in self.times])
self.z = np.array(self.z)
self.z = numpy.ma.masked_invalid(self.z)
cmap=plt.get_cmap(self.colormap)
- cmap.set_bad('white', 1.)
+ cmap.set_bad('black', 1.)
for n, ax in enumerate(self.axes):
x, y, z = self.fill_gaps(*self.decimate())
@@ -695,9 +711,9 @@ class PlotWindProfilerData(PlotRTIData):
)
divider = make_axes_locatable(ax)
cax = divider.new_horizontal(size='2%', pad=0.05)
- cax.set_ylabel(self.clabels[n])
self.figure.add_axes(cax)
- plt.colorbar(plot, cax)
+ cb = plt.colorbar(plot, cax)
+ cb.set_label(self.clabels[n])
ax.set_ylim(self.ymin, self.ymax)
ax.xaxis.set_major_formatter(FuncFormatter(func))
@@ -734,3 +750,62 @@ class PlotDOPData(PlotRTIData):
class PlotPHASEData(PlotCOHData):
CODE = 'phase'
colormap = 'seismic'
+
+
+class PlotSkyMapData(PlotData):
+
+ CODE = 'met'
+
+ def setup(self):
+
+ self.ncols = 1
+ self.nrows = 1
+ self.width = 7.2
+ self.height = 7.2
+
+ self.xlabel = 'Zonal Zenith Angle (deg)'
+ self.ylabel = 'Meridional Zenith Angle (deg)'
+
+ if self.figure is None:
+ self.figure = plt.figure(figsize=(self.width, self.height),
+ edgecolor='k',
+ facecolor='w')
+ else:
+ self.figure.clf()
+
+ self.ax = plt.subplot2grid((self.nrows, self.ncols), (0, 0), 1, 1, polar=True)
+ self.ax.firsttime = True
+
+
+ def plot(self):
+
+ arrayParameters = np.concatenate([self.data['param'][t] for t in self.times])
+ 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
+
+ if self.ax.firsttime:
+ self.ax.plot = self.ax.plot(x, y, 'bo', markersize=5)[0]
+ self.ax.set_ylim(0,90)
+ self.ax.set_yticks(numpy.arange(0,90,20))
+ self.ax.set_xlabel(self.xlabel)
+ self.ax.set_ylabel(self.ylabel)
+ self.ax.yaxis.labelpad = 40
+ self.ax.firsttime = False
+ else:
+ self.ax.plot.set_data(x, y)
+
+
+ dt1 = datetime.datetime.fromtimestamp(self.min_time).strftime('%y/%m/%d %H:%M:%S')
+ dt2 = datetime.datetime.fromtimestamp(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.ax.set_title(title, size=8)
+
+ self.saveTime = self.max_time
diff --git a/schainpy/model/graphics/mpldriver.py b/schainpy/model/graphics/mpldriver.py
index c09ec41..b84fb1c 100644
--- a/schainpy/model/graphics/mpldriver.py
+++ b/schainpy/model/graphics/mpldriver.py
@@ -204,7 +204,7 @@ def createPcolor(ax, x, y, z, xmin, xmax, ymin, ymax, zmin, zmax,
z = numpy.ma.masked_invalid(z)
cmap=matplotlib.pyplot.get_cmap(colormap)
- cmap.set_bad('white', 1.)
+ 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)
@@ -264,7 +264,7 @@ def addpcolorbuffer(ax, x, y, z, zmin, zmax, xlabel='', ylabel='', title='', col
z = numpy.ma.masked_invalid(z)
cmap=matplotlib.pyplot.get_cmap(colormap)
- cmap.set_bad('white', 1.)
+ cmap.set_bad('black', 1.)
ax.pcolormesh(x,y,z.T,vmin=zmin,vmax=zmax, cmap=cmap)
diff --git a/schainpy/model/io/jroIO_base.py b/schainpy/model/io/jroIO_base.py
index a9b38a1..30a6f83 100644
--- a/schainpy/model/io/jroIO_base.py
+++ b/schainpy/model/io/jroIO_base.py
@@ -9,6 +9,7 @@ import glob
import time
import numpy
import fnmatch
+import inspect
import time, datetime
#import h5py
import traceback
@@ -536,6 +537,9 @@ class JRODataIO:
return dtype_width
+ def getAllowedArgs(self):
+ return inspect.getargspec(self.run).args
+
class JRODataReader(JRODataIO):
@@ -1432,12 +1436,52 @@ class JRODataReader(JRODataIO):
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,
+ queue=None,
+ skip=None,
+ cursor=None,
+ warnings=True,
+ verbose=True, **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,
+ queue=queue,
+ skip=skip,
+ cursor=cursor,
+ warnings=warnings,
+ verbose=verbose)
self.isConfig = True
self.getData()
@@ -1740,11 +1784,11 @@ class JRODataWriter(JRODataIO):
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()
diff --git a/schainpy/model/proc/jroproc_base.py b/schainpy/model/proc/jroproc_base.py
index e52ceef..55f3afd 100644
--- a/schainpy/model/proc/jroproc_base.py
+++ b/schainpy/model/proc/jroproc_base.py
@@ -149,6 +149,7 @@ class ProcessingUnit(object):
self.mp = True
self.start()
else:
+ self.operationKwargs[opId]['parent'] = self.kwargs
methodToCall(**self.operationKwargs[opId])
else:
if name=='run':
@@ -187,6 +188,7 @@ class ProcessingUnit(object):
if hasattr(externalProcObj, 'mp'):
if externalProcObj.mp is False:
+ externalProcObj.kwargs['parent'] = self.kwargs
self.operationKwargs[objId] = externalProcObj.kwargs
externalProcObj.mp = True
externalProcObj.start()
@@ -194,6 +196,7 @@ class ProcessingUnit(object):
externalProcObj.run(self.dataOut, **externalProcObj.kwargs)
self.operationKwargs[objId] = externalProcObj.kwargs
+
return True
def call(self, opType, opName=None, opId=None):
diff --git a/schainpy/model/proc/jroproc_parameters.py b/schainpy/model/proc/jroproc_parameters.py
index ee2b423..3111353 100644
--- a/schainpy/model/proc/jroproc_parameters.py
+++ b/schainpy/model/proc/jroproc_parameters.py
@@ -1038,7 +1038,7 @@ class WindProfiler(Operation):
return data_output
- def run(self, dataOut, technique, **kwargs):
+ def run(self, dataOut, technique, hmin=70, hmax=110, nHours=1, **kwargs):
param = dataOut.data_param
if dataOut.abscissaList != None:
diff --git a/schainpy/model/utils/jroutils_publish.py b/schainpy/model/utils/jroutils_publish.py
index 68a5907..e46c8c9 100644
--- a/schainpy/model/utils/jroutils_publish.py
+++ b/schainpy/model/utils/jroutils_publish.py
@@ -15,6 +15,7 @@ from threading import Thread
from multiprocessing import Process
from schainpy.model.proc.jroproc_base import Operation, ProcessingUnit
+from schainpy.model.data.jrodata import JROData
MAXNUMX = 100
MAXNUMY = 100
@@ -257,7 +258,44 @@ class PublishData(Operation):
self.client.loop_stop()
self.client.disconnect()
-class ReceiverData(ProcessingUnit, Process):
+
+class ReceiverData(ProcessingUnit):
+
+ 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)
+ print '[Starting] ReceiverData from {}'.format(self.address)
+
+
+ def run(self):
+
+ if not self.isConfig:
+ self.setup()
+ self.isConfig = True
+
+ self.dataOut = self.receiver.recv_pyobj()
+ print '[Receiving] {} - {}'.format(self.dataOut.type,
+ self.dataOut.datatime.ctime())
+
+
+class PlotterReceiver(ProcessingUnit, Process):
throttle_value = 5
@@ -268,7 +306,7 @@ class ReceiverData(ProcessingUnit, Process):
self.mp = False
self.isConfig = False
self.isWebConfig = False
- self.plottypes =[]
+ self.plottypes = []
self.connections = 0
server = kwargs.get('server', 'zmq.pipe')
plot_server = kwargs.get('plot_server', 'zmq.web')
@@ -373,8 +411,10 @@ class ReceiverData(ProcessingUnit, Process):
self.data[plottype][t] = self.dataOut.getCoherence()
if plottype == 'phase':
self.data[plottype][t] = self.dataOut.getCoherence(phase=True)
- if plottype == 'wind':
+ if plottype == 'output':
self.data[plottype][t] = self.dataOut.data_output
+ if plottype == 'param':
+ self.data[plottype][t] = self.dataOut.data_param
if self.realtime:
self.data_web['timestamp'] = t
if plottype == 'spc':
@@ -402,8 +442,14 @@ class ReceiverData(ProcessingUnit, Process):
self.sender_web = self.context.socket(zmq.PUB)
self.sender_web.connect(self.plot_address)
time.sleep(1)
- self.sender.bind("ipc:///tmp/zmq.plots")
+
+ 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(3)
+
t = Thread(target=self.event_monitor, args=(monitor,))
t.start()
@@ -417,7 +463,6 @@ class ReceiverData(ProcessingUnit, Process):
if self.dataOut.firstdata is True:
self.data['STARTED'] = True
-
if self.dataOut.finished is True:
self.send(self.data)
self.connections -= 1
diff --git a/schainpy/project.py b/schainpy/project.py
new file mode 100644
index 0000000..bdea4c3
--- /dev/null
+++ b/schainpy/project.py
@@ -0,0 +1,34 @@
+from schainpy.controller import Project
+
+desc = "A schain project"
+
+controller = Project()
+controller.setup(id='191', name="project", description=desc)
+
+readUnitConf = controller.addReadUnit(datatype='VoltageReader',
+ path="/home/nanosat/schain/schainpy",
+ startDate="1970/01/01",
+ endDate="2017/12/31",
+ startTime="00:00:00",
+ endTime="23:59:59",
+ online=0,
+ verbose=1,
+ walk=1,
+ )
+
+procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
+
+opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
+opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
+
+opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
+opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', 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='figpath', value="/home/nanosat/schain/schainpy/figs", format='str')
+opObj11.addParameter(name='wr_period', value='5', format='int')
+opObj11.addParameter(name='exp_code', value='22', format='int')
+
+
+controller.start()
diff --git a/schainpy/scripts/project.py b/schainpy/scripts/project.py
new file mode 100644
index 0000000..17237bd
--- /dev/null
+++ b/schainpy/scripts/project.py
@@ -0,0 +1,33 @@
+from schainpy.controller import Project
+
+desc = "A schain project"
+
+controller = Project()
+controller.setup(id='191', name="project", description=desc)
+
+readUnitConf = controller.addReadUnit(datatype='VoltageReader',
+ path="/home/nanosat/schain/schainpy/scripts",
+ startDate="1970/01/01",
+ endDate="2017/12/31",
+ startTime="00:00:00",
+ endTime="23:59:59",
+ online=0,
+ walk=1,
+ )
+
+procUnitConf1 = controller.addProcUnit(datatype='VoltageProc', inputId=readUnitConf.getId())
+
+opObj11 = procUnitConf1.addOperation(name='ProfileSelector', optype='other')
+opObj11.addParameter(name='profileRangeList', value='120,183', format='intlist')
+
+opObj11 = procUnitConf1.addOperation(name='RTIPlot', optype='other')
+opObj11.addParameter(name='wintitle', value='Jicamarca Radio Observatory', 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='figpath', value="/home/nanosat/schain/schainpy/scripts/figs", format='str')
+opObj11.addParameter(name='wr_period', value='5', format='int')
+opObj11.addParameter(name='exp_code', value='22', format='int')
+
+
+controller.start()
diff --git a/schainpy/scripts/receiver.py b/schainpy/scripts/receiver.py
index c0a4bf6..73af1b8 100644
--- a/schainpy/scripts/receiver.py
+++ b/schainpy/scripts/receiver.py
@@ -14,14 +14,16 @@ if __name__ == '__main__':
controllerObj = Project()
controllerObj.setup(id='191', name='test01', description=desc)
- proc1 = controllerObj.addProcUnit(name='ReceiverData')
+ proc1 = controllerObj.addProcUnit(name='PlotterReceiver')
# proc1.addParameter(name='realtime', value='0', format='bool')
#proc1.addParameter(name='plottypes', value='rti,coh,phase,snr,dop', format='str')
#proc1.addParameter(name='plottypes', value='rti,coh,phase,snr', format='str')
proc1.addParameter(name='plottypes', value='dop', format='str')
- proc1.addParameter(name='throttle', value='10', format='int')
- #proc1.addParameter(name='server', value='tcp://10.10.10.82:7000', format='str')
+ #proc1.addParameter(name='throttle', value='10', format='int')
+
+ proc1.addParameter(name='interactive', value='0', format='bool') # ? PREGUNTAR
+ # proc1.addParameter(name='server', value='tcp://10.10.10.82:7000', format='str')
## TODO Agregar direccion de server de publicacion a graficos como variable
"""
diff --git a/schainpy/scripts/schain.xml b/schainpy/scripts/schain.xml
index fe952f2..cf3e5c5 100644
--- a/schainpy/scripts/schain.xml
+++ b/schainpy/scripts/schain.xml
@@ -1 +1 @@
-
\ No newline at end of file
+
\ 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..85f1489
--- /dev/null
+++ b/schainpy/utils/log.py
@@ -0,0 +1,45 @@
+""".
+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):
+ click.echo(click.style('[WARNING] - ' + message, fg='yellow'))
+ pass
+
+
+def error(message):
+ click.echo(click.style('[ERROR] - ' + message, fg='red'))
+ pass
+
+
+def success(message):
+ click.echo(click.style(message, fg='green'))
+ pass
+
+
+def log(message):
+ click.echo('[LOG] - ' + message)
+ pass
+
+
+def makelogger(topic, bg='reset', fg='reset'):
+ def func(message):
+ click.echo(click.style('[{}] - '.format(topic.upper()) + message,
+ bg=bg, fg=fg))
+ return func
diff --git a/setup.py b/setup.py
index 3fe773f..dcee0b2 100644
--- a/setup.py
+++ b/setup.py
@@ -1,49 +1,57 @@
-'''
+""".
+
Created on Jul 16, 2014
@author: Miguel Urco
-'''
+"""
from schainpy import __version__
from setuptools import setup, Extension
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"])],
- install_requires=[
- "scipy >= 0.14.0",
- "h5py >= 2.2.1",
- "matplotlib >= 1.4.2",
- "pyfits >= 3.4",
- "numpy >= 1.11.2",
- "paramiko >= 2.1.2",
- "paho-mqtt >= 1.2",
- "zmq",
- "fuzzywuzzy"
- ],
+ 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,
+ entry_points={
+ 'console_scripts': [
+ 'schain = schaincli.cli:main',
+ ],
+ },
+ scripts=['schainpy/gui/schainGUI'],
+ ext_modules=[Extension("cSchain", ["schainpy/model/proc/extensions.c"])],
+ install_requires=[
+ "scipy >= 0.14.0",
+ "h5py >= 2.2.1",
+ "matplotlib >= 1.4.2",
+ "pyfits >= 3.4",
+ "numpy >= 1.11.2",
+ "paramiko >= 2.1.2",
+ "paho-mqtt >= 1.2",
+ "zmq",
+ "fuzzywuzzy",
+ "click",
+ "colorama",
+ "python-Levenshtein"
+ ],
)
diff --git a/trash b/trash
new file mode 100644
index 0000000..384299d
--- /dev/null
+++ b/trash
@@ -0,0 +1 @@
+You should install "digital_rf_hdf5" module if you want to read USRP data