source: SHX/trunk/src/SeismicHandler/tests/test_commands.py @ 152

Revision 152, 17.1 KB checked in by marcus, 14 years ago (diff)
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Rev Id Date
Line 
1# -*- coding: utf-8 -*-
2
3from SeismicHandler.core.modules.Events import Message, MessageService
4from SeismicHandler.core.modules.Trace import Traces
5from SeismicHandler.core.modules.Variables import Symbol, System
6from SeismicHandler.core.modules.Tools import convertFilename
7from SeismicHandler.core.commands import Run
8from SeismicHandler.core.shheaders import TIME
9
10import pickle
11import os
12
13import unittest
14
15class commandsTestCase(unittest.TestCase):
16    def setUp(self):
17        self.traces = Traces()
18
19    def tearDown(self):
20        # Following every test all traces are deleted.
21        Run("del all")
22
23    def loadCompare(self, name):
24        return pickle.load(open(os.path.join("data", os.path.extsep.join((name, "pkl")))))
25
26    def checkTraceData(self, trc, cmp=None, cmpindex=None, digits=7):
27        """Compare trc data either to cmp data or data from cmpindex
28
29        For accuracy adjustment use the digits parameter."""
30
31        if cmp == None:
32            check = self.loadCompare(cmpindex)
33        else:
34            check = cmp
35
36        # Check for identical length.
37        self.assertEqual(len(trc), len(check))
38
39        # Compare data points itself.
40        for i, dat in enumerate(check):
41            self.assertAlmostEqual(dat, trc.fetchData()[i], digits)
42
43    def testAl(self):
44        # XXX Commands for visualisation are not tested yet.
45        pass
46
47    def testAm(self):
48        # Create synthetic trace of 100 seconds length.
49        # Maximum amplitude 113 at position 15.
50        Run("create sharp 0.05 100 113. 15. .1 .5")
51
52        # create symbols (we want to set the result type from python)
53        Symbol.min = 0.
54        Symbol.minpos = 0.
55        Symbol.max = 0.
56        Symbol.maxpos = 0.
57        Run("am 1 0. 100. &min &max &minpos &maxpos")
58
59        # test values taken from SH command line version
60        self.assertAlmostEqual(Symbol.min, -60.2811)
61        self.assertAlmostEqual(Symbol.minpos, 24.05)
62        self.assertAlmostEqual(Symbol.max, 113.00)
63        self.assertAlmostEqual(Symbol.maxpos, 17.75)
64
65    def testAppend(self):
66        # Create two synthetic traces.
67        MessageService.block(Message(MessageService.REDRAW))
68        Run("cresharp")
69        Run("cresharp")
70        MessageService.unblock(Message(MessageService.REDRAW))
71
72        self.assertEqual(self.traces[0].length, 1000)
73        self.assertEqual(self.traces[1].length, 1000)
74
75        # Append trace 1 to trace 2
76        Run("append 1 2")
77
78        self.assertEqual(self.traces[0].length, 1000)
79        self.assertEqual(self.traces[1].length, 2000)
80
81        # Data for comparison saved from SH command line
82        # and converted to pickle.
83        check = self.loadCompare("cresharp")
84
85        # Check trace 1.
86        self.checkTraceData(self.traces[0], check)
87
88        # Check trace 2, simply append comparison data again.
89        self.checkTraceData(self.traces[1], check*2)
90
91    def testArp(self):
92        # Create synthetic trace and run auto correlation three times.
93        Run("cresharp")
94        Run("arp 1 2 1.8 -0.9")
95        Run("arp 1 2 1.8 -0.9")
96        Run("arp 1 2 1.8 -0.9")
97
98        # Unfortunately exporting small floats to ascii format has a very
99        # poor accuracy, so we just use 3 decimal places.
100        self.checkTraceData(self.traces[0], cmpindex="cresharp-arp", digits=3)
101
102    def testBeam(self):
103        # XXX Commands for visualisation are not tested yet.
104        pass
105
106    def testCalc(self):
107        # Calculation operations can be done in python very easily and more
108        # flexible. Except for time data type everything is just built-in.
109        pass
110
111    def testCall(self):
112        # The call command just fills symbol variables. Access to them are
113        # tested in test_variables case.
114        pass
115
116    def testCmd(self):
117        # This is more or less replaced by the history function in SHX.
118        pass
119
120    def testConnect(self):
121        Run("cresharp")
122        Run("cresharp")
123        Run("connect mul 1 2")
124        # This should more or less restore the original trace.
125        Run("connect div 3 1")
126
127        self.checkTraceData(self.traces[2], cmpindex="cresharp-connectmul")
128        self.checkTraceData(self.traces[3], cmpindex="cresharp", digits=5)
129
130    def testCopy(self):
131        Run("cresharp")
132        Run("copy 1 20 40")
133
134        # Compare data from 20 to 40 seconds (and add extra sample, the "seismosample")
135        check = self.loadCompare("cresharp")[20*20:40*20+1]
136
137        self.checkTraceData(self.traces[1], check)
138
139    def testCorr(self):
140        # This test also fails. The resulting trace is somehow scaled down to
141        # a maximum amplitude if 1. Also the trace seems to be distorted...
142        Run("cresharp")
143        Run("cresharp")
144
145        # I set the correlation length to be save, that's the default.
146        Run("corrl -30.0 100.0")
147        Run("corr 1 15. 25. 2")
148
149#        self.traces[2].plot()
150        self.checkTraceData(self.traces[2], cmpindex="cresharp-corr")
151
152    def testCorrl(self):
153        # There's not method to check the values of correlation length.
154        pass
155
156    def testCreate(self):
157        Run("create spike 0.05 250 20 40")
158        Run("create sharp 0.05 250 20 20 .03 .5")
159        Run("create gauss 0.05 250 20 125 5")
160        Run("create exp 0.05 250 20 40 30")
161        # Obviously we cannot test the random trace creation. :)
162
163        self.checkTraceData(self.traces[0], cmpindex="create-spike")
164        self.checkTraceData(self.traces[1], cmpindex="create-sharp", digits=5)
165        self.checkTraceData(self.traces[2], cmpindex="create-gauss", digits=5)
166        self.checkTraceData(self.traces[3], cmpindex="create-exp", digits=5)
167
168    def testCurve(self):
169        # XXX Commands for visualisation are not tested yet.
170        pass
171
172    def testCut(self):
173        Run("cresharp")
174
175        # Just to show that there is a natural counting access to traces.
176        # This is identical to "trc = self.traces[0]"
177        trc = self.traces.get(1)
178
179        # By definition all traces without time information start on
180        # 01-Jul-1970 12:00:00.000 which results in 15681600 seconds unix epoch.
181        start = trc.start.hi
182        self.assertAlmostEqual(start, 15681600)
183        self.assertAlmostEqual(trc.start.lo, 0)
184
185        Run("cut 1 20 40")
186
187        self.checkTraceData(trc, cmpindex="cut")
188
189        # Since the first 20 seconds were cut, the trace start is shifted
190        self.assertEquals(trc.start.hi, start + 20)
191        self.assertAlmostEqual(trc.start.lo, 0)
192
193    def testDecimate(self):
194        Run("cresharp")
195        self.assertAlmostEqual(self.traces[0].delta, 0.05)
196
197        Run("decimate 1 4")
198        self.assertAlmostEqual(self.traces[0].delta, 0.20)
199
200        self.checkTraceData(self.traces[0], cmpindex="decimate")
201
202    def testDefault(self):
203        # Interactive prompting is not tested yet.
204        pass
205
206    def testDel(self):
207        Run("cresharp")
208        self.assertEqual(len(self.traces), 1)
209        Run("del 1")
210        self.assertEqual(len(self.traces), 0)
211
212    def testDelay_sum(self):
213        # XXX Commands for visualisation are not tested yet.
214        pass
215
216    def testDemean(self):
217        Run("cresharp")
218        Run("demean 1")
219
220        self.checkTraceData(self.traces[0], cmpindex="demean")
221
222    def testDerive(self):
223        Run("cresharp")
224        Run("derive 1 3")
225
226        self.checkTraceData(self.traces[0], cmpindex="derive")
227
228    def testDespike(self):
229        Run("create spike 0.05 50 20 20")
230        Run("despike 1 100.")
231
232        # Now we should have only zeros in trace data:
233        trc = self.traces.get(1)
234        self.checkTraceData(trc, [0.,]*trc.length)
235
236    def testDisplay(self):
237        # XXX Commands for visualisation are not tested yet.
238        pass
239
240    def testDtw(self):
241        # XXX Commands for visualisation are not tested yet.
242        pass
243
244    def testEcho(self):
245        # This function is not useful in python context.
246        pass
247
248    def testEchoCh(self):
249        # This function is not useful in python context.
250        pass
251
252    def testEnter(self):
253        # This function is not useful in python context.
254        pass
255
256    def testEntry(self):
257        # Note: Since info entries cannot be unset, this will affect every
258        # test case following this one.
259        Run("entry define foo s 3 3")
260
261        # Reload info entries.
262        MessageService.trigger(Message(MessageService.INFOIDXUPDATE))
263
264        # Create test trace and assign value to created info entry.
265        Run("cresharp")
266        self.traces.get(1).foo = "lala"
267
268        # Trace data has been altered.
269        MessageService.trigger(Message(MessageService.TRACEUPDATE))
270
271        self.assertEqual(self.traces.get(1).foo, "lala")
272
273    def testExec(self):
274        # This function is not useful in python context.
275        pass
276
277    def testExtract(self):
278        # XXX q-file related function are not tested yet.
279        pass
280
281    def testFct(self):
282        # XXX Some subfunctions are display related, some not.
283        pass
284
285    def testFft(self):
286        # XXX This test fails.
287
288        Run("cresharp")
289        # Increase amplitude
290        Run("trcfct 1 mul 100")
291        Run("fft 1 5 30 1")
292
293#        self.traces[1].plot()
294        self.checkTraceData(self.traces[1], cmpindex="fft")
295
296    def testFilter(self):
297        Run("create spike 0.05 50 20 20")
298        Run("fili f BP_2S_10HZ_4")
299        Run("filter f 1")
300
301        self.checkTraceData(self.traces[1], cmpindex="filter", digits=5)
302
303    testFili = testFilter
304
305    def testFold(self):
306        Run("cresharp")
307        Run("cresharp")
308        Run("fold 1 10 20 2")
309
310        self.checkTraceData(self.traces[2], cmpindex="fold", digits=5)
311
312    def testGoto(self):
313        # This command is already replaced by python
314        pass
315
316    def testHc(self):
317        # This function is not useful in python context.
318        pass
319
320    def testHelp(self):
321        # This function is not useful in python context.
322        pass
323
324    def testHide(self):
325        # XXX Commands for visualisation are not tested yet.
326        pass
327
328    def testIf(self):
329        # This command is already replaced by python
330        pass
331
332    def testInt(self):
333        Run("cresharp")
334        Run("int 1")
335
336        self.checkTraceData(self.traces[1], cmpindex="int", digits=5)
337
338    def testLocate(self):
339        # XXX not tested since it depends on AL command
340        pass
341
342    def testMark(self):
343        # XXX Commands for visualisation are not tested yet.
344        pass
345
346    def testMaxAmpl(self):
347        Run("cresharp")
348        Run("trcfct 1 mul 100")
349        Run("maxampl 1 35")
350        self.checkTraceData(self.traces[0], cmpindex="maxampl", digits=5)
351
352    def testMaximum(self):
353        Run("cresharp")
354        Run("cresharp")
355        Run("mirror 2")
356        Run("maximum all number")
357        self.checkTraceData(self.traces[2], cmpindex="maximum1")
358        self.checkTraceData(self.traces[3], cmpindex="maximum2")
359
360    def testMdir(self):
361        for _ in range(3):
362            Run("cresharp")
363
364        Run("mirror 2")
365
366        Symbol.azi = 0.
367        Symbol.inci = 0.
368
369        Run("mdir 1,2 10. 20. &azi")
370        self.assertAlmostEqual(Symbol.azi, 6.271768)
371
372        Run("mdir 1-3 10. 20. &azi &inci")
373        self.assertAlmostEqual(Symbol.azi, 263.763123, 4)
374        self.assertAlmostEqual(Symbol.inci, 45.170059, 5)
375
376        Symbol.azi = None
377        Symbol.inci = None
378
379    def testMend(self):
380        # This test fails in context to all other tests. Running stand alone, it will pass.
381        # It also passes, if next line is uncommented (strange, isn't it).
382        # XXX
383#        print len(self.traces)
384        Run("cresharp")
385        Run("mend 1 6 10 30")
386        self.checkTraceData(self.traces[0], cmpindex="mend")
387
388    def testMerge(self):
389        Run("cresharp")
390        Run("cresharp")
391
392        # shift trace #2 by 21 seconds
393        t = TIME()
394        t.hi = self.traces[1].start.hi + 21
395        t.lo = 0
396        self.traces[1].start = t
397
398        Run("merge 2 1")
399
400        self.checkTraceData(self.traces[2], cmpindex="merge")
401
402    def testMergePair(self):
403        # create three traces of which two are "mergeable" (identical source)
404        for _ in range(3):
405            Run("cresharp")
406
407        trc1 = self.traces.get(1)
408        trc2 = self.traces.get(2)
409        trc3 = self.traces.get(3)
410
411        trc1.comp = trc2.comp = trc3.comp = "Z"
412        trc1.station = trc3.station = "TST"
413        trc2.station = "TTT"
414        trc1.chan1 = trc2.chan1 = trc3.chan1 = "B"
415        trc1.chan2 = trc2.chan2 = trc3.chan2 = "H"
416
417        Symbol.one = 0
418        Symbol.two = 0
419
420        Run("merge_pair &one &two")
421
422        self.assertEqual(Symbol.one, 1)
423        self.assertEqual(Symbol.two, 3)
424
425    def testMirror(self):
426        Run("cresharp")
427        Run("mirror 1")
428
429        check = self.loadCompare("cresharp")[::-1]
430        self.checkTraceData(self.traces[0], cmp=check)
431
432    def testNorm(self):
433        # XXX Commands for visualisation are not tested yet.
434        pass
435
436    def testNr(self):
437        # XXX Commands for visualisation are not tested yet.
438        pass
439
440    def testOverlay(self):
441        # XXX Commands for visualisation are not tested yet.
442        pass
443
444    def testPick(self):
445        # read real world data (@ = don't convert case of this command)
446        Run("@READGSE %s ALL" % convertFilename("data/GRF_031102_0225.GSE"))
447        # create symbol
448        Symbol.x = ""
449
450        Run("pick 1 0 200 &x")
451        self.assertEqual(Symbol.x, " 2-NOV-2003_02:26:43.500")
452
453        # delete symbol
454        Symbol.x = None
455
456    def testPmch(self):
457        # XXX Commands for visualisation are not tested yet.
458        pass
459
460    def testPm(self):
461        # XXX Commands for visualisation are not tested yet.
462        pass
463
464    def testPolFil(self):
465        self.fail("no test case created")
466
467    def testQuit(self):
468        # no need to test this
469        pass
470
471    def testRd(self):
472        # XXX Commands for visualisation are not tested yet.
473        pass
474
475    def testRead(self):
476        Run("@READ %s 1" % convertFilename("data/cresharp"))
477        self.checkTraceData(self.traces[0], cmpindex="cresharp")
478
479    def testReada(self):
480        Run("@READA %s" % convertFilename("data/CRESHARP.asc"))
481        self.checkTraceData(self.traces[0], cmpindex="cresharp")
482
483        # I set a comment containing recipe how the trace was compiled.
484        self.assertEqual(self.traces[0].comment, "CRESHARP")
485
486    def testReadf(self):
487        # Just test for GSE2 format
488        Run("@READF/FMT=5 %s ALL" % convertFilename("data/GRF_031102_0225.GSE"))
489        self.assertEqual(int(System.tottrcs), 19)
490#        self.traces.plot()
491
492    def testReads(self):
493        self.fail("no test created yet!")
494
495    def testResample(self):
496        Run("cresharp")
497        Run("resample 1 .01")
498
499        # resample does not trigger redraw
500        MessageService.trigger(Message(MessageService.TRACEUPDATE))
501
502        self.assertAlmostEqual(self.traces[-1].delta, 0.01)
503        self.assertAlmostEqual(self.traces[-1].length, 5000)
504        self.assertAlmostEqual(self.traces[-1].alloc, 5000)
505
506    def testReturn(self):
507        # This function is not useful in python context.
508        pass
509
510    def testRms(self):
511        Run("cresharp")
512        Symbol.rms = 0.
513        Run("rms 1 ;;; &rms")
514
515        self.assertAlmostEqual(Symbol.rms, 0.2942311)
516
517        Symbol.rms = None
518
519    def testRot(self):
520        Run("cresharp")
521        Run("cresharp")
522        Run("rot 1,2 45")
523
524        # Trace 3 now contains only zeros, while trace 4 holds all energy.
525        self.checkTraceData(self.traces[2], cmp=[0.]*self.traces[-2].length)
526        self.checkTraceData(self.traces[3], cmpindex="rot", digits=6)
527
528    def testSdef(self):
529        # This function is not useful in python context.
530        pass
531
532    def testSdel(self):
533        # This function is not useful in python context.
534        pass
535
536    def testSet(self):
537        # This function is not useful in python context.
538        pass
539
540    def testShift(self):
541        # XXX Commands for visualisation are not tested yet.
542        pass
543
544    def testSpecDiv(self):
545        self.fail("no test created!")
546
547    def testSpectrogram(self):
548        import tempfile
549        tmp = tempfile.mktemp()
550        del tempfile
551
552        Run("cresharp")
553        Run("@SPECTROGRAM 1 ;;; 128 2 %s" % convertFilename(tmp))
554
555        self.assertEqual(open(tmp).readlines(), open("data/spectrogram.out").readlines())
556
557        os.remove(tmp)
558
559    def testSpectrum(self):
560        self.fail("no test created!")
561
562    def testSum(self):
563        # this test fails for some reason
564        # the summed trace has *never* a length greater 100 seconds
565
566        MessageService.block(Message(MessageService.REDRAW))
567
568        # if you set seconds to 100 or lower, everything works fine
569        # this is independent from sampling rate(!)
570        seconds, delta = 120., 0.01
571
572        # create 2 identical synthetics with "seconds" length, 1/"delta" Hz
573        for _ in xrange(2):
574            Run("CREATE SHARP %.2f %u 1. 15. .1 .5" % (delta, seconds))
575
576        Run("sum all")
577
578        MessageService.unblock(Message(MessageService.REDRAW))
579
580        for trc in self.traces:
581            self.assertAlmostEqual(trc.delta, delta, 6)
582
583            self.assertEqual(trc.length, seconds/delta)
584            self.assertAlmostEqual(len(trc), seconds/delta, 1)
585
586def suite():
587#    return unittest.makeSuite(commandsTestCase, 'test')
588    return unittest.makeSuite(commandsTestCase, 'test2')
589
590if __name__ == "__main__":
591    unittest.main(defaultTest='suite')
Note: See TracBrowser for help on using the repository browser.