##// END OF EJS Templates
merged branches
joabAM -
r1370:81f892b894eb merge
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,28
1 This software, unless otherwise noted, is licensed under the BSD 3-clause.
2
3 Copyright (c) 2012-2020 Jicamarca Radio Observatory
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
10
11 * Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14
15 * Neither the name of the copyright holder nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,82
1 #include <Python.h>
2 #include <numpy/arrayobject.h>
3 #include <math.h>
4
5
6 static PyObject *hildebrand_sekhon(PyObject *self, PyObject *args) {
7 double navg;
8 PyObject *data_obj, *data_array;
9
10 if (!PyArg_ParseTuple(args, "Od", &data_obj, &navg)) {
11 return NULL;
12 }
13
14 data_array = PyArray_FROM_OTF(data_obj, NPY_FLOAT64, NPY_IN_ARRAY);
15
16 if (data_array == NULL) {
17 Py_XDECREF(data_array);
18 Py_XDECREF(data_obj);
19 return NULL;
20 }
21 double *sortdata = (double*)PyArray_DATA(data_array);
22 int lenOfData = (int)PyArray_SIZE(data_array) ;
23 double nums_min = lenOfData*0.2;
24 if (nums_min <= 5) nums_min = 5;
25 double sump = 0;
26 double sumq = 0;
27 long j = 0;
28 int cont = 1;
29 double rtest = 0;
30 while ((cont == 1) && (j < lenOfData)) {
31 sump = sump + sortdata[j];
32 sumq = sumq + pow(sortdata[j], 2);
33 if (j > nums_min) {
34 rtest = (double)j/(j-1) + 1/navg;
35 if ((sumq*j) > (rtest*pow(sump, 2))) {
36 j = j - 1;
37 sump = sump - sortdata[j];
38 sumq = sumq - pow(sortdata[j],2);
39 cont = 0;
40 }
41 }
42 j = j + 1;
43 }
44
45 double lnoise = sump / j;
46
47 Py_DECREF(data_array);
48
49 // return PyLong_FromLong(lnoise);
50 return PyFloat_FromDouble(lnoise);
51 }
52
53
54 static PyMethodDef noiseMethods[] = {
55 { "hildebrand_sekhon", hildebrand_sekhon, METH_VARARGS, "Get noise with hildebrand_sekhon algorithm" },
56 { NULL, NULL, 0, NULL }
57 };
58
59 #if PY_MAJOR_VERSION >= 3
60
61 static struct PyModuleDef noisemodule = {
62 PyModuleDef_HEAD_INIT,
63 "_noise",
64 "Get noise with hildebrand_sekhon algorithm",
65 -1,
66 noiseMethods
67 };
68
69 #endif
70
71 #if PY_MAJOR_VERSION >= 3
72 PyMODINIT_FUNC PyInit__noise(void) {
73 Py_Initialize();
74 import_array();
75 return PyModule_Create(&noisemodule);
76 }
77 #else
78 PyMODINIT_FUNC init_noise() {
79 Py_InitModule("_noise", noiseMethods);
80 import_array();
81 }
82 #endif
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -100,15 +100,3 ENV/
100 100 # eclipse
101 101 .project
102 102 .pydevproject
103 # vscode
104
105 .vscode
106
107 schaingui/node_modules/
108 schainpy/scripts/
109 .svn/
110 *.png
111 *.pyc
112 .vscode
113 trash
114 *.log
@@ -1,13 +1,19
1 ## CHANGELOG:
1 # CHANGELOG
2 2
3 ### 3.0
4 * Python 3.x compatible
5 * New architecture with multiprocessing and IPC communication
6 * Add @MPDecorator for multiprocessing Units and Operations
3 ## 3.0.0
4
5 * Python 3.x & 2.X compatible
6 * New architecture with multiprocessing support
7 * Add @MPDecorator for multiprocessing Operations (Plots, Writers and Publishers)
7 8 * Added new type of operation `external` for non-locking operations
8 9 * New plotting architecture with buffering/throttle capabilities to speed up plots
10 * Clean controller to optimize scripts (format & optype are no longer required)
11 * Replace `ParamReader` and `ParamWriter` with new flexible `HDFReader` and `HDFWriter`
12 * New GUI with dynamic load of Units and operations (use Kivy framework)
13 * Clean code
14
15 ## 2.3
9 16
10 ### 2.3
11 17 * Added support for Madrigal formats (reading/writing).
12 18 * Added support for reading BLTR parameters (*.sswma).
13 19 * Added support for reading Julia format (*.dat).
@@ -28,92 +34,108
28 34 * Updated README for MAC OS GUI installation.
29 35 * Setup now installs numpy.
30 36
31 ### 2.2.6
37 ## 2.2.6
38
32 39 * Graphics generated by the GUI are now the same as generated by scripts. Issue #1074.
33 40 * Added support for C extensions.
34 41 * Function `hildebrand_sehkon` optimized with a C wrapper.
35 42 * Numpy version updated.
36 43 * Migration to GIT.
37 44
38 ### 2.2.5:
45 ## 2.2.5
46
39 47 * splitProfiles and combineProfiles modules were added to VoltageProc and Signal Chain GUI.
40 48 * nProfiles of USRP data (hdf5) is the number of profiles thera are in one second.
41 49 * jroPlotter works directly with data objects instead of dictionaries
42 50 * script "schain" was added to Signal Chain installer
43 51
44 ### 2.2.4.1:
52 ## 2.2.4.1
53
45 54 * jroIO_usrp.py is update to read Sandra's data
46 55 * decimation in Spectra and RTI plots is always enabled.
47 56 * time* window option added to GUI
48 57
49 ### 2.2.4:
58 ## 2.2.4
59
50 60 * jroproc_spectra_lags.py added to schainpy
51 61 * Bug fixed in schainGUI: ProcUnit was created with the same id in some cases.
52 62 * Bug fixed in jroHeaderIO: Header size validation.
53 63
54 ### 2.2.3.1:
64 ## 2.2.3.1
65
55 66 * Filtering block by time has been added.
56 67 * Bug fixed plotting RTI, CoherenceMap and others using xmin and xmax parameters. The first day worked
57 68 properly but the next days did not.
58 69
59 ### 2.2.3:
70 ## 2.2.3
71
60 72 * Bug fixed in GUI: Error getting(reading) Code value
61 73 * Bug fixed in GUI: Flip option always needs channelList field
62 74 * Bug fixed in jrodata: when one branch modified a value in "dataOut" (example: dataOut.code) this value
63 75 was modified for every branch (because this was a reference). It was modified in data.copy()
64 76 * Bug fixed in jroproc_voltage.profileSelector(): rangeList replaces to profileRangeList.
65 77
66 ### 2.2.2:
78 ## 2.2.2
79
67 80 * VoltageProc: ProfileSelector, Reshape, Decoder with nTxs!=1 and getblock=True was tested
68 81 * Rawdata and testRawdata.py added to Signal Chain project
69 82
70 ### 2.2.1:
83 ## 2.2.1
84
71 85 * Bugs fixed in GUI
72 86 * Views were improved in GUI
73 87 * Support to MST* ISR experiments
74 88 * Bug fixed getting noise using hyldebrant. (minimum number of points > 20%)
75 89 * handleError added to jroplotter.py
76 90
77 ### 2.2.0:
91 ## 2.2.0
92
78 93 * GUI: use of external plotter
79 94 * Compatible with matplotlib 1.5.0
80 95
81 ### 2.1.5:
96 ## 2.1.5
97
82 98 * serializer module added to Signal Chain
83 99 * jroplotter.py added to Signal Chain
84 100
85 ### 2.1.4.2:
101 ## 2.1.4.2
102
86 103 * A new Plotter Class was added
87 104 * Project.start() does not accept filename as a parameter anymore
88 105
89 ### 2.1.4.1:
106 ## 2.1.4.1
107
90 108 * Send notifications when an error different to ValueError is detected
91 109
92 ### 2.1.4:
110 ## 2.1.4
111
93 112 * Sending error notifications to signal chain administrator
94 113 * Login to email server added
95 114
96 ### 2.1.3.3:
115 ## 2.1.3.3
116
97 117 * Colored Button Icons were added to GUI
98 118
99 ### 2.1.3.2:
119 ## 2.1.3.2
120
100 121 * GUI: user interaction enhanced
101 122 * controller_api.py: Safe access to ControllerThead
102 123
103 ### 2.1.3.1:
124 ## 2.1.3.1
125
104 126 * GUI: every icon were resized
105 127 * jroproc_voltage.py: Print a message when "Read from code" option is selected and the code is not defined inside data file
106 128
107 ### 2.1.3:
129 ## 2.1.3
130
108 131 * jroplot_heispectra.py: SpectraHeisScope was not showing the right channels
109 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value),
110 Bug fixed selecting heights by block (selecting profiles instead heights)
132 * jroproc_voltage.py: Bug fixed selecting profiles (self.nProfiles took a wrong value), Bug fixed selecting heights by block (selecting profiles instead heights)
111 133 * jroproc_voltage.py: New feature added: decoding data by block using FFT.
112 134 * jroIO_heispectra.py: Bug fixed in FitsReader. Using local Fits instance instead schainpy.mode.data.jrodata.Fits.
113 135 * jroIO_heispectra.py: Channel index list does not exist.
114 136
115 ### 2.1.2:
116 * jroutils_ftp.py: Bug fixed, Any error sending file stopped the Server Thread
117 Server thread opens and closes remote server each time file list is sent
137 ## 2.1.2
138
139 * 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
118 140 * jroplot_spectra.py: Noise path was not being created when noise data is saved.
119 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF [18:00 * 07:00] No newline at end of file
141 * jroIO_base.py: startTime can be greater than endTime. Example: SpreadF
@@ -1,155 +1,104
1 1 # Signal Chain
2 2
3 ## Introduction
3 Signal Chain is a radar data processing library wich includes modules to read,
4 and write different files formats, besides modules to process and visualize the
5 data.
4 6
5 Signal Chain (SCh) is a radar data processing library developed using [Python](www.python.org) at JRO. SCh provides modules to read, write, process and plot data.
7 ## Dependencies
8
9 - GCC (gcc or gfortran)
10 - Python.h (python-dev or python-devel)
11 - Python-TK (python-tk)
12 - HDF5 libraries (libhdf5-dev)
6 13
7 14 ## Installation
8 15
9 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.
16 To get started the easiest way to install it is through
17 [PyPI](https://pypi.org/project/schainpy/) with pip. We strongly recommend to
18 use an virtual environment like virtualenv or anaconda.
10 19
11 ### Linux based system
20 ```bash
21 pip install schainpy
12 22 ```
13 $ 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
14 $ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/
15 $ cd schain
16 $ sudo pip install ./
17 23
18 ```
24 ### From source
19 25
20 ### MAC Os
21 ```
22 $ brew install python
23 $ brew install cartr/qt4/pyqt
24 $ git clone http://jro-dev.igp.gob.pe/rhodecode/schain/
25 $ cd schain
26 $ pip install ./
27 ```
26 First, ensure that you have the above-listed dependencies installed, then clone
27 the repository and install as normal python package:
28 28
29 **It is recommended to install schain in a virtual environment**
30 ```
31 $ virtualenv /path/to/virtual
32 $ source /path/to/virtual/bin/activate
33 (virtual) $ cd schain
34 (virtual) $ pip install ./
35 (virtual) $ bash link_PyQt4.sh
29 ```bash
30 git clone https://github.com/JRO-Peru/schainpy.git
31 cd schain
32 git checkout `branch-name` (optional)
33 sudo pip install ./
36 34 ```
37 35
38 ### Docker
36 ### Using Docker
39 37
40 Download Dockerfile from the repository, and create a docker image
38 Download Dockerfile from the repository, and create a docker image:
41 39
40 ```bash
41 docker build -t schain .
42 42 ```
43 $ docker build -t schain .
44 ```
45
46 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
47 ```
48 $ docker run -it --rm --volume /path/to/host/data:/data schain xml /data/test.xml
49 $ docker run -it --rm --volume /path/to/host/data:/data --entrypoint /urs/local/bin/python schain /data/test.py
50 ```
51
52 ## First Script
53
54 Read Spectra data (.pdata) - remove dc - plot spectra & RTI
55
56 Import SCh and creating a project
57
58 ```python
59 #!/usr/bin/python
60
61 from schainpy.controller import Project
62
63 controller = Project()
64 controller.setup(id = '100',
65 name='test',
66 description='Basic experiment')
67 43
44 You can run a container using an xml file or a schain script also you need to
45 mount a volume for the data input and for the output files/plots:
68 46
47 ```bash
48 docker run -it --rm --volume /path/to/host/data:/data schain xml /data/test.xml
49 docker run -it --rm --volume /path/to/host/data:/data --entrypoint /urs/local/bin/python schain /data/test.py
69 50 ```
70 51
71 Adding read unit and operations
52 ## CLI (command line interface)
72 53
73 ```python
74 read_unit = controller.addReadUnit(datatype='Spectra',
75 path='/path/to/pdata/',
76 startDate='2014/01/31',
77 endDate='2014/03/31',
78 startTime='00:00:00',
79 endTime='23:59:59',
80 online=0,
81 walk=0)
54 Signal Chain provides the following commands:
82 55
83 proc_unit = controller.addProcUnit(datatype='Spectra',
84 inputId=read_unit.getId())
56 - schainGUI: Open the GUI
57 - schain: Signal chain command line
85 58
86 op = proc_unit.addOperation(name='selectChannels')
87 op.addParameter(name='channelList', value='0,1', format='intlist')
88
89 op = proc_unit.addOperation(name='selectHeights')
90 op.addParameter(name='minHei', value='80', format='float')
91 op.addParameter(name='maxHei', value='200', format='float')
92
93 op = proc_unit.addOperation(name='removeDC')
94
95 ```
96
97 Plotting data & start project
98
99 ```python
100 op = proc_unit.addOperation(name='SpectraPlot', optype='other')
101 op.addParameter(name='id', value='1', format='int')
102 op.addParameter(name='wintitle', value='Spectra', format='str')
103
104 op = procUnitConfObj1.addOperation(name='RTIPlot', optype='other')
105 op.addParameter(name='id', value='2', format='int')
106 op.addParameter(name='wintitle', value='RTI', format='str')
107
108 controller.start()
109
110 ```
111
112 Full script
59 ## Example
113 60
61 Here you can find an script to read Spectra data (.pdata), remove dc and plot
62 self-spectra & RTI:
114 63
115 64 ```python
116 65 #!/usr/bin/python
117 66
118 67 from schainpy.controller import Project
119 68
120 controller = Project()
121 controller.setup(id = '100',
122 name='test',
123 description='Basic experiment')
124 read_unit = controller.addReadUnit(datatype='Spectra',
69 prj = Project()
70
71 read_unit = prj.addReadUnit(
72 datatype='Spectra',
125 73 path='/path/to/pdata/',
126 74 startDate='2014/01/31',
127 75 endDate='2014/03/31',
128 76 startTime='00:00:00',
129 77 endTime='23:59:59',
130 78 online=0,
131 walk=0)
79 walk=0
80 )
132 81
133 proc_unit = controller.addProcUnit(datatype='Spectra',
134 inputId=read_unit.getId())
82 proc_unit = prj.addProcUnit(
83 datatype='Spectra',
84 inputId=read_unit.getId()
85 )
135 86
136 87 op = proc_unit.addOperation(name='selectChannels')
137 op.addParameter(name='channelList', value='0,1', format='intlist')
88 op.addParameter(name='channelList', value='0,1')
138 89
139 90 op = proc_unit.addOperation(name='selectHeights')
140 op.addParameter(name='minHei', value='80', format='float')
141 op.addParameter(name='maxHei', value='200', format='float')
91 op.addParameter(name='minHei', value='80')
92 op.addParameter(name='maxHei', value='200')
142 93
143 94 op = proc_unit.addOperation(name='removeDC')
144 95
145 op = proc_unit.addOperation(name='SpectraPlot', optype='other')
146 op.addParameter(name='id', value='6', format='int')
96 op = proc_unit.addOperation(name='SpectraPlot')
147 97 op.addParameter(name='wintitle', value='Spectra', format='str')
148 98
149 op = procUnitConfObj1.addOperation(name='RTIPlot', optype='other')
150 op.addParameter(name='id', value='2', format='int')
99 op = proc_unit.addOperation(name='RTIPlot')
151 100 op.addParameter(name='wintitle', value='RTI', format='str')
152 101
153 controller.start()
102 prj.start()
154 103
155 104 ```
@@ -1,7 +1,8
1 '''
2 Created on Jul 3, 2018
1 """Signal chain python package"""
3 2
4 @author $Author$
5 @version $Id$
6 '''
7 __version__ = '3.0'
3 try:
4 from schainpy.controller import Project
5 except:
6 pass
7
8 __version__ = '3.0.0b6'
@@ -1,12 +1,9
1 1 import click
2 import schainpy
3 2 import subprocess
4 3 import os
5 4 import sys
6 5 import glob
7 save_stdout = sys.stdout
8 sys.stdout = open('/dev/null', 'w')
9 from multiprocessing import cpu_count
6 import schainpy
10 7 from schainpy.controller import Project
11 8 from schainpy.model import Operation, ProcessingUnit
12 9 from schainpy.utils import log
@@ -19,7 +16,6 try:
19 16 from queue import Queue
20 17 except:
21 18 from Queue import Queue
22 sys.stdout = save_stdout
23 19
24 20
25 21 def getProcs():
@@ -45,11 +41,19 def getOperations():
45 41
46 42 def getArgs(op):
47 43 module = locate('schainpy.model.{}'.format(op))
44 try:
45 obj = module(1, 2, 3, Queue())
46 except:
47 obj = module()
48 48
49 if hasattr(module, '__attrs__'):
50 args = module.__attrs__
49 if hasattr(obj, '__attrs__'):
50 args = obj.__attrs__
51 else:
52 if hasattr(obj, 'myrun'):
53 args = inspect.getfullargspec(obj.myrun).args
51 54 else:
52 args = inspect.getargspec(module.run).args
55 args = inspect.getfullargspec(obj.run).args
56
53 57 try:
54 58 args.remove('self')
55 59 except Exception as e:
@@ -63,7 +67,7 def getArgs(op):
63 67 def getDoc(obj):
64 68 module = locate('schainpy.model.{}'.format(obj))
65 69 try:
66 obj = module(1,2,3,Queue(),5,6)
70 obj = module(1, 2, 3, Queue())
67 71 except:
68 72 obj = module()
69 73 return obj.__doc__
@@ -89,9 +93,9 PREFIX = 'experiment'
89 93 @click.argument('nextcommand', default=None, required=False, type=str)
90 94 def main(command, nextcommand, version):
91 95 """COMMAND LINE INTERFACE FOR SIGNAL CHAIN - JICAMARCA RADIO OBSERVATORY V3.0\n
92 Available commands.\n
96 Available commands:\n
93 97 xml: runs a schain XML generated file\n
94 run: runs any python script starting 'experiment_'\n
98 run: runs any python script'\n
95 99 generate: generates a template schain script\n
96 100 list: return a list of available procs and operations\n
97 101 search: return avilable operations, procs or arguments of the given
@@ -151,11 +155,9 def search(nextcommand):
151 155 try:
152 156 args = getArgs(nextcommand)
153 157 doc = getDoc(nextcommand)
154 if len(args) == 0:
155 log.success('\n{} has no arguments'.format(nextcommand), '')
156 else:
157 log.success('{}\n{}\n\narguments:\n {}'.format(
158 nextcommand, doc, ', '.join(args)), '')
158 log.success('{}\n{}\n\nparameters:\n {}'.format(
159 nextcommand, doc, ', '.join(args)), ''
160 )
159 161 except Exception as e:
160 162 log.error('Module `{}` does not exists'.format(nextcommand), '')
161 163 allModules = getAll()
This diff has been collapsed as it changes many lines, (921 lines changed) Show them Hide them
@@ -1,26 +1,29
1 '''
2 Updated on January , 2018, for multiprocessing purposes
3 Author: Sergio Cortez
4 Created on September , 2012
5 '''
6 from platform import python_version
1 # Copyright (c) 2012-2020 Jicamarca Radio Observatory
2 # All rights reserved.
3 #
4 # Distributed under the terms of the BSD 3-clause license.
5 """API to create signal chain projects
6
7 The API is provide through class: Project
8 """
9
10 import re
7 11 import sys
8 12 import ast
9 13 import datetime
10 14 import traceback
11 import math
12 15 import time
13 import zmq
14 from multiprocessing import Process, Queue, Event, Value, cpu_count
16 import multiprocessing
17 from multiprocessing import Process, Queue
15 18 from threading import Thread
16 from xml.etree.ElementTree import ElementTree, Element, SubElement, tostring
17 from xml.dom import minidom
18
19 from xml.etree.ElementTree import ElementTree, Element, SubElement
19 20
20 21 from schainpy.admin import Alarm, SchainWarning
21 22 from schainpy.model import *
22 23 from schainpy.utils import log
23 24
25 if 'darwin' in sys.platform and sys.version_info[0] == 3 and sys.version_info[1] > 7:
26 multiprocessing.set_start_method('fork')
24 27
25 28 DTYPES = {
26 29 'Voltage': '.r',
@@ -287,282 +290,157 class OperationConf():
287 290 self.id = '0'
288 291 self.name = None
289 292 self.priority = None
290 self.topic = None
291
292 def __getNewId(self):
293
294 return int(self.id) * 10 + len(self.parmConfObjList) + 1
293 self.parameters = {}
294 self.object = None
295 self.operations = []
295 296
296 297 def getId(self):
298
297 299 return self.id
298 300
301 def getNewId(self):
302
303 return int(self.id) * 10 + len(self.operations) + 1
304
299 305 def updateId(self, new_id):
300 306
301 307 self.id = str(new_id)
302 308
303 309 n = 1
304 for parmObj in self.parmConfObjList:
305
306 idParm = str(int(new_id) * 10 + n)
307 parmObj.updateId(idParm)
308
310 for conf in self.operations:
311 conf_id = str(int(new_id) * 10 + n)
312 conf.updateId(conf_id)
309 313 n += 1
310 314
311 def getElementName(self):
312
313 return self.ELEMENTNAME
315 def getKwargs(self):
314 316
315 def getParameterObjList(self):
317 params = {}
316 318
317 return self.parmConfObjList
319 for key, value in self.parameters.items():
320 if value not in (None, '', ' '):
321 params[key] = value
318 322
319 def getParameterObj(self, parameterName):
323 return params
320 324
321 for parmConfObj in self.parmConfObjList:
325 def update(self, **kwargs):
322 326
323 if parmConfObj.name != parameterName:
324 continue
327 for key, value in kwargs.items():
328 self.addParameter(name=key, value=value)
325 329
326 return parmConfObj
330 def addParameter(self, name, value, format=None):
331 '''
332 '''
327 333
328 return None
334 if isinstance(value, str) and re.search(r'(\d+/\d+/\d+)', value):
335 self.parameters[name] = datetime.date(*[int(x) for x in value.split('/')])
336 elif isinstance(value, str) and re.search(r'(\d+:\d+:\d+)', value):
337 self.parameters[name] = datetime.time(*[int(x) for x in value.split(':')])
338 else:
339 try:
340 self.parameters[name] = ast.literal_eval(value)
341 except:
342 if isinstance(value, str) and ',' in value:
343 self.parameters[name] = value.split(',')
344 else:
345 self.parameters[name] = value
329 346
330 def getParameterObjfromValue(self, parameterValue):
347 def getParameters(self):
331 348
332 for parmConfObj in self.parmConfObjList:
349 params = {}
350 for key, value in self.parameters.items():
351 s = type(value).__name__
352 if s == 'date':
353 params[key] = value.strftime('%Y/%m/%d')
354 elif s == 'time':
355 params[key] = value.strftime('%H:%M:%S')
356 else:
357 params[key] = str(value)
333 358
334 if parmConfObj.getValue() != parameterValue:
335 continue
359 return params
336 360
337 return parmConfObj.getValue()
361 def makeXml(self, element):
338 362
339 return None
363 xml = SubElement(element, self.ELEMENTNAME)
364 for label in self.xml_labels:
365 xml.set(label, str(getattr(self, label)))
340 366
341 def getParameterValue(self, parameterName):
367 for key, value in self.getParameters().items():
368 xml_param = SubElement(xml, 'Parameter')
369 xml_param.set('name', key)
370 xml_param.set('value', value)
342 371
343 parameterObj = self.getParameterObj(parameterName)
372 for conf in self.operations:
373 conf.makeXml(xml)
344 374
345 # if not parameterObj:
346 # return None
375 def __str__(self):
347 376
348 value = parameterObj.getValue()
377 if self.ELEMENTNAME == 'Operation':
378 s = ' {}[id={}]\n'.format(self.name, self.id)
379 else:
380 s = '{}[id={}, inputId={}]\n'.format(self.name, self.id, self.inputId)
349 381
350 return value
382 for key, value in self.parameters.items():
383 if self.ELEMENTNAME == 'Operation':
384 s += ' {}: {}\n'.format(key, value)
385 else:
386 s += ' {}: {}\n'.format(key, value)
351 387
352 def getKwargs(self):
388 for conf in self.operations:
389 s += str(conf)
353 390
354 kwargs = {}
391 return s
355 392
356 for parmConfObj in self.parmConfObjList:
357 if self.name == 'run' and parmConfObj.name == 'datatype':
358 continue
393 class OperationConf(ConfBase):
359 394
360 kwargs[parmConfObj.name] = parmConfObj.getValue()
361
362 return kwargs
395 ELEMENTNAME = 'Operation'
396 xml_labels = ['id', 'name']
363 397
364 def setup(self, id, name, priority, type, project_id, err_queue, lock):
398 def setup(self, id, name, priority, project_id, err_queue):
365 399
366 400 self.id = str(id)
367 401 self.project_id = project_id
368 402 self.name = name
369 self.type = type
370 self.priority = priority
403 self.type = 'other'
371 404 self.err_queue = err_queue
372 self.lock = lock
373 self.parmConfObjList = []
374
375 def removeParameters(self):
376
377 for obj in self.parmConfObjList:
378 del obj
379
380 self.parmConfObjList = []
381
382 def addParameter(self, name, value, format='str'):
383
384 if value is None:
385 return None
386 id = self.__getNewId()
387
388 parmConfObj = ParameterConf()
389 if not parmConfObj.setup(id, name, value, format):
390 return None
391
392 self.parmConfObjList.append(parmConfObj)
393
394 return parmConfObj
395
396 def changeParameter(self, name, value, format='str'):
397
398 parmConfObj = self.getParameterObj(name)
399 parmConfObj.update(name, value, format)
400
401 return parmConfObj
402
403 def makeXml(self, procUnitElement):
404
405 opElement = SubElement(procUnitElement, self.ELEMENTNAME)
406 opElement.set('id', str(self.id))
407 opElement.set('name', self.name)
408 opElement.set('type', self.type)
409 opElement.set('priority', str(self.priority))
410 405
411 for parmConfObj in self.parmConfObjList:
412 parmConfObj.makeXml(opElement)
406 def readXml(self, element, project_id, err_queue):
413 407
414 def readXml(self, opElement, project_id):
415
416 self.id = opElement.get('id')
417 self.name = opElement.get('name')
418 self.type = opElement.get('type')
419 self.priority = opElement.get('priority')
408 self.id = element.get('id')
409 self.name = element.get('name')
410 self.type = 'other'
420 411 self.project_id = str(project_id)
412 self.err_queue = err_queue
421 413
422 # Compatible with old signal chain version
423 # Use of 'run' method instead 'init'
424 if self.type == 'self' and self.name == 'init':
425 self.name = 'run'
426
427 self.parmConfObjList = []
428
429 parmElementList = opElement.iter(ParameterConf().getElementName())
430
431 for parmElement in parmElementList:
432 parmConfObj = ParameterConf()
433 parmConfObj.readXml(parmElement)
434
435 # Compatible with old signal chain version
436 # If an 'plot' OPERATION is found, changes name operation by the value of its type PARAMETER
437 if self.type != 'self' and self.name == 'Plot':
438 if parmConfObj.format == 'str' and parmConfObj.name == 'type':
439 self.name = parmConfObj.value
440 continue
441
442 self.parmConfObjList.append(parmConfObj)
443
444 def printattr(self):
445
446 print('%s[%s]: name = %s, type = %s, priority = %s, project_id = %s' % (self.ELEMENTNAME,
447 self.id,
448 self.name,
449 self.type,
450 self.priority,
451 self.project_id))
452
453 for parmConfObj in self.parmConfObjList:
454 parmConfObj.printattr()
414 for elm in element.iter('Parameter'):
415 self.addParameter(elm.get('name'), elm.get('value'))
455 416
456 417 def createObject(self):
457 418
458 419 className = eval(self.name)
459 420
460 if self.type == 'other':
461 opObj = className()
462 elif self.type == 'external':
421 if 'Plot' in self.name or 'Writer' in self.name or 'Send' in self.name or 'print' in self.name:
463 422 kwargs = self.getKwargs()
464 opObj = className(self.id, self.id, self.project_id, self.err_queue, self.lock, 'Operation', **kwargs)
423 opObj = className(self.id, self.id, self.project_id, self.err_queue, **kwargs)
465 424 opObj.start()
466 self.opObj = opObj
425 self.type = 'external'
426 else:
427 opObj = className()
467 428
429 self.object = opObj
468 430 return opObj
469 431
470 class ProcUnitConf():
432 class ProcUnitConf(ConfBase):
471 433
472 434 ELEMENTNAME = 'ProcUnit'
435 xml_labels = ['id', 'inputId', 'name']
473 436
474 def __init__(self):
475
476 self.id = None
477 self.datatype = None
478 self.name = None
479 self.inputId = None
480 self.opConfObjList = []
481 self.procUnitObj = None
482 self.opObjDict = {}
483
484 def __getPriority(self):
485
486 return len(self.opConfObjList) + 1
487
488 def __getNewId(self):
489
490 return int(self.id) * 10 + len(self.opConfObjList) + 1
491
492 def getElementName(self):
493
494 return self.ELEMENTNAME
495
496 def getId(self):
497
498 return self.id
499
500 def updateId(self, new_id):
501 '''
502 new_id = int(parentId) * 10 + (int(self.id) % 10)
503 new_inputId = int(parentId) * 10 + (int(self.inputId) % 10)
504
505 # If this proc unit has not inputs
506 #if self.inputId == '0':
507 #new_inputId = 0
508
509 n = 1
510 for opConfObj in self.opConfObjList:
511
512 idOp = str(int(new_id) * 10 + n)
513 opConfObj.updateId(idOp)
514
515 n += 1
516
517 self.parentId = str(parentId)
518 self.id = str(new_id)
519 #self.inputId = str(new_inputId)
520 '''
521 n = 1
522
523 def getInputId(self):
524
525 return self.inputId
526
527 def getOperationObjList(self):
528
529 return self.opConfObjList
530
531 def getOperationObj(self, name=None):
532
533 for opConfObj in self.opConfObjList:
534
535 if opConfObj.name != name:
536 continue
537
538 return opConfObj
539
540 return None
541
542 def getOpObjfromParamValue(self, value=None):
543
544 for opConfObj in self.opConfObjList:
545 if opConfObj.getParameterObjfromValue(parameterValue=value) != value:
546 continue
547 return opConfObj
548 return None
549
550 def getProcUnitObj(self):
551
552 return self.procUnitObj
553
554 def setup(self, project_id, id, name, datatype, inputId, err_queue, lock):
437 def setup(self, project_id, id, name, datatype, inputId, err_queue):
555 438 '''
556 id sera el topico a publicar
557 inputId sera el topico a subscribirse
558 439 '''
559 440
560 # Compatible with old signal chain version
561 441 if datatype == None and name == None:
562 442 raise ValueError('datatype or name should be defined')
563 443
564 #Definir una condicion para inputId cuando sea 0
565
566 444 if name == None:
567 445 if 'Proc' in datatype:
568 446 name = datatype
@@ -578,100 +456,49 class ProcUnitConf():
578 456 self.datatype = datatype
579 457 self.inputId = inputId
580 458 self.err_queue = err_queue
581 self.lock = lock
582 self.opConfObjList = []
459 self.operations = []
460 self.parameters = {}
583 461
584 self.addOperation(name='run', optype='self')
462 def removeOperation(self, id):
585 463
586 def removeOperations(self):
587
588 for obj in self.opConfObjList:
589 del obj
590
591 self.opConfObjList = []
592 self.addOperation(name='run')
593
594 def addParameter(self, **kwargs):
595 '''
596 Add parameters to 'run' operation
597 '''
598 opObj = self.opConfObjList[0]
464 i = [1 if x.id==id else 0 for x in self.operations]
465 self.operations.pop(i.index(1))
599 466
600 opObj.addParameter(**kwargs)
467 def getOperation(self, id):
601 468
602 return opObj
469 for conf in self.operations:
470 if conf.id == id:
471 return conf
603 472
604 473 def addOperation(self, name, optype='self'):
605 474 '''
606 Actualizacion - > proceso comunicacion
607 En el caso de optype='self', elminar. DEfinir comuncacion IPC -> Topic
608 definir el tipoc de socket o comunicacion ipc++
609
610 475 '''
611 476
612 id = self.__getNewId()
613 priority = self.__getPriority() # Sin mucho sentido, pero puede usarse
614 opConfObj = OperationConf()
615 opConfObj.setup(id, name=name, priority=priority, type=optype, project_id=self.project_id, err_queue=self.err_queue, lock=self.lock)
616 self.opConfObjList.append(opConfObj)
617
618 return opConfObj
477 id = self.getNewId()
478 conf = OperationConf()
479 conf.setup(id, name=name, priority='0', project_id=self.project_id, err_queue=self.err_queue)
480 self.operations.append(conf)
619 481
620 def makeXml(self, projectElement):
482 return conf
621 483
622 procUnitElement = SubElement(projectElement, self.ELEMENTNAME)
623 procUnitElement.set('id', str(self.id))
624 procUnitElement.set('name', self.name)
625 procUnitElement.set('datatype', self.datatype)
626 procUnitElement.set('inputId', str(self.inputId))
484 def readXml(self, element, project_id, err_queue):
627 485
628 for opConfObj in self.opConfObjList:
629 opConfObj.makeXml(procUnitElement)
630
631 def readXml(self, upElement, project_id):
632
633 self.id = upElement.get('id')
634 self.name = upElement.get('name')
635 self.datatype = upElement.get('datatype')
636 self.inputId = upElement.get('inputId')
486 self.id = element.get('id')
487 self.name = element.get('name')
488 self.inputId = None if element.get('inputId') == 'None' else element.get('inputId')
489 self.datatype = element.get('datatype', self.name.replace(self.ELEMENTNAME.replace('Unit', ''), ''))
637 490 self.project_id = str(project_id)
491 self.err_queue = err_queue
492 self.operations = []
493 self.parameters = {}
638 494
639 if self.ELEMENTNAME == 'ReadUnit':
640 self.datatype = self.datatype.replace('Reader', '')
641
642 if self.ELEMENTNAME == 'ProcUnit':
643 self.datatype = self.datatype.replace('Proc', '')
644
645 if self.inputId == 'None':
646 self.inputId = '0'
647
648 self.opConfObjList = []
649
650 opElementList = upElement.iter(OperationConf().getElementName())
651
652 for opElement in opElementList:
653 opConfObj = OperationConf()
654 opConfObj.readXml(opElement, project_id)
655 self.opConfObjList.append(opConfObj)
656
657 def printattr(self):
658
659 print('%s[%s]: name = %s, datatype = %s, inputId = %s, project_id = %s' % (self.ELEMENTNAME,
660 self.id,
661 self.name,
662 self.datatype,
663 self.inputId,
664 self.project_id))
665
666 for opConfObj in self.opConfObjList:
667 opConfObj.printattr()
668
669 def getKwargs(self):
670
671 opObj = self.opConfObjList[0]
672 kwargs = opObj.getKwargs()
673
674 return kwargs
495 for elm in element:
496 if elm.tag == 'Parameter':
497 self.addParameter(elm.get('name'), elm.get('value'))
498 elif elm.tag == 'Operation':
499 conf = OperationConf()
500 conf.readXml(elm, project_id, err_queue)
501 self.operations.append(conf)
675 502
676 503 def createObjects(self):
677 504 '''
@@ -681,42 +508,27 class ProcUnitConf():
681 508 className = eval(self.name)
682 509 #print(self.name)
683 510 kwargs = self.getKwargs()
684 #print(kwargs)
685 #print("mark_a")
686 procUnitObj = className(self.id, self.inputId, self.project_id, self.err_queue, self.lock, 'ProcUnit', **kwargs)
687 #print("mark_b")
511 procUnitObj = className()
512 procUnitObj.name = self.name
688 513 log.success('creating process...', self.name)
689 514
690 for opConfObj in self.opConfObjList:
515 for conf in self.operations:
691 516
692 if opConfObj.type == 'self' and opConfObj.name == 'run':
693 continue
694 elif opConfObj.type == 'self':
695 opObj = getattr(procUnitObj, opConfObj.name)
696 else:
697 opObj = opConfObj.createObject()
517 opObj = conf.createObject()
698 518
699 519 log.success('adding operation: {}, type:{}'.format(
700 opConfObj.name,
701 opConfObj.type), self.name)
702
703 procUnitObj.addOperation(opConfObj, opObj)
520 conf.name,
521 conf.type), self.name)
704 522
705 procUnitObj.start()
706 self.procUnitObj = procUnitObj
523 procUnitObj.addOperation(conf, opObj)
707 524
708 def close(self):
525 self.object = procUnitObj
709 526
710 for opConfObj in self.opConfObjList:
711 if opConfObj.type == 'self':
712 continue
713
714 opObj = self.procUnitObj.getOperationObj(opConfObj.id)
715 opObj.close()
716
717 self.procUnitObj.close()
527 def run(self):
528 '''
529 '''
718 530
719 return
531 return self.object.call(**self.getKwargs())
720 532
721 533
722 534 class ReadUnitConf(ProcUnitConf):
@@ -729,28 +541,12 class ReadUnitConf(ProcUnitConf):
729 541 self.datatype = None
730 542 self.name = None
731 543 self.inputId = None
732 self.opConfObjList = []
733 self.lock = Event()
734 self.lock.set()
735 self.lock.n = Value('d', 0)
736
737 def getElementName(self):
738
739 return self.ELEMENTNAME
544 self.operations = []
545 self.parameters = {}
740 546
741 547 def setup(self, project_id, id, name, datatype, err_queue, path='', startDate='', endDate='',
742 548 startTime='', endTime='', server=None, **kwargs):
743 549
744
745 '''
746 *****el id del proceso sera el Topico
747
748 Adicion de {topic}, si no esta presente -> error
749 kwargs deben ser trasmitidos en la instanciacion
750
751 '''
752
753 # Compatible with old signal chain version
754 550 if datatype == None and name == None:
755 551 raise ValueError('datatype or name should be defined')
756 552 if name == None:
@@ -770,133 +566,41 class ReadUnitConf(ProcUnitConf):
770 566 self.project_id = project_id
771 567 self.name = name
772 568 self.datatype = datatype
773 if path != '':
774 self.path = os.path.abspath(path)
775 print (self.path)
776 self.startDate = startDate
777 self.endDate = endDate
778 self.startTime = startTime
779 self.endTime = endTime
780 self.server = server
781 569 self.err_queue = err_queue
782 self.addRunOperation(**kwargs)
783
784 def update(self, **kwargs):
785
786 if 'datatype' in kwargs:
787 datatype = kwargs.pop('datatype')
788 if 'Reader' in datatype:
789 self.name = datatype
790 else:
791 self.name = '%sReader' % (datatype)
792 self.datatype = self.name.replace('Reader', '')
793
794 attrs = ('path', 'startDate', 'endDate',
795 'startTime', 'endTime')
796
797 for attr in attrs:
798 if attr in kwargs:
799 setattr(self, attr, kwargs.pop(attr))
800
801 self.updateRunOperation(**kwargs)
802 570
803 def removeOperations(self):
571 self.addParameter(name='path', value=path)
572 self.addParameter(name='startDate', value=startDate)
573 self.addParameter(name='endDate', value=endDate)
574 self.addParameter(name='startTime', value=startTime)
575 self.addParameter(name='endTime', value=endTime)
804 576
805 for obj in self.opConfObjList:
806 del obj
807
808 self.opConfObjList = []
809
810 def addRunOperation(self, **kwargs):
811
812 opObj = self.addOperation(name='run', optype='self')
813
814 if self.server is None:
815 opObj.addParameter(
816 name='datatype', value=self.datatype, format='str')
817 opObj.addParameter(name='path', value=self.path, format='str')
818 opObj.addParameter(
819 name='startDate', value=self.startDate, format='date')
820 opObj.addParameter(
821 name='endDate', value=self.endDate, format='date')
822 opObj.addParameter(
823 name='startTime', value=self.startTime, format='time')
824 opObj.addParameter(
825 name='endTime', value=self.endTime, format='time')
826
827 for key, value in list(kwargs.items()):
828 opObj.addParameter(name=key, value=value,
829 format=type(value).__name__)
830 else:
831 opObj.addParameter(name='server', value=self.server, format='str')
832
833 return opObj
834
835 def updateRunOperation(self, **kwargs):
836
837 opObj = self.getOperationObj(name='run')
838 opObj.removeParameters()
839
840 opObj.addParameter(name='datatype', value=self.datatype, format='str')
841 opObj.addParameter(name='path', value=self.path, format='str')
842 opObj.addParameter(
843 name='startDate', value=self.startDate, format='date')
844 opObj.addParameter(name='endDate', value=self.endDate, format='date')
845 opObj.addParameter(
846 name='startTime', value=self.startTime, format='time')
847 opObj.addParameter(name='endTime', value=self.endTime, format='time')
848
849 for key, value in list(kwargs.items()):
850 opObj.addParameter(name=key, value=value,
851 format=type(value).__name__)
852
853 return opObj
854
855 def readXml(self, upElement, project_id):
856
857 self.id = upElement.get('id')
858 self.name = upElement.get('name')
859 self.datatype = upElement.get('datatype')
860 self.project_id = str(project_id) #yong
861
862 if self.ELEMENTNAME == 'ReadUnit':
863 self.datatype = self.datatype.replace('Reader', '')
864
865 self.opConfObjList = []
866
867 opElementList = upElement.iter(OperationConf().getElementName())
868
869 for opElement in opElementList:
870 opConfObj = OperationConf()
871 opConfObj.readXml(opElement, project_id)
872 self.opConfObjList.append(opConfObj)
873
874 if opConfObj.name == 'run':
875 self.path = opConfObj.getParameterValue('path')
876 self.startDate = opConfObj.getParameterValue('startDate')
877 self.endDate = opConfObj.getParameterValue('endDate')
878 self.startTime = opConfObj.getParameterValue('startTime')
879 self.endTime = opConfObj.getParameterValue('endTime')
577 for key, value in kwargs.items():
578 self.addParameter(name=key, value=value)
880 579
881 580
882 581 class Project(Process):
582 """API to create signal chain projects"""
883 583
884 584 ELEMENTNAME = 'Project'
885 585
886 def __init__(self):
586 def __init__(self, name=''):
887 587
888 588 Process.__init__(self)
889 self.id = None
589 self.id = '1'
590 if name:
591 self.name = '{} ({})'.format(Process.__name__, name)
890 592 self.filename = None
891 593 self.description = None
892 594 self.email = None
893 self.alarm = None
894 self.procUnitConfObjDict = {}
895 self.err_queue = Queue()
595 self.alarm = []
596 self.configurations = {}
597 # self.err_queue = Queue()
598 self.err_queue = None
599 self.started = False
896 600
897 def __getNewId(self):
601 def getNewId(self):
898 602
899 idList = list(self.procUnitConfObjDict.keys())
603 idList = list(self.configurations.keys())
900 604 id = int(self.id) * 10
901 605
902 606 while True:
@@ -909,43 +613,28 class Project(Process):
909 613
910 614 return str(id)
911 615
912 def getElementName(self):
913
914 return self.ELEMENTNAME
915
916 def getId(self):
917
918 return self.id
919
920 616 def updateId(self, new_id):
921 617
922 618 self.id = str(new_id)
923 619
924 keyList = list(self.procUnitConfObjDict.keys())
620 keyList = list(self.configurations.keys())
925 621 keyList.sort()
926 622
927 623 n = 1
928 newProcUnitConfObjDict = {}
624 new_confs = {}
929 625
930 626 for procKey in keyList:
931 627
932 procUnitConfObj = self.procUnitConfObjDict[procKey]
628 conf = self.configurations[procKey]
933 629 idProcUnit = str(int(self.id) * 10 + n)
934 procUnitConfObj.updateId(idProcUnit)
935 newProcUnitConfObjDict[idProcUnit] = procUnitConfObj
630 conf.updateId(idProcUnit)
631 new_confs[idProcUnit] = conf
936 632 n += 1
937 633
938 self.procUnitConfObjDict = newProcUnitConfObjDict
634 self.configurations = new_confs
939 635
940 636 def setup(self, id=1, name='', description='', email=None, alarm=[]):
941 637
942 print(' ')
943 print('*' * 60)
944 print('* Starting SIGNAL CHAIN PROCESSING (Multiprocessing) v%s *' % schainpy.__version__)
945 print('*' * 60)
946 print("* Python " + python_version() + " *")
947 print('*' * 19)
948 print(' ')
949 638 self.id = str(id)
950 639 self.description = description
951 640 self.email = email
@@ -955,108 +644,91 class Project(Process):
955 644
956 645 def update(self, **kwargs):
957 646
958 for key, value in list(kwargs.items()):
647 for key, value in kwargs.items():
959 648 setattr(self, key, value)
960 649
961 650 def clone(self):
962 651
963 652 p = Project()
964 p.procUnitConfObjDict = self.procUnitConfObjDict
653 p.id = self.id
654 p.name = self.name
655 p.description = self.description
656 p.configurations = self.configurations.copy()
657
965 658 return p
966 659
967 660 def addReadUnit(self, id=None, datatype=None, name=None, **kwargs):
968 661
969 662 '''
970 Actualizacion:
971 Se agrego un nuevo argumento: topic -relativo a la forma de comunicar los procesos simultaneos
972
973 * El id del proceso sera el topico al que se deben subscribir los procUnits para recibir la informacion(data)
974
975 663 '''
976 664
977 665 if id is None:
978 idReadUnit = self.__getNewId()
666 idReadUnit = self.getNewId()
979 667 else:
980 668 idReadUnit = str(id)
981 669
982 readUnitConfObj = ReadUnitConf()
983 readUnitConfObj.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
984 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
670 conf = ReadUnitConf()
671 conf.setup(self.id, idReadUnit, name, datatype, self.err_queue, **kwargs)
672 self.configurations[conf.id] = conf
985 673
986 return readUnitConfObj
674 return conf
987 675
988 def addProcUnit(self, inputId='0', datatype=None, name=None):
676 def addProcUnit(self, id=None, inputId='0', datatype=None, name=None):
989 677
990 678 '''
991 Actualizacion:
992 Se agrego dos nuevos argumentos: topic_read (lee data de otro procUnit) y topic_write(escribe o envia data a otro procUnit)
993 Deberia reemplazar a "inputId"
994
995 ** A fin de mantener el inputID, este sera la representaacion del topicoal que deben subscribirse. El ID propio de la intancia
996 (proceso) sera el topico de la publicacion, todo sera asignado de manera dinamica.
997
998 679 '''
999 680
1000 idProcUnit = self.__getNewId()
1001 procUnitConfObj = ProcUnitConf()
1002 input_proc = self.procUnitConfObjDict[inputId]
1003 procUnitConfObj.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue, input_proc.lock)
1004 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
1005
1006 return procUnitConfObj
1007
1008 def removeProcUnit(self, id):
681 if id is None:
682 idProcUnit = self.getNewId()
683 else:
684 idProcUnit = id
1009 685
1010 if id in list(self.procUnitConfObjDict.keys()):
1011 self.procUnitConfObjDict.pop(id)
686 conf = ProcUnitConf()
687 conf.setup(self.id, idProcUnit, name, datatype, inputId, self.err_queue)
688 self.configurations[conf.id] = conf
1012 689
1013 def getReadUnitId(self):
690 return conf
1014 691
1015 readUnitConfObj = self.getReadUnitObj()
692 def removeProcUnit(self, id):
1016 693
1017 return readUnitConfObj.id
694 if id in self.configurations:
695 self.configurations.pop(id)
1018 696
1019 def getReadUnitObj(self):
697 def getReadUnit(self):
1020 698
1021 for obj in list(self.procUnitConfObjDict.values()):
1022 if obj.getElementName() == 'ReadUnit':
699 for obj in list(self.configurations.values()):
700 if obj.ELEMENTNAME == 'ReadUnit':
1023 701 return obj
1024 702
1025 703 return None
1026 704
1027 def getProcUnitObj(self, id=None, name=None):
1028
1029 if id != None:
1030 return self.procUnitConfObjDict[id]
705 def getProcUnit(self, id):
1031 706
1032 if name != None:
1033 return self.getProcUnitObjByName(name)
707 return self.configurations[id]
1034 708
1035 return None
1036
1037 def getProcUnitObjByName(self, name):
709 def getUnits(self):
1038 710
1039 for obj in list(self.procUnitConfObjDict.values()):
1040 if obj.name == name:
1041 return obj
711 keys = list(self.configurations)
712 keys.sort()
1042 713
1043 return None
714 for key in keys:
715 yield self.configurations[key]
1044 716
1045 def procUnitItems(self):
717 def updateUnit(self, id, **kwargs):
1046 718
1047 return list(self.procUnitConfObjDict.items())
719 conf = self.configurations[id].update(**kwargs)
1048 720
1049 721 def makeXml(self):
1050 722
1051 projectElement = Element('Project')
1052 projectElement.set('id', str(self.id))
1053 projectElement.set('name', self.name)
1054 projectElement.set('description', self.description)
723 xml = Element('Project')
724 xml.set('id', str(self.id))
725 xml.set('name', self.name)
726 xml.set('description', self.description)
1055 727
1056 for procUnitConfObj in list(self.procUnitConfObjDict.values()):
1057 procUnitConfObj.makeXml(projectElement)
728 for conf in self.configurations.values():
729 conf.makeXml(xml)
1058 730
1059 self.projectElement = projectElement
731 self.xml = xml
1060 732
1061 733 def writeXml(self, filename=None):
1062 734
@@ -1082,54 +754,38 class Project(Process):
1082 754
1083 755 self.makeXml()
1084 756
1085 ElementTree(self.projectElement).write(abs_file, method='xml')
757 ElementTree(self.xml).write(abs_file, method='xml')
1086 758
1087 759 self.filename = abs_file
1088 760
1089 761 return 1
1090 762
1091 def readXml(self, filename=None):
1092
1093 if not filename:
1094 print('filename is not defined')
1095 return 0
763 def readXml(self, filename):
1096 764
1097 765 abs_file = os.path.abspath(filename)
1098 766
1099 if not os.path.isfile(abs_file):
1100 print('%s file does not exist' % abs_file)
1101 return 0
1102
1103 self.projectElement = None
1104 self.procUnitConfObjDict = {}
767 self.configurations = {}
1105 768
1106 769 try:
1107 self.projectElement = ElementTree().parse(abs_file)
770 self.xml = ElementTree().parse(abs_file)
1108 771 except:
1109 print('Error reading %s, verify file format' % filename)
772 log.error('Error reading %s, verify file format' % filename)
1110 773 return 0
1111 774
1112 self.project = self.projectElement.tag
1113
1114 self.id = self.projectElement.get('id')
1115 self.name = self.projectElement.get('name')
1116 self.description = self.projectElement.get('description')
1117
1118 readUnitElementList = self.projectElement.iter(
1119 ReadUnitConf().getElementName())
1120
1121 for readUnitElement in readUnitElementList:
1122 readUnitConfObj = ReadUnitConf()
1123 readUnitConfObj.readXml(readUnitElement, self.id)
1124 self.procUnitConfObjDict[readUnitConfObj.getId()] = readUnitConfObj
1125
1126 procUnitElementList = self.projectElement.iter(
1127 ProcUnitConf().getElementName())
1128
1129 for procUnitElement in procUnitElementList:
1130 procUnitConfObj = ProcUnitConf()
1131 procUnitConfObj.readXml(procUnitElement, self.id)
1132 self.procUnitConfObjDict[procUnitConfObj.getId()] = procUnitConfObj
775 self.id = self.xml.get('id')
776 self.name = self.xml.get('name')
777 self.description = self.xml.get('description')
778
779 for element in self.xml:
780 if element.tag == 'ReadUnit':
781 conf = ReadUnitConf()
782 conf.readXml(element, self.id, self.err_queue)
783 self.configurations[conf.id] = conf
784 elif element.tag == 'ProcUnit':
785 conf = ProcUnitConf()
786 input_proc = self.configurations[element.get('inputId')]
787 conf.readXml(element, self.id, self.err_queue)
788 self.configurations[conf.id] = conf
1133 789
1134 790 self.filename = abs_file
1135 791
@@ -1137,28 +793,33 class Project(Process):
1137 793
1138 794 def __str__(self):
1139 795
1140 print('Project: name = %s, description = %s, id = %s' % (
796 text = '\nProject[id=%s, name=%s, description=%s]\n\n' % (
797 self.id,
1141 798 self.name,
1142 799 self.description,
1143 self.id))
800 )
1144 801
1145 for procUnitConfObj in self.procUnitConfObjDict.values():
1146 print(procUnitConfObj)
802 for conf in self.configurations.values():
803 text += '{}'.format(conf)
1147 804
1148 def createObjects(self):
805 return text
1149 806
807 def createObjects(self):
1150 808
1151 keys = list(self.procUnitConfObjDict.keys())
809 keys = list(self.configurations.keys())
1152 810 keys.sort()
1153 811 for key in keys:
1154 self.procUnitConfObjDict[key].createObjects()
812 conf = self.configurations[key]
813 conf.createObjects()
814 if conf.inputId is not None:
815 conf.object.setInput(self.configurations[conf.inputId].object)
1155 816
1156 817 def monitor(self):
1157 818
1158 t = Thread(target=self.__monitor, args=(self.err_queue, self.ctx))
819 t = Thread(target=self._monitor, args=(self.err_queue, self.ctx))
1159 820 t.start()
1160 821
1161 def __monitor(self, queue, ctx):
822 def _monitor(self, queue, ctx):
1162 823
1163 824 import socket
1164 825
@@ -1189,13 +850,7 class Project(Process):
1189 850 else:
1190 851 name, err = self.name, err_msg
1191 852
1192 time.sleep(2)
1193
1194 for conf in self.procUnitConfObjDict.values():
1195 for confop in conf.opConfObjList:
1196 if confop.type == 'external':
1197 confop.opObj.terminate()
1198 conf.procUnitObj.terminate()
853 time.sleep(1)
1199 854
1200 855 ctx.term()
1201 856
@@ -1211,15 +866,14 class Project(Process):
1211 866 subtitle += 'Configuration file: %s\n' % self.filename
1212 867 subtitle += 'Time: %s\n' % str(datetime.datetime.now())
1213 868
1214 readUnitConfObj = self.getReadUnitObj()
869 readUnitConfObj = self.getReadUnit()
1215 870 if readUnitConfObj:
1216 871 subtitle += '\nInput parameters:\n'
1217 subtitle += '[Data path = %s]\n' % readUnitConfObj.path
1218 subtitle += '[Data type = %s]\n' % readUnitConfObj.datatype
1219 subtitle += '[Start date = %s]\n' % readUnitConfObj.startDate
1220 subtitle += '[End date = %s]\n' % readUnitConfObj.endDate
1221 subtitle += '[Start time = %s]\n' % readUnitConfObj.startTime
1222 subtitle += '[End time = %s]\n' % readUnitConfObj.endTime
872 subtitle += '[Data path = %s]\n' % readUnitConfObj.parameters['path']
873 subtitle += '[Start date = %s]\n' % readUnitConfObj.parameters['startDate']
874 subtitle += '[End date = %s]\n' % readUnitConfObj.parameters['endDate']
875 subtitle += '[Start time = %s]\n' % readUnitConfObj.parameters['startTime']
876 subtitle += '[End time = %s]\n' % readUnitConfObj.parameters['endTime']
1223 877
1224 878 a = Alarm(
1225 879 modes=self.alarm,
@@ -1232,64 +886,33 class Project(Process):
1232 886
1233 887 a.start()
1234 888
1235 def isPaused(self):
1236 return 0
1237
1238 def isStopped(self):
1239 return 0
1240
1241 def runController(self):
1242 '''
1243 returns 0 when this process has been stopped, 1 otherwise
1244 '''
1245
1246 if self.isPaused():
1247 print('Process suspended')
1248
1249 while True:
1250 time.sleep(0.1)
1251
1252 if not self.isPaused():
1253 break
1254
1255 if self.isStopped():
1256 break
1257
1258 print('Process reinitialized')
1259
1260 if self.isStopped():
1261 print('Process stopped')
1262 return 0
1263
1264 return 1
1265
1266 889 def setFilename(self, filename):
1267 890
1268 891 self.filename = filename
1269 892
1270 def setProxy(self):
893 def runProcs(self):
1271 894
1272 if not os.path.exists('/tmp/schain'):
1273 os.mkdir('/tmp/schain')
895 err = False
896 n = len(self.configurations)
1274 897
1275 self.ctx = zmq.Context()
1276 xpub = self.ctx.socket(zmq.XPUB)
1277 xpub.bind('ipc:///tmp/schain/{}_pub'.format(self.id))
1278 xsub = self.ctx.socket(zmq.XSUB)
1279 xsub.bind('ipc:///tmp/schain/{}_sub'.format(self.id))
1280 self.monitor()
1281 try:
1282 zmq.proxy(xpub, xsub)
1283 except zmq.ContextTerminated:
1284 xpub.close()
1285 xsub.close()
898 while not err:
899 for conf in self.getUnits():
900 ok = conf.run()
901 if ok == 'Error':
902 n -= 1
903 continue
904 elif not ok:
905 break
906 if n == 0:
907 err = True
1286 908
1287 909 def run(self):
1288 910
1289 log.success('Starting {}: {}'.format(self.name, self.id), tag='')
911 log.success('\nStarting Project {} [id={}]'.format(self.name, self.id), tag='')
912 self.started = True
1290 913 self.start_time = time.time()
1291 914 self.createObjects()
1292 self.setProxy()
1293 log.success('{} Done (Time: {}s)'.format(
915 self.runProcs()
916 log.success('{} Done (Time: {:4.2f}s)'.format(
1294 917 self.name,
1295 918 time.time()-self.start_time), '')
@@ -1,1 +0,0
1 from viewcontroller import * No newline at end of file
@@ -1,39 +1,325
1 1 #!/usr/bin/env python
2 2 import os
3 3 import sys
4 import ast
5
6 from schainpy.controller import Project
7 from schainpy.cli import cli
4 8 from schainpy.utils import log
5 9
6 10 try:
7 from PyQt4 import QtCore, QtGui
8 from PyQt4.QtGui import QApplication
11 import kivy
12 from kivy.app import App
13 from kivy.uix.label import Label
14 from kivy.uix.boxlayout import BoxLayout
15 from kivy.uix.gridlayout import GridLayout
16 from kivy.uix.textinput import TextInput
17 from kivy.uix.button import Button
18 from kivy.uix.dropdown import DropDown
19 from kivy.uix.togglebutton import ToggleButton
20 from kivy.uix.popup import Popup
21 from kivy.uix.filechooser import FileChooserListView
9 22 except:
10 23 log.error(
11 'You should install PyQt4 module in order to run the GUI. See the README.')
24 'You should install kivy module in order to run the GUI.')
12 25 sys.exit()
13 26
14 from schainpy.gui.viewcontroller.initwindow import InitWindow
15 from schainpy.gui.viewcontroller.basicwindow import BasicWindow
16 from schainpy.gui.viewcontroller.workspace import Workspace
17 27
28 DEFAULTS = {
29 'path': os.path.expanduser('~'),
30 'startDate': '2018/01/01',
31 'endDate': '2020/01/01',
32 'startTime': '00:00:00',
33 'endTime': '23:59:59',
34 'online': '1',
35 'delay': '30',
36 'walk': '1',
37 'show': '1',
38 'zmin': '10',
39 'zmax': '40',
40 }
41
42
43 class MainLayout(BoxLayout):
44 def __init__(self, **kwargs):
45 super(MainLayout, self).__init__(**kwargs)
46
47 self.workspace = os.path.join(os.path.expanduser('~'), 'workspace/scripts')
48 self.current_unit_id = None
49 self._units = []
50 self.project = Project()
51 self.project.setup(id='1', name='test', description='')
52
53 self.sidebar_left = BoxLayout(orientation='vertical', size_hint_x=0.4, spacing=5)
54 self.body = BoxLayout(orientation='vertical', spacing=5)
55 self.sidebar_right = BoxLayout(orientation='vertical', size_hint_x=0.6, spacing=5)
56
57 bt_prj = Button(text='Project')
58 bt_prj.bind(on_press=self.show_project)
59 self.sidebar_left.add_widget(bt_prj)
60
61 bt_add_unit = Button(text='Add Unit')
62 bt_add_unit.bind(on_press=self.select_unit)
63 self.sidebar_left.add_widget(bt_add_unit)
64
65 bt_add_operation = Button(text='Add Operation')
66 bt_add_operation.bind(on_press=self.select_operation)
67 self.sidebar_left.add_widget(bt_add_operation)
68
69 bt_import = Button(text='Import')
70 bt_import.bind(on_press=self.load)
71 self.sidebar_left.add_widget(bt_import)
72
73 bt_export = Button(text='Export')
74 bt_export.bind(on_press=self.export)
75 self.sidebar_left.add_widget(bt_export)
76
77 bt_run = Button(text='Run')
78 bt_run.bind(on_press=self.run)
79 self.sidebar_left.add_widget(bt_run)
80
81 bt_stop = Button(text='Stop')
82 bt_stop.bind(on_press = self.stop)
83 self.sidebar_left.add_widget(bt_stop)
84
85 bt_exit = Button(text = 'Exit', height = 40, size_hint_y = None, background_color=(1, 0, 0, 1))
86 bt_exit.bind(on_press=App.get_running_app().stop)
87 self.sidebar_left.add_widget(bt_exit)
88
89 self.add_widget(self.sidebar_left)
90 self.add_widget(self.body)
91 self.add_widget(self.sidebar_right)
92
93 def update_body(self):
94
95 self._units = []
96 self.body.clear_widgets()
97 self.sidebar_right.clear_widgets()
98
99 for unit in self.project.getUnits():
100 box = GridLayout(cols=3)
101 bt = ToggleButton(text=unit.name, group='units')
102 bt._obj = unit
103 bt.bind(on_press=self.show_parameters)
104 box.add_widget(bt)
105 self._units.append(bt)
106
107 for operation in unit.operations:
108 bt_op = Button(text = operation.name, background_color=(1, 0.5, 0, 1))
109 bt_op._id = unit.id
110 bt_op._obj = operation
111 bt_op.bind(on_press=self.show_parameters)
112 box.add_widget(bt_op)
113
114 self.body.add_widget(box)
115
116 print(self.project)
117
118 def show_parameters(self, instance):
119
120 obj = instance._obj
121 self.current_unit_id = obj.id
122 self.sidebar_right.clear_widgets()
123
124 if obj and obj.parameters:
125 self._params = {}
126
127 for key, value in obj.getParameters().items():
128 self.sidebar_right.add_widget(Label(text=key))
129 text = TextInput(text=value, multiline=False)
130 self._params[key] = text
131 self.sidebar_right.add_widget(text)
132
133 bt_save = Button(text = 'Save', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
134 bt_save._obj = obj
135 if hasattr(instance, '_id'):
136 bt_save._id = instance._id
137 self.current_unit_id = None
138 bt_save.bind(on_press=self.save_parameters)
139 self.sidebar_right.add_widget(bt_save)
140
141 bt_delete = Button(text = 'Delete', height = 40, size_hint_y = None, background_color=(1, 0, 0, 1))
142 bt_delete._obj = obj
143 if hasattr(instance, '_id'):
144 bt_delete._id = instance._id
145 self.current_unit_id = obj.id
146 bt_delete.bind(on_press=self.delete_object)
147 self.sidebar_right.add_widget(bt_delete)
148
149 def save_parameters(self, instance):
150
151 obj = instance._obj
152 params = {}
153 for key in self._params:
154 if self._params[key]:
155 params[key] = self._params[key].text
156
157 if hasattr(instance, '_id'):
158 unit = self.project.getProcUnit(instance._id)
159 op = unit.getOperation(obj.id)
160 op.update(**params)
161 else:
162 unit = self.project.getProcUnit(obj.id)
163 unit.update(**params)
164
165 def delete_object(self, instance):
166
167 obj = instance._obj
168
169 if hasattr(instance, '_id'):
170 unit = self.project.getProcUnit(instance._id)
171 unit.removeOperation(obj.id)
172 else:
173 self.project.removeProcUnit(obj.id)
174
175 self.project.updateId(self.project.id)
176 self.update_body()
177
178 def show_project(self, instance):
179
180 self.sidebar_right.clear_widgets()
181 self._params = {}
182 for label in ['Id', 'Name', 'Description']:
183 self.sidebar_right.add_widget(Label(text=label))
184 text = TextInput(text=getattr(self.project, label.lower()), multiline=False)
185 self._params[label] = text
186 self.sidebar_right.add_widget(text)
187
188 self.sidebar_right.add_widget(Label(text='Workspace'))
189 text = TextInput(text=getattr(self, 'workspace'), multiline=False)
190 self._params['Workspace'] = text
191 self.sidebar_right.add_widget(text)
192
193 bt_save = Button(text = 'Save', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
194 bt_save.bind(on_press = self.save_project_parameters)
195 self.sidebar_right.add_widget(bt_save)
196
197 def save_project_parameters(self, instance):
198
199 for label in ['Id', 'Name', 'Description']:
200 setattr(self.project, label.lower(), self._params[label].text)
201
202 setattr(self, 'workspace', self._params['Workspace'].text)
203
204 def select_unit(self, instance):
205
206 self.sidebar_right.clear_widgets()
207 bt_main = Button(text = 'Select Unit', height = 40, size_hint_y = None)
208 dropdown = DropDown()
209
210 for unit in cli.getProcs():
211
212 btn = Button(text = unit, size_hint_y = None, height = 40)
213 btn.bind(on_release = lambda btn: dropdown.select(btn.text))
214 dropdown.add_widget(btn)
215
216 bt_main.bind(on_release = dropdown.open)
217 dropdown.bind(on_select = lambda instance, x: setattr(bt_main, 'text', x))
218
219 bt_add = Button(text = 'Add', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
220 bt_add.bind(on_press = lambda instance: self.add_unit(bt_main.text))
221
222 self.sidebar_right.add_widget(bt_main)
223 self.sidebar_right.add_widget(bt_add)
224
225 def add_unit(self, s):
226
227 if s:
228 if 'Reader' in s:
229 unit = self.project.addReadUnit(name=s)
230 else:
231 *_, last = self.project.getUnits()
232 unit = self.project.addProcUnit(name=s, inputId=last.id)
233
234 keys = cli.getArgs(unit.name)
235 values = [DEFAULTS[key] if key in DEFAULTS else '' for key in keys]
236 unit.update(**dict(zip(keys, values)))
237 self.update_body()
238
239 def select_operation(self, instance):
240
241 self.sidebar_right.clear_widgets()
242 btns = [bt.state == 'down' for bt in self._units]
243 if True in btns:
244 bt_main = Button(text = 'Select Operation', height = 40, size_hint_y = None)
245 dropdown = DropDown()
246
247 for unit in cli.getOperations():
248
249 btn = Button(text = unit, size_hint_y = None, height = 40)
250 btn.bind(on_release = lambda btn: dropdown.select(btn.text))
251 dropdown.add_widget(btn)
252
253 bt_main.bind(on_release = dropdown.open)
254 dropdown.bind(on_select = lambda instance, x: setattr(bt_main, 'text', x))
255
256 bt_add = Button(text = 'Add', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
257 bt_add.bind(on_press = lambda instance: self.add_operation(bt_main.text))
258
259 self.sidebar_right.add_widget(bt_main)
260 self.sidebar_right.add_widget(bt_add)
261 else:
262 self.sidebar_right.add_widget(Label(text='Select Unit'))
263
264 def add_operation(self, s):
265
266 if s:
267 unit = self.project.getProcUnit(self.current_unit_id)
268 op = unit.addOperation(name=s)
269 keys = cli.getArgs(op.name)
270 values = [DEFAULTS[key] if key in DEFAULTS else '' for key in keys]
271 op.update(**dict(zip(keys, values)))
272 self.update_body()
273
274 def run(self, instance):
275
276 if self.project and self.project.is_alive():
277 self.sidebar_right.clear_widgets()
278 self.sidebar_right.add_widget(Label(text='Project running'))
279 else:
280 if self.project.exitcode is None:
281 self.project.start()
282 else:
283 self.project = self.project.clone()
284 self.project.start()
285
286 def stop(self, instance):
287
288 if self.project and self.project.is_alive():
289 self.project.kill()
290 log.error('Project Stopped by user', 'GUI')
291 else:
292 self.sidebar_right.clear_widgets()
293 self.sidebar_right.add_widget(Label(text='Project not running'))
294
295 def load(self, instance):
296
297 self.sidebar_right.clear_widgets()
298 textinput = FileChooserListView(
299 path=self.workspace, size_hint=(1, 1), dirselect=False, filters=['*.xml'])
300
301 self.sidebar_right.add_widget(textinput)
302 bt_open = Button(text = 'Open', height = 40, size_hint_y = None, background_color=(0, 1, 0, 1))
303 bt_open.textinput = textinput
304 bt_open.bind(on_press = self.load_file)
305 self.sidebar_right.add_widget(bt_open)
18 306
19 def main():
307 def load_file(self, instance):
20 308
21 app = QtGui.QApplication(sys.argv)
309 self.project.readXml(instance.textinput.selection[0])
310 self.update_body()
22 311
23 Welcome = InitWindow()
312 def export(self, instance):
24 313
25 if not Welcome.exec_():
26 sys.exit(-1)
314 filename = os.path.join(self.workspace, '{}.xml'.format(self.project.name))
315 self.project.writeXml(filename)
316 log.success('File created: {}'.format(filename), 'GUI')
27 317
28 WorkPathspace = Workspace()
29 if not WorkPathspace.exec_():
30 sys.exit(-1)
31 318
32 MainGUI = BasicWindow()
33 MainGUI.setWorkSpaceGUI(WorkPathspace.dirComBox.currentText())
34 MainGUI.show()
35 sys.exit(app.exec_())
319 class SignalChainApp(App):
320 def build(self):
321 return MainLayout(spacing=10)
36 322
37 323
38 324 if __name__ == "__main__":
39 main()
325 SignalChainApp().run() No newline at end of file
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from schainpy/gui/figures/__init__.py to schainpy/scripts/restore.spst
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
This diff has been collapsed as it changes many lines, (1765 lines changed) Show them Hide them
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now