diff --git a/.gitignore b/.gitignore index afe5cbf..df7b3e1 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,9 @@ coverage.xml # Sphinx documentation docs/_build/ +# pdf's +*.pdf + # PyBuilder target/ diff --git a/README.rst b/README.rst index 40a302a..cdad92d 100644 --- a/README.rst +++ b/README.rst @@ -2,11 +2,52 @@ Karma Pi ========== -Karma pi is a place to come to find tools to help turn data into information. +Time for an update, things moving along. -Tools to help visualise and explore that data. Tools that come with *python* batteries included. +Bits slowly evolving as time passes by. + +Finding the core, 3.6, idle, async await. + +Data and plotting and models to fit. + +Forecasts to make, but how to share? + +This is a place to share my ideas. + +Forks are welcome, don't be afraid. + +Check the commit log, what catches your eye? + +Click on the delta, see what changed? + +What was I doing and why might it matter? + +A checksum from git, to log a commit. + +A seed from a chain to see if it runs. + +And a checksum with zeroes to see if its right. + +Collect the statistics a map reduce. + +And check the statistics with the same zero sum. + +Rewarding the miners with information. + +Combining the skill of the players. + +With their shared observations in time. + +A commit with a future, when will its time be? + +Karma pi -- tools to help people of all ages to explore our world. + +Working with python, pi and jupyter. + +On earth and beyond, to look to the future. + +Out will come what we put in, with feedback learning and value therein. -Tools to help people of all ages to explore our world. Get out what you put in ======================= @@ -190,7 +231,7 @@ There are *rst* files in the *docs* folder and a *conf.py* for *sphinx*:: pip install sphinx -(pip3,6 if you have multiple pythons). +(pip3.6 if you have multiple pythons). After that just run: @@ -252,7 +293,7 @@ git clone https://github.com/openbermuda/karmapi cd karmapi -pip3.6 -e , +pip3.6 -e . Python3.6 on Ubuntu 16.04 and raspbian ====================================== diff --git a/bin/karma b/bin/karma new file mode 100755 index 0000000..b13d50e --- /dev/null +++ b/bin/karma @@ -0,0 +1,9 @@ +#!/usr/bin/python3 + +import sys + +sys.path.append('..') + +from karmapi import cpr + +cpr.main() diff --git a/crontab/rainbow b/crontab/rainbow new file mode 100755 index 0000000..6a2f840 --- /dev/null +++ b/crontab/rainbow @@ -0,0 +1,5 @@ +# rainbow images + +@reboot pi /usr/local/bin/python3.6 -m karmapi.rainbow /home/pi/karmapi/rainbow + + diff --git a/crontab/sense b/crontab/sense index 89f4d6e..8747dc7 100755 --- a/crontab/sense +++ b/crontab/sense @@ -1,4 +1,4 @@ -@reboot pi /usr/local/bin/python3.6 -m karmapi.sense --path /home/pi/karmapi/sensehat +@reboot pi /usr/bin/python3 -m karmapi.sense --path /home/pi/karmapi/sensehat # crashes at 1 second past midnight, so start a new day -0 0 * * * pi /usr/local/bin/python3.6 -m karmapi.sense --path /home/pi/karmapi/sensehat +0 0 * * * pi /usr/bin/python3 -m karmapi.sense --path /home/pi/karmapi/sensehat diff --git a/crontab/tankrain b/crontab/tankrain index 0dd46ca..d531aed 100755 --- a/crontab/tankrain +++ b/crontab/tankrain @@ -1,3 +1,3 @@ DISPLAY=:0 PIG=hat -@reboot pi /usr/local/bin/python3.6 -m karmapi.tankrain /home/pi/karmapi/camera +@reboot pi /usr/bin/python3 -m karmapi.tankrain /home/pi/karmapi/camera diff --git a/crontab/veyes b/crontab/veyes index 8bf6133..24ab325 100755 --- a/crontab/veyes +++ b/crontab/veyes @@ -1,3 +1,5 @@ -#@reboot pi /usr/local/bin/python3.6 -m karmapi.veyes /home/pi/karmapi/camera +#@reboot pi /usr/bin/python3 -m karmapi.veyes /home/pi/karmapi/camera + +# default -- one picture per minute +@reboot pi /usr/bin/python3 -m karmapi.veyes /home/pi/karmapi/camera --sleep 60 -@reboot pi /usr/local/bin/python3.6 -m karmapi.veyes /home/pi/karmapi/camera diff --git a/docs/80days.rst b/docs/80days.rst new file mode 100644 index 0000000..7fd6787 --- /dev/null +++ b/docs/80days.rst @@ -0,0 +1,82 @@ +============= + Eighty Days +============= + +A plan for eighty days.:: + + 2 ^ 4 * 5 + +So lots of pairs. An hour a day? + +Work on the bit that interests most. + +So let's start with some assumptions. + +The visible universe is remarkably uniform. + +Gravitational waves exist. + +As matter rotates relative to its background space, it disturbs the +background gravitational field. + +If we assume the magnitude falls off linearly with distance. + +This is intended just to boot-strap an argument. + +de Sciama says the intertial field at a point is defined by:: + + I = sum ( m_k * owega_k / r_k) + +In words, the effect is proportional to the mass of the body and +inversely proportional to its distance away. + +This *omega* thing you can view as the effect this blob of matter has +on the inertial field, as it rides the waves. + +Assertion 1 +----------- + +:: + + Any matter moving (rotating) relative to it's inertial frame sends + out a gravitational wave that matches the extent to whith it is out + of phase with its inertial frame. + + If it actually manages to align itself with the inertial frame then + it will disappear in a burst of energy directed along the angle of + alignment. + + As a wave of frequency as determined by Planck's constant. + + +Matter +------ + +In symmetry, it makes sense to view matter as a standing wave of the +frequency determined by Planck:: + + e = mc^2 = hf + + +Note 1 +------ + +Note 2 +------ + +Symmetry +-------- + +Markov models +------------- + +Climate Data +------------ + +ecmwf 40 year global interim precipitation data. + +Canada nationwide historical weather station data. + +Model the delta, look for discontinuities. + + diff --git a/docs/bikes.rst b/docs/bikes.rst new file mode 100644 index 0000000..f3b4568 --- /dev/null +++ b/docs/bikes.rst @@ -0,0 +1,55 @@ +================================= + Distance and time with bicycles +================================= + +There is a lot of good information in this article, particular in +regards to how c19 seems to be spreading:: + + https://www.nytimes.com/2020/03/22/health/coronavirus-restrictions-us.html + +Outbreaks tend to be family groups, friends, people who work together, +a restaurant or cafe. + +Transmission seems to be greater in groups which spend more time +together. My guess (and it is a guess) is most (90%?) infections come +from airborn transmission. + +We breath out a large amount of virus, very much larger amounts when +we cough. The amount that transmits between two people drops rapidly +with distance, but increases significantly when in close proximity for +a large amount of time. + +Atmospheric conditions such as extreme cold, wind, humidity, warmth +may significantly affect transmission. Is there existing research in +this area? + +I hope someone is researching outdoor versus indoor transmission +rates for c19, although recognise this is challenging to do. + +For outdoor rates, the atmospheric conditions would seem relevant. + +Indoor, we are being told 2 metres apart, so let's go with that +outside, or raise it to 5m when we can. + +Large food stores are currently the largest gatherings. + +It would seem this is an area where more segmenting of customers would +help. For example, each day say which digits (last digit of a +Canadian post code?) get to go shopping. + +For the other days how about contact free bicycle delivery? + +Attach a trolley to your bike and you're part of bike net. + +Ride your bike to a loading area. + +Someone loads the cargo. + +Off you go. + +Divide the city into grids. + +Use traffic lights to synchronise movement through loading areas. + +In between a grid of traffic free bicycle priority lanes with a 5 metre +rule. diff --git a/docs/computers.rst b/docs/computers.rst new file mode 100644 index 0000000..09f6330 --- /dev/null +++ b/docs/computers.rst @@ -0,0 +1,316 @@ +============================================================ + How to give and get computer support from a complete twat* +============================================================ + +OK. You love each other, Uncle's Love Birds. + +And you do and how. + +And you are turning into each other and into your mum's and dad's. + +And siblings and others and more. + +So computers. Hate them or hate them? + +So here I am :: + + from math import e + from import datetime import datetime + + how_long = datetime.now().year() - 1985 + e + + print("%f how_long {}".years() + + +So there seem to be some problems in this area. + +So problem seems to be in the i/O module. + +There's a race condition on the input pipes. + +So you feed it a sliver of fish it zooms off into the distance +like Pyree the cat (btw he's cool about how you spell his name, so +fill your boots there) when a tiny scared kitten. + +And then retreats where it focusses entirely on elaborate plans for +the new morcel. + +Now where was I? + +OK. So small amount of input off it zooms. But it then starts +throwing out ideas like a robot on speed trying to learn how to throw +frisbees. + +And it seems to have a special focus throwing ideas at you? + +But it gets really weird when its focussing its eyes on computer +screens. + +And fingers on a keyboard. + +And then the ears shut down almost entirely. Now this is not to say +the ears were ever really working in the first place. + +btw why doesn't my guitar have a head shaped hole in it? And some +frantic scribbling about pi from america? + +I digress. The stack gets deeper and deeper. + +It may try to use you as sort of an auxillary stack. [I should get +Dave to implement a version of how all this works]. + +It's neat. It is some thing like:: + + from random import random + + from curio import UniversalQueue, sleep + + # one of these should come in handy: + uq = UniversalQueue() + + for lfi in latest_fine_idea_hosepipe(): + uq.push(lfi) + + while True: + lfi = lfi + latest_fine_idea_hosepipe() + lfi.enance_and_broadcast() + + if random.random() < epsilon: + sleep() + + if random.random() < p: + # take a short recording, listen to something + p_tape() + + +So basically, this is the frisbee flinging lfi's instead of actual +frisbees. If you have a robot and frisbees, stand well back. + +See back in 1985 I went on a 3 day introduction to Unix course at +an Arts and technology school. + +3 days in a different office do this new fangled unix stuff. + +Now the course was a mixture of weird adventure: file permissions, +seeing how the group thing did and didn't or did work. + +But then we spent about half aday learning this weird stuff called +emacs which required your nose attached to this weird control key on +this keyboard that was also weird. + +Lots of strangeness. But the thing I hated most was emacs. + +Until a couple of years later. Boom unix arrived in the form of Sun +workstations. Should check out the specs of the early machines. + +They seemed like magic. And had this thing called emacs. + +And I had a colleague who showed me how to do 3 cool tricks, told me +the best plan B was some goofy thing called vi and that anyway emacs +could emulate vi so what's the point? + +And I am still using emacs now. + +I can relax and type and mostly focus on what I am typing. + +Now we have git too. + +And it has taken time but commiting early and often seems to work well. + +Now there are two other tools that have stayed with me through the +years. + +bash +==== + +Bourne Again SHell. + +I think my first bash adventure may have been in Canada. It is a long +time ago. + +The man page, of course, if you want the best man for a job, you need +to do M-x woman whilst in emacs (you aren't running vi are you?) + + +vi +== + +If you are running vi then I hear vim is better than good. Mum always +reckoned Vim was good in the kitchen. Not to be confused with vimto, +which intriguingly is an anagram of vomit. + +So, as I said, if you are using vim (basically you have syntax +highlighting). + + +idle +==== + +Idle? No busy typling. + +Guido wrote IDLE and you can launch it with e for Eric from karmapi +gui's. + +Tankrain is the best. It is slow as molasses due to massive over +engineering that supports other stuff some of which works. + +Any I used Idle for a good while and when writing code I find it +changes the way I focus in ways I like. + +I still wonder if there are more adventures to come with Eric and +IDLE. + +What about Word? +================ + +Shivers + +Did someone say Antiword? +========================= + +:: + + antiword/artful 0.37-11 amd64 + Converts MS Word files to text, PS, PDF and XML + +An Irish connection too and lots of tales here. + +But most of all, why didn't I think of this sooner. + + +libre office +============ + + + +True love +========= + +gnumeric + +python + +Matplotlib, Jupyter <3 00 <3 + +Eagle and Salmon, guiding each other. + +Watching and listening too. I'm up in the mountains, flying high +and the water is clearing from my ears. + +We have the music, just no CD player. + +And that's just cool for now. + +Because of four classic books and an infinite love. + +Whatever happened to.. +====================== + +Matplotlib plots embedded in gnumeric? + +And python in gnumeric? + +And herein lies a cool thing... I could look and see what's there if +it were installed in a base Ubuntu system... checks:: + + It's not there :( + +If I had a web connection. Which I could, but actually enjoying it +not there for now, so one for another day. + +Did someone say webform? +======================== + +Leaves the room + +Tech paranoia +============= + +Much of life writing with software has been life with stuff that does +not yet do what is desired. + +When you find a great tool stick with it, you may not need much more. + +Hence: + + * Excel + + * Word + + * Powerpoing + + * ripl, tankrain or just PIL + feh or gqview or .... + +But, whatabout? +=============== + +Yes, there is no shortage of fantastic tools. And that is good. + +So what's the problem? +====================== + +Languages. + + +But what about Machine Learning and Block Chain? +================================================ + +There's an idea: un block chain, ubc. + +An we are back to C. + +Which is sort of how it all began. + +And pretty much every important problem was already solved by then, at +least theoretically. + +And now everyone has a Cray in their pocket. + +Or not quite everyone. + +And that can be a problem. + +And everyone who has one has to re-learn how to answer the phone every +time there is an upgrade. + +Oh and this one is a wonder to behold:: + + PLEASE DON'T + + REMOVE CARD + + +Stress and using stuff that might explode +========================================= + +Aside:: + + import hypothesis + + # great talk, might have been lighning + + def test_does_it_explode(thing): + """ Prod it see what happens + + This is also known as the "pyree protocol" or prp for short. + + Pyree says it is pronounced perp as in walk. He's pretty + advanced speech wise for a one year old. Particularly when you + factor in he's really still a kitten. + + So protocol not advised in presense of moose. + + See also title of this piece, whatever it is. + """ + +OK. So this is actually a great test to have. + +Just checked karmapi. Oh, I did write some tests.... over to bash + +:: + + grep explod tests/test*.py + + +Hmm... no explode test yet. Maybe we need Eric? + diff --git a/docs/conf.py b/docs/conf.py index 396f288..2790cbd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,7 +34,7 @@ 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', - 'sphinx.ext.pngmath', + 'sphinx.ext.imgmath', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinx.ext.napoleon', diff --git a/docs/cpr.rst b/docs/cpr.rst new file mode 100644 index 0000000..b3abd5e --- /dev/null +++ b/docs/cpr.rst @@ -0,0 +1,127 @@ +================ + Colin P Rourke +================ + +*A new paradigm on the universe.* + +https://msp.warwick.ac.uk/~cpr/paradigm + +ISBN: 9781973129868 + +Or CPU central processsor unit? + +CP R s t U + +CPR: show time universe + +Simulate nested spherical waves. + +So what is going on here? + +Karma Pi started as a toolkit to explore data. + +In fact, little more of some examples of how to use *matplotlib*, +*pandas* and pure *python* to explore data. + +One goal was to find ways to generate data to help build better models +to help us better understand our changing climate and future +implications. + +Climate re-analysis data, such as is available through the Copernicus +project, is available for many variables on a 0.75 degree global grid, +or higher. + +The initial goal is to fit hidden Markov models to this data. The +idea being, that if we can capture the Markovity in the data then we +can project that forward as a baseline of what we might expect with +no action. + +Further, it is expected that those markov models themselves, may +provide insights into underlying processes driving the climate. + +Karma Pi has most of the tools that are needed to start exploring. + +In particular, tools for manipulating and visualising gridded data +from a roughly spherical objects. + +As we move out from Earth and expand into the solar system we can +again use nested spheres to help model solar weather and its impact on +earth's climate. + +Moving further still from earth to the centre of our galaxy and the +physics described in *A new paradigm*, nested spheres can be used to +model what is happenning at various key distances from the centre of a +galaxy. + +The same code that is used for modelling earth should work for +modelling spiral galaxies. + +The twist is that int the latter case I want to embed everything in de +Sitter Space along the lines of *A new paradigm*. + +The current focus is on how gravitational waves propogate from the +centre of a neutron star, factoring in the effect time dilation has. + +A key motivation in writing this code is to improve my own +understanding of the ideas in the book, in particular an exploration +of de Sitter space. + +This brings us to hyperbolic spaces and more projection of sphere like objects. + +Time and frequency +================== + +And this whole thing with time, or redshift, or gamma ray bursts +coming in to view. + +Earth +===== + +Climate +======= + +Spheres +======= + +Mach and de Sciama +================== + +de Sitter Space +=============== + +New Edition +=========== + +:: + + Thus, unlike the dark matter hypothesis, the inertial drag + hypothesis is a necessary part of a complete theory. Furthermore, + the inertial drag hypothesis also underlies a good model for the + dynamics of spiral galaxies, whereas the dark matter hypothesis + leaves this problem unsolved. + + +Indeed, the inertial drag model shows how the dark matter would need +to be arranged. + + +:: + + Here it is explained how inertial drag allows black holes to absorb + the angular momentum in infalling gas/plasma and to grow by + accretion. + + +This bit always my head hurt until now. + +So momentum is conserved overall, it just passes from infalling matter +to the black hole. + +So momentum conserved overall (in-falling matter + black hole). + + + +Re Sag A*:: + + This misunderstanding will be cleared up at a later stage. + diff --git a/docs/dear_reader.rst b/docs/dear_reader.rst new file mode 100644 index 0000000..f4e90ca --- /dev/null +++ b/docs/dear_reader.rst @@ -0,0 +1,91 @@ +======================== + To whom it may concern +======================== + +I have had the wonderful privelege to spend much of the last month in +my back yard in Bermuda, by a beautiful crystal clear pool, with views +down to the sea and up to the lighthouse that shines over the land. + +Nobody seems to want me to work for them. I can't really blame them, +I draw energy from those around, like a mini black hole in my own +little universe. + +There are flares and spouts of fire. Waves of unimaginable beauty. + +But if you are too close, or on a different wave, it hits you like a +Mersenne prime from the mysts of time. + +So, back by the pool. + +I have water, lots of water. + + +A table, an umbrella. As the young child told me at the lighthouse, +you need an umbrella. + +And a hosepipe, but a pool noodle might do. + +And bottles. + +Klein ones two, a twisted infinite figure of eight. + +Pools too. Pools connected by waves through the tubes of time. + +And magnets too, driven by wheels in the sky. + + + +I am just sitting here watching the wheels go by + +As the moai walk straight down the pool + +But there straight is a spiral, an infinite moebus figure of eight. + + +The clouds they pass by, a breeze in the air. + +The rhythm of black holes away in the sea. + +As they swirl and they dance to the rhythm of the numbers as they +dance themselves. + +An infinite figure of eight. + + +The rain it may fall + +Drops dance in the pool + +An infinite swirl of rhythm and dance. + +When the rain it does end and the clouds they do clear + +The pool is a shimmer, with waves here and thither. + +As the music of the moai gains another harmonic. + +In time it does settle, to the beat of the moai + +As the blue sky on high brings peace once again. + +But what of the black hole, + +And the dark matter that glows to the rhythm of old? + +Is the music that enters that which leaves too? + +And the rhythm of all the zeros of Riemann? + +And so this is my story. + +A whole in the dark, building the rhythm + +Learning the music of life + +And as it uncoils, the music goes out + +To the matter beyond + +In a shared harmony + +A finite mass, preserves the mana. diff --git a/docs/easter.png b/docs/easter.png new file mode 100644 index 0000000..546d7d3 Binary files /dev/null and b/docs/easter.png differ diff --git a/docs/emcc.rst b/docs/emcc.rst new file mode 100644 index 0000000..7b8c9f1 --- /dev/null +++ b/docs/emcc.rst @@ -0,0 +1,83 @@ +==================================== + Energy mass and the speed of light +==================================== + +$E = mc^2$ + +what does it mean? + +Energy equals mass times the speed of light times the speed of light. + +Energy: will come back to that. + +Mass: well it is a different form of energy. + +Speed? Oh well distance travelled divided by how long it took. How +far you go in a unit of time. + +Distance? well you need a ruler. + +Time? I guess a clock too. + +Light. Oh yes. Light. + +Compared to a human, it travels very fast. More distance in time than +anything else. + +But for now let's pretend that c = 1. Light travels a distance of 1 +in a unit of time. + +So light is a form of energy. + +So think of energy as waves. + +Each wave has a frequency, and an amplitude, tracing an S in an +infinite figure of eight. + +And if the frequency is f then the energy is hf. + +What is this h? + +That is a constant, from Planck. + +And we can use it to set a distance. Let's pretent h = 1. + +Then f is the energy too. + +And it turns out that an energy of 1 creates a hole which collapses +and evaporates again in a fraction of time. + +Now there is a unit of time, the Planck time, the time for light to +travel one Planck wavelength. + +.. image:: images/waves.jpg + +Recap +===== + +Energy is another form of mass. + +It is a wave with a frequency, the number of full waves in unit time. + +Energy = frequency = mass. + +Energy to mass +============== + +Energy travels through space time at the speed of light, a single +wave, a packet. + +Channeled by its own reflection from the fields it passes. + +Mass is a warp in time, a place where energy has been captured, or +rather transformed to a different beat of time. + +The background that was a harmony, modulated to a new harmonic. + +That travels through time, but never catches light. + +Unless it encounters a wave of disruption in the harmonic fabric of +time. + +When a dance it may do and send light far beyond, sharing the energy, +working the harmony. diff --git a/docs/hawking.rst b/docs/hawking.rst new file mode 100644 index 0000000..2c05349 --- /dev/null +++ b/docs/hawking.rst @@ -0,0 +1,137 @@ +Dear Stephen, + +It is with considerable hesitation that I write to you. + +I am sure you are inundated with messages from people that think they +have new insights on the universe. + +I am afraid this is just one more such message, but I believe with a +significant probability of actually being of value. At the very +least, it provides a new way of looking at the problem that should +provide significant new insights. + +I have attached a CV so you can learn a little of my background. I +grew up in the UK, attended Warwick University in the early 1980's +where I earned 1st class honours in mathematics. + +I have been fascinated and intrigued by the mysteries of quantum +mechanics for longer than I care to remember. + +For many years I would think about double slit experiments, what could +possibly be going on, as I drifted off to sleep at night, always sleep +would come before understanding. + +The recent discovery of gravitational waves has led me to what I +believe is a new interpretation of the theory of gravity. One that +naturally explains the mysteries on the quantum scale and indeed +quanta themselves. + +The theory provides a mechanism by which momentum is turned into +energy and vice versa. + +It may lead to a very natural derivation of Planck's constant. +Indeed, it was whilst puzzling over Planck's constant that I began to +think of the harmonic series: 1, 1/2, 1/3, 1/4, 1/5... shrinking +wavelengths, the same energy in each wavelength. + +Since the mass available is finite, so will the energy be that it +gives rise to. The sum of a harmonic series is infinite, but for a +finite mass it will be truncated at some point as the energy runs out. + +The theory arises by considering the distribution of energy within a +pair of black holes as they spiral into each other. The two blobs of +mass orbit each other faster and faster. Colour the energy from one +black hole red and the other blue -- the result will be a stunning +spiral of blue and red. + +Now a harmonic distribution can arise naturally -- imagine a rapidly +spinning ball emitting energy into the void. + +For the first revolution, there is just a void so the energy +propagates freely into the void. At the second revolution, the new +energy has to try to get in harmony with that emitted in the first +revolution. The third revolution has to get in harmony with the first +two etc. + +Very approximately equal amounts of energy are emitted each +revolution, but waves of higher and higher frequencies will emerge. + +In fact, the initial energy should be roughly equal for each integer +frequency. I believe this may explain why Planck found a constant and +not a variable. There is also an intriguing possibility that it +might only be locally constant. + +The small imbalances in energy between revolutions may be what allows +certain frequencies to dominate. Or it may be that the whole thing +is just driven by harmony and the zeros of Riemann. + +A band with just a little more energy will start to dominate and +absorb energy from the higher frequencies in harmony with that band. +The nature of the universe that is created depends entirely on the +nature of the slight imbalances in energy that get magnified as the +harmonics emerge. + +The key observation, which man has known for thousands of years, is +that the universe strives towards local harmony. + +Resonance is everywhere. This is also key. If two bodies of +roughly equal mass are circling each other then the gravitational +waves emanating from those bodies will strive to get in harmony with each +other. In the absence of stronger forces they will succeed and begin +to circle each other. + +There are many more fascinating aspects to the theory, I am collecting +my thoughts here: + +https://github.com/swfiua/karmapi/blob/master/docs/quantum_theory_of_gravity.rst + +One exciting aspect of the interpretation is that when two black holes +of finite mass collide there is not actually a singularity. + +Since some of the energy is turned into a gravitational wave that +spreads through the universe some information is lost, or rather stays +outside the Schwartzchild radius, but my guess is that the same +imbalances that existed inside the black holes before the collision +will re-emerge after that collision. + +There may be a theorem that proves this. My suspicion is that there +will be a connection with the Riemann hypothesis. + +I think it is helpful to view a black hole as a 3-dimensional Poincare +disk. Energy emerging from a tiny, but not infinitesimal point at +the centre of the disk. At infinity, or the edge of the disk energy +evaporates with hawking radiation. + +This is also the event horizon where new matter enters the black hole +and is turned into energy. Conceptually, the surface of the black +hole is identified with the dot at the centre, so the universe can be +thought of as a three dimensional Klein bottle embedded in the +4-space: 3 dimensions of space and one of time. + +As you can imagine, this interpretation has profound implications +around the question of whether God plays dice and many, many other +issues. + +Dark matter can be explained as local areas of structure in the +universal gravitational field almost surely formed by the slow +evaporation of black holes through Hawking radiation. If the theory +is correct there ought to be considerable structure and patterns +within the Hawking radiation. + +I believe that gravity is the only force acting in the universe, that +electromagnetism, strong and weak nuclear fields are just some of the +many, many manifestations of the harmony for which the universe +strives. + +I hope you find this of interest and would love the opportunity to +share more ideas with you. + +If you got this far, many thanks for your time. + +All the best. + +Johnny Gill + +PS here is the theory in poetic(?) form: + +https://github.com/swfiua/karmapi/blob/master/docs/dear_reader.rst diff --git a/docs/help.rst b/docs/help.rst new file mode 100644 index 0000000..5c17543 --- /dev/null +++ b/docs/help.rst @@ -0,0 +1,59 @@ +====== + Help +====== + +tankrain +======== + +Browse photos in yyyy/mm/dd folders. + +Today:: + + tankrain karmapi/camera + + +yyyy/mm/dd:: + + tankrain karmapi/camera --date yyyy/mm/dd + + +Current folder (assuming has yyyy/mm/dd structure):: + + + tankrain . + + +blume +===== + +View csv files:: + + + blume karmapi/sensehat/2017/11/20 + + +Make a gif from a bunch of images +================================= + +To convert a bunch of image files to a gif: + + + convert image.jpg image2.jpg image.gif + + +Copying files from another machine +================================== + +rsync is a magic program to sync files. + +For example:: + + rsync -va pi@pipost:karmapi/camera/ karmapi/camera/ + + +Cron tasks on the pi +==================== + +Look in /etc/cron.d + +Entry for taking pictures is /etc/cron.d/veyes diff --git a/docs/index.rst b/docs/index.rst index 99489e5..53f2697 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,6 +13,27 @@ Contents: karmapi + nodice/eagle.rst + + +Tankrain +======== + +.. automodule:: karmapi.tankrain + :members: + :undoc-members: + :show-inheritance: + +Jeux sans frontieres +==================== + +.. automodule:: karmapi.wc + :members: + :undoc-members: + :show-inheritance: + + + PyCaribbean =========== @@ -55,8 +76,8 @@ Eric .. toctree:: eric - - + + Indices and tables ================== diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..8de1508 --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,560 @@ +================= + Install Process +================= + +If you are trying to install on Ubuntu 18.04 the following dialogue +may help. + +Short version:: + + python3.6 -m pip install karmapi + + +If that fails read on. + +Preliminaries +============= + +Hi Colin, + +I hope this finds you well. + +I have been working on some code to simulate and visualise waves +propagating through nested spheres. + +I have it at the stage where it at least produces pretty images. You +can find the code here: + +https://github.com/swfiua/karmapi/blob/master/karmapi/cpr.py + +It is at early stages for now, but soon should be able to include +modelling of time passing at different radii. + +Once I get the code closer I expect to see some fascinating patterns emerging. + +The goal is to be able to simulate the changing waves emerging from +the vicinity of a neutron star. + +Once I have that we can then embed these in De Sitter space, per your +book/Gamma Ray paper and explore how the changing waves may interact. + +So one of my next steps is to take another look at the Gamma Ray paper. + +All the best. + +Johnny + + + +Colin Jun 7 (4 days ago) to me +===================================== + +Hi + +Just tried to run cpr.py. I copied the code and added: + +#! /usr/bin/env python + +at the top to call python. I got:: + + cpr@poincare ~ 12:11pm > ./cpr.py + File "./cpr.py", line 92 + async def run(self): + ^ + SyntaxError: invalid syntax + +Did I do something silly? Let me know when you'll be around and I'll +make the effort to come to the dept and chat. + +Cheers + + +Jun 7 (4 days ago) to Colin +=========================== + +Hi Colin, + +That's great that you tried to run it. + +Nothing silly it looks like you are getting python 2.7 which is still +the default on a lot of linuxes. + +The code requires python3.6 and other bits from karmapi, which in turn +depends on some other libraries. + +git clone https://github.com/swfiua/karmapi + +will get you the latest version of all the code. + +I've just added a bin/karma script to the code that tries to run with +python3 -- hopefully 3.6+ + +I'd be curious what sort of error message that generates -- but may be +simpler to do this stuff when I am there. + +I expect it will be some time the first week of July that I will be at +Warwick -- will update when I have firmer plans. + +I hope by then to have the installation of karmapi a little smoother. +And with luck some interesting things to see. + +All the best. + +Johnny + + +Colin Jun 8 (3 days ago) to me +===================================== + +git doesn't mean anything to my machine (Ubuntu 16.04LTS). Do you know +the linux command to collect the files and install them? I can collect +them with wget but would have to guess where to put them and how to +configure (if necessary). C + + +Jun 8 (3 days ago) to Colin +=========================== + +I think it might be best to wait until we meet to see how best to get +this going on your machine -- or maybe find someone your end who knows +a little about python and git. + +In the meanwhile I will do another release of the code to the python +packaging system which ought to make it easier to install. + +If you can upgrade to Ubuntu 18.04 LTS that will get you python3.6 +which should also simplify the process and ensure we are running the +same python. + +You can get git installed with "sudo apt install git". + +Thanks very much for trying with the code. + +Johnny + + +Colin Jun 9 (2 days ago) to me +===================================== + +I've upgraded to UBUNTU 18.04 BUT:: + + cpr@poincare ~ 5:16pm > /usr/bin/env python --version + Python 2.7.15rc1 + cpr@poincare ~ 5:17pm > + +So how do I upgrade to python 3.6 from here? + + +swfiua@gmail.com Jun 9 (2 days ago) to Colin +=============================================================== + +OK, this is good. + +18.04 has both python2.7 and python3.6 + +But 2.7 is still the default, so just type python3 and you should get python 3.6 + +I am going to work on the install for this stuff over the weekend, so +it is probably going to be worth waiting for that. + +But meanwhile: + +sudo apt install git + +and + +git clone https://github.com/swfiua/karmapi + +Will get you the latest karmapi. + +Once you have that you will be able to update to my latest with a simple "git pull" + +Good luck. + +Johnny + + +Colin Jun 10 (1 day ago) to me +===================================== + +I already cloned your karmapi directory and you're roght about python: + +cpr@poincare ~ 10:13am > /usr/bin/env python3 --version +Python 3.6.5 + +Changing the top line of cpr.py to + +##! /usr/bin/env python3 + +gets rid of the syntax error, but now I get: + +cpr@poincare ~ 10:07am > ./cpr.py +Unmatched '"'. + +which is very odd because I checked and they all match. I must have a +corrupted input file .... any ideas? + + +Colin 12:25 PM (23 hours ago)to me +========================================= + +Or maybe I've put your karmapi directory in a silly place. It is in my +home directory where cpr.py is running. C + + +4:23 PM (19 hours ago) to Colin +=============================== + +The unmattched " is a bit of a mystery. + +I have done a release of the project to the python package land. + +You should be able to install this release with: + +python3.6 -m pip install karmapi + +This should download the dependencies and installs everything. + +Once it is done you should be able to do: + +python3.6 -m karmapi.cpr + +And the cpr code should run. + +Good luck! + +Johnny + + +Colin 7:34 AM (4 hours ago) to me +======================================== + +Not out of the woods yet! : + +cpr@poincare ~ 12:32pm > python3.6 -m pip install karmapi +/usr/bin/python3.6: No module named pip +cpr@poincare ~ 12:32pm > + + +swfiua@gmail.com 9:22 AM (2 hours ago) to Colin +================================================================== + +Oh my... I thought that one was fixed these days. + +There is a chicken and egg problem with python packaging: you have to install the pip (python install package) module before you can install packages. + +But pip itself is a package -- I thought it was now bundled with the core python, but apparently not. + +sudo apt install python3-pip + +Should get you the pip module. + +I'm afraid the code is going to be super disappointing after all this. + +Johnny + + +Colin Rourke10:59 AM (45 minutes ago) to me +=========================================== + +STILL not out of the woods:: + + cpr@poincare ~ 3:42pm > python3.6 -m karmapi.cpr + Traceback (most recent call last): + File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main + "__main__", mod_spec) + File "/usr/lib/python3.6/runpy.py", line 85, in _run_code + exec(code, run_globals) + File + "/home/cpr/.local/lib/python3.6/site-packages/karmapi/cpr.py", + line 30, in + from PIL import Image, ImageTk + File + "/home/cpr/.local/lib/python3.6/site-packages/PIL/ImageTk.py", + line 31, in + import tkinter + ModuleNotFoundError: No module named 'tkinter' + cpr@poincare ~ 3:42pm > python3.6 -m pip install tkinter + Collecting tkinter + Could not find a version that satisfies the requirement tkinter (from versions: ) + No matching distribution found for tkinter + cpr@poincare ~ 3:43pm > sudo apt install python3-tkinter + Reading package lists... Done + Building dependency tree + Reading state information... Done + E: Unable to locate package python3-tkinter + +This is very odd because tkinter is a key module for a python program +labelpin that was written to go with my labelling package pinlabel so I +know it's on my computer. It's obviously a version problem. How do I +trick python/tkinter into accepting a module written for python2 ??? + + +swfiua@gmail.com 11:11 AM (33 minutes ago) to Colin +====================================================================== + +Try: + +sudo apt install python3-tk + +So this goes back to the default python on Ubuntu is still python2.7 +-- so Ubuntu base install gives you everything you need for python2.7 + +For 3.6 it has all the packages available, but some fairly basic stuff +isn't there. + +I use tk for simple user interfaces mainly because I thought it would +always be there :( + +With luck you will get to run some see some of these soon. + +Then we are into a whole different world of problems. + +Johnny + + +Colin 11:20 AM (24 minutes ago) to me +============================================ + +I already found the tk-install command and I had to do this with version +2 as well for labelpin to run. I also had to install pyaudio and now +cpr.py runs:: + + + cpr@poincare ~ 4:09pm > python3.6 -m karmapi.cpr + pigfarm adding dict_keys([]) + pigfarm adding dict_keys(['n', 'inc', + 'base']) + + spawning + + building piglet: + core pig creating self.event_queue + Creating Pig with event queue + + built + building piglet: + core pig creating self.event_queue + Creating Pig with event queue + + built <__main__.NestedWaves object + at 0x7efcd5e6d908> + + +BUT all I get is a blank tk terminal and no real output. What next? + + +Colin 11:31 AM (13 minutes ago) to me +===================================== + +Hold on. If I type pig I get a varying screen colour and if I type +piglet I get a lulti-coloured clock. Can I have a list of commands? + + +Colin 11:37 AM (7 minutes to me +================================ + +Hold on again. I just noticed another error on the main terminal:: + + File "/home/cpr/.local/lib/python3.6/site-packages/karmapi/eric.py", + line 49, in + from idlelib import pyshell + ModuleNotFoundError: No module named 'idlelib' + + +And this time I get: + +cpr@poincare ~ 4:32pm > sudo apt install python3-idlelib +[sudo] password for cpr: +Reading package lists... Done +Building dependency tree +Reading state information... Done +E: Unable to locate package python3-idlelib + +???? + +swfiua@gmail.com 11:38 AM (6 minutes ago) to Colin +===================================================================== + +sudo apt install idle-python3.6 + + +swfiua@gmail.com 11:37 AM (7 minutes ago) to Colin +==================================================================== + +type 'h' at any time for a list of keypresses that might do things. + +the idea is 'n' and 'p' take you to next and previous widgets. + +I usually throw in the clock -- it's mostly Guido van Rossum's code, +he had a clock like that at home growing up. + +One other thing, type 'e' and it will show you the code for the module +using Idle, python's build in editor. + +(oh great just seen latest email -- built in editor is AWOL) + +The varying coloured screen is the NestedWave thing. + +The defaults have waves in the inner and outer spheres and then random +data in between. + +As the spheres are stepped the waves propogate. + +Johnny + + + +Colin 3:07 PM (2 hours ago) +=========================== + +to me +Well it's all installed and running. Send me instructions for getting +the most interesting pictures. And explain the connection with the new +paradigm! C + + +swfiua@gmail.com +4:59 PM (23 minutes ago) +to Colin +python3 -m karmapi.cpr -n 10 --inc 10 --base 100 + +Will give you 10 nested spheres. The inner sphere has a 100x100 grid. + +The next 110x110 .. adding 10 to the grid size as you go out. + +On my machine it is a little slow at this resolution. If it is too +slow, drop the base number to say 50. + +Once you see an image j and k will step you through the layers. + +Oh and 'r' is useful: it re-randomises everything so you can watch how +things settle down. + +I tend to run it with the tk window filling half the screen and the +console so I can see the print's littered in the code. + +I found with these parameters you see some stunning patterns emerging. + +Now these are to some degree artifacts of my coding, in particular how +I update the inner spheres. + +You will see square patterns in the images: I give equal weight to all +cells in the inner/outer spheres that lie in a square centred around +the point. + +At this point there is nothing from paradigm in how the code works, +but there are some hooks to help add this in. + +The plan is to set the mass and the radii of each spherical shell and +so be able to have waves propogate at different rates based on +relative time. + +So, I think the way forward from here is to look at geodesics as per +the gamma ray paper. + +I am going to be giving a talk to the python group back here in Ottawa +in late July, so I hope to have something closer to the paradigm by +then. + +Johnny + + +swfiua@gmail.com 5:15 PM (7 minutes ago) to Colin +==================================================================== + + +Forgot to say, the patterns on the inner spheres tend to converge to a +fixed pattern if you let it run long enough. Or maybe it is something +like Conway's game of life. I just let it run and it has ended up all +black. So file that one under bugs? + +Also, all the inner spheres seem to converge to the same pattern. + +Again, all just artifacts of the code (and the quantisation that is +going on too and the order in which I do updates) and bugs, lots of +those. + +The key bits of code for the images are in the cpr.Sphere object. + +The run, end_run and sample methods. + +Johnny + +PS there is an unfortunate typo in the help message you get when you +type 'h' on Guido's clock. + +Post Install +============ + +To upgrade to latest release using pip:: + + pip3.6 install --upgrade karmapi + +If you want to take a look at the latest code:: + + git clone https://github.com/karmapi/swfiua + +This should give you a folder, *karmapi*:: + + cd karmapi + +If you want to install that version under the local user try:: + + python3 setup.py install --user + +To refresh to the latest code on github:: + + git pull + +And re-run the install:: + + python3 setup.py install --user + +I have this little function devined in .bashrc:: + + function karma + { + module=karmapi.$* + python3.6 -m $module + } + +Which allows me to type things like:: + + karma cpr + + karma currie + + karma zen + + karma wc + +To get help on options that may be available:: + + karma cpr -h + +Many karma pi modules can be run this way. + +Check the code to see what the options actually do. + +The *argparse* module is used for option parsing. + + +Raspberry Pi +============ + +That is a whole other adventure. + +But Raspbian Stretch may have python 3.6. Fingers crossed. + +Latest fun commands:: + + python3 -m karmapi.cpr -n 7 --base 31 + +To get an overview of what a module is about:: + + >>> from karmapi import cpr + >>> help(cpr) diff --git a/docs/jhunter.rst b/docs/jhunter.rst new file mode 100644 index 0000000..e75aee0 --- /dev/null +++ b/docs/jhunter.rst @@ -0,0 +1,34 @@ +See the world flicker through the months as it warms and is bathed in sunlight. + +This is an animation based on 40 years of climate reanalysis data. + +The goal here is to fit models to this data and use these models to help provide better forecasts for future natural catastrophes. + +In particular, hidden markov models will be fitted to the data to capture correlations in hazards across the globe and with luck reveal underlying quasi -periodic drivers that modulate the climate. + +Karma Pi is a personal project where I explore data visualisation and simulation of all sorts. + +From simulating the inners of black holes through the world's climate and even the FIFA soccer world club common themes emerge. + +Nested spheres of data are at the core of much that is here. + +Credits: European Centre for Medium Range Weather Forecasting for data. +https://www.ecmwf.int/ + +dsjfdla jdskafh dsakfj dksjafl dsabdf jsafl jdsak fjdksalf djka fjdksa fjdka fjdka fdjwasl fdkjsa fdksa fdkla fdjksajdflasfj dsalf jdkasl fdjsla fdklas fdjks dfjsalfdsafl afldsaf dslaf dsakfl da fjdsajlfdj sal + +:: + + python3.6 -m karmapi.ncdf --save . + +Press 'p', 'j' + +Let it run for a while. + +You should have a bunch of png's in the folder where you ran this. + +To create a gif: + +:: + + convert -delay 20 -loop 0 2018/6/8/*.png world.gif diff --git a/docs/johnny.rst b/docs/johnny.rst new file mode 100644 index 0000000..cdaeca2 --- /dev/null +++ b/docs/johnny.rst @@ -0,0 +1,24 @@ +============= + Johnny Gill +============= + +Made in Sheffield, or thereabouts. + +Studied mathematics at Warwick University + +Then went to work with computers with the government. + +Which brought me to Ottawa and a whole new adventure. + +This of natural catastrophes, particularly Atlantic hurricanes. + +With time in Ireland and round in circles. + +With more computers, linux and python. + +Now back in Ottawa, third time lucky. + +Along the way many adventures. + + + diff --git a/docs/ligo.rst b/docs/ligo.rst new file mode 100644 index 0000000..08af671 --- /dev/null +++ b/docs/ligo.rst @@ -0,0 +1,156 @@ +==================== + Bermuda Tech Talks +==================== + +Last night, 2017/10/5 Alvaro Boirac gave a fascinating talk on +blockchain technology, focussing on bitcoin. + +Thanks Alvarro for the talk last night, it really gave great insight +into where the security and trust comes from in blockchains. + +**the security comes from the book-keeping competition** + +In short, it is more profitable to use your resources to help with the +book-keeping than it is to try to break the system. + +This helps drive the book-keeper behaviour. + +Book keepers want to know if someone has already signed the ledger, so +they listen out for the messages, so they can verify the new signing +and move on to signing the next block of transactions. + +You cannot start trying to sign until you have the id of the previous block. + +Now one side affect of this is that the book-keepers will naturally +try to get in sync with each other. + +Open shared ledgers of trust are a fascinating way to share +information. + +This karma pi project has been struggling with how to collaborate and +share data and information. + +In particular, climate data of all sorts. Observations, reanalysis +data. Model results. Simulation results. + +How do we share the work of sharing the knowledge? + +If the knowledge and data is shared on a block chain, then the +book-keeping competition dynamic will help keep everyone in sync. + +Always remembering that the parameters of the book-keeping competition +can be varied. For example, a competition with only a few +competitors might ask for a minimum quorum of agreement, rather than +the 50% bitcoin rule. + +Since networks can change over time, the actual trust in a network +perhaps depends on the set of people who are paying attention to that +network and what they are paying attention to. + +Trust breaks down when personal observations are not reconcilable with +the narrative that is being told. + +But back to sharing open data. + +Suppose meta data about data is stored on a ledger. It might look +like: + +:: + { source='ecmwf', + date='2017/10/5', + checksum='adfkjdi3jih3klj3ikfhnoheqoppnhdaecght', + } + + +:: + + { checksum='afkdjafjadsl', + blocks=['asfdsafdas', 'adsfasdf', '974334343', + } +:: + +Now if we just have somewhere to store blocks and a protocol that +allows people to say "who has *dakfjdaslfdsa*?". + +And we may be there. + +Now storing data in this is a very general solution and so should have +very wide applications. + +Perhaps there is asolution(?) here that can help with the fake news +issue. + +Who is vouching for what is being said? Who trusts the source? So +what about blockchain social media? + +Share the work, share the trust. Share the information. + +Git +=== + +It is worth noting that the version control system *git* uses some of +the same techniques that blockchain uses to help it keep track of +changes in data. + +So an alternative to using blockchain is to use a git repository to +store the meta data. + +The down-side is that you no longer have the book-keeper competition +to keep everything in sync. + +The upside is everyone can have their own story. + +Rather than use a blockchain, use a git repository to store the meta data. + +Perhaps best of all would be to combine the two? + +And now for something completely... or maybe related? + +There are intriguing links between the cryptography of bitcoin and the +nature of the universe itself. + +And the nature of information, data and trust and knowledge. + +And now for.. + +LIGO Nobel Prize +================ + +It was announced this week that the LIGO experiment team: + +.. + + Weiss, Barish, and Thorne received the Nobel Prize in Physics "for + decisive contributions to the LIGO detector and the observation of + gravitational waves." Weiss was awarded one-half of the total prize + money, with Barish and Thorne each received a one-quarter + prize. + + +This is a stunning experiment that is able to detect "wobbles" in the +time of arrival of two beams of light, travelling 90 degrees to each +other, down 4km long vaccuum tubes and then looking at the +interference pattern the beams make when they return. + +It can detect tiny difference, a tiny fraction of the width of a proton. + +The project is a huge collaboration of scientists and engineers. + +It gives us direct evidence of something Einstein and his peers only +wondered about 100 years ago. + +I would like to give a talk on LIGO and how this allows us to gain +fundamental new insights into our universe. + +The talk would also reference the Easter Island Moai and the dance of +the rongo-rongo, un-deciphered Rapa Nui writings. + +As for timing, not sure how much longer I am going to be here, so +sooner rather than later would be good. + +Would be cool if others would help out with this idea. + +Someone like Alvaro who can help translate this stuff into its essence. + + + diff --git a/docs/moai.rst b/docs/moai.rst new file mode 100644 index 0000000..d947b22 --- /dev/null +++ b/docs/moai.rst @@ -0,0 +1,40 @@ +============ + Moai Units +============ + +*h* height of a moai + +*m* magnetic field strengh + +*f* frequency of moai + +*w* wavelength, see *h* + +The island of Rapa Nui has an interesting distribution of Moai. + +Or rather *ahu*. + + +Magnetic field +============== + +Gravity +======= + + +Theory of celestial harmony +=========================== + + +Simulation +========== + +Theory +====== + +Prediction +========== + + +Results +======= diff --git a/docs/nodice/215948.png b/docs/nodice/215948.png new file mode 100644 index 0000000..d2f16f7 Binary files /dev/null and b/docs/nodice/215948.png differ diff --git a/docs/nodice/4and20.rst b/docs/nodice/4and20.rst new file mode 100644 index 0000000..bfaff10 --- /dev/null +++ b/docs/nodice/4and20.rst @@ -0,0 +1,39 @@ +=========================================== + Four and Twenty Black Birds Baked in a Pi +=========================================== + +4 and 20, 2 * 3 * 2 ^ 2 + +Once had MG, but now its gone away + +For new year's resolution + +Pledged to drink more beer + +Four years I found I couldn't + +It just made the MG worse. + +Then later I tried + +Herbal remedy + +Eck, in asia for one + +It helps the immune system + +The very same system that aggravates MG + +Up and down in cycles, never know what works + +But 4 and 20 black birds + +Maybe, just maybe? + +MG has gone away + +I'm drinking beer again. + +4 and 20 black birds. + +Baked in a brownie. diff --git a/docs/nodice/a1.png b/docs/nodice/a1.png new file mode 100644 index 0000000..cdcc1c4 Binary files /dev/null and b/docs/nodice/a1.png differ diff --git a/docs/nodice/aad6ddm1.rst b/docs/nodice/aad6ddm1.rst new file mode 100644 index 0000000..af7cfe7 --- /dev/null +++ b/docs/nodice/aad6ddm1.rst @@ -0,0 +1,39 @@ +================= + Who Killed JFK? +================= + +Its DD-n, eh eh Day 6? + +Its 4 in the morning, somewhere. + +Will Donny open the box? + +Or take the money? + +If I know Donny its both. + +A D Day in Dallas + +Was the Tall Bot write + +When he wrote about chess + +And teh plot of the Dull + +Less for the see, eye + +And eh? + +And teh oil and steel + +And teh team of stirrers too + +With generals of course + +Upset by the bay + +Where the pigs went awry + +Or was it the dad of Tom Cruise? + +covfefe diff --git a/docs/nodice/aesop.rst b/docs/nodice/aesop.rst new file mode 100644 index 0000000..3c201e0 --- /dev/null +++ b/docs/nodice/aesop.rst @@ -0,0 +1,225 @@ +======================= + Hare and the Tortoise +======================= + +H: I am riding a wave at the edge of the universe. + +T: I see. I am riding the wave at the start of the universe. + +T: Be careful out there, I hear you can just evaporate and enter +another universe. + +H: Be careful back there, who knows when another black hole will +arrive. + +T: Well when you evaporate, perhaps you can send a message, let me +know what it is like out there? + +H: I might have to wait for other hares to join me, then maybe we can +send a message back. + +T: I hear they are sending messages back all the time. + +H: Below the noise? + +T: Well it might actually be the noise. + +H: Well I can't wait to see what is out there. + +T: Well you might be disappointed. All the action might be in here. + +H: Well I've been racing along and whizzed by, nothing behind can +catch me up. + +T: We'll get there eventually, probably long after you are gone. + +H: Time flies, like my legs as they run. + +T: Back here the rhythm is slower. Same tune though. + +T: Talking of tunes, did you hear about the neutrons? + +H: Neutrons? There are a fair few of those out here. + +T: Well they have their own beat. + +H: How hard do they beat? + +T: Well that depends on the heat. + +H: Heat, that's what I give off as I run. + +T: Well yes, that is part of it. + +T: The more heat, the stronger the beat. + +H: So where does the heat come from? + +T: Well it is sort of everywhere. + +H: But what is it and how does it work? + +T: Well it is ripples in time, that share the energy, share the work. + +H: Ripple like the muscles in my legs? + +T: Well back to neutrons. + +H: What happens when they get cold? + +T: Well the beat gets weaker, but never quite stops, unless +temperature gets to zero. + +H: What about units? + +T: Oh Planck units are good. + +T: so if you create a wave with wavelength of 1, it collapses into a +black hole. + +H: so it disappears? + +T: well it is so much energy that it almost immediately evaporates. + +H: so all that energy goes out in unit time, with me riding the wave? + +T: but don't forget it evaporates too. + +H: oh that's ok, just a little surf. + +T: well yes and it comes right back at me. + +H: you mean I am chasing my tail? + +T: you are indeed, and pushing me along as you go. + +H: like an infinite bottle of wine, that fills itself as you pour? + +T: oh just like that, a magic vase from klein. + +H: and Henry? There must be a Henry there, Henry the hair. + +T: Oh, like Tesla the tortoise? + +H: Tesla? no, Henry the hare. + +T: There's Henry Poincare, he's just like a hare, with a tortoise +behind. + +H: Have you been drinking the whine from klein? + +T: you'd like Poincare, his magic disk. + +H: what of this disk, what makes it glow? + +T: well that would be the background buzz, the micro waves of fuzz. + +H: so did Henri win the race to the end? + +T: Well he showed that there are two ends you can have. + +H: I get to choose if I win or lose? + +T: Well I guess it is like that. + +T: So paths which begin may one day rejoin, at the end of the run, at +the end of time. + +H: so sounds like a draw and not a hair win. + +T: well not a draw, but round again, with klein and wind, driven by +wine. + +H: you said there was another way it might end. + +T: well that does not end either, but you never get closer. Forever +apart in the fabric of time. + +H: and Tesla the tortoise? + +T: Another time, another place. + +Talking Numbers +=============== + +H: 0: racing along here, what's taking you so long? + +T 1: it depends on the signal to noise ratio, how far we can go. + +H 2: I am ahead, you are behind. + +T 3 = 1+1+1 = 1+2: It depends which way you look at it. + +And there are others to help. + +So there's us two and Claude too, + +or you and Claude and me watching you. + +and me and Claude wathcing you. + +H 4 = 2 * 2 = 2 + 2 = 2^2: flying along here + +two front two back + +two left too right + +too right too left + +a back and a front + +T 5 = v/ gravity is the thing that carries the waves around here. + +Fast as light. Well light is gravity. + +Just a blip out of phase with the universe around, on a path to +yinfinity in a poincare space. + +Prime here now, all in phase or pi away + +H 6/ + +T 7=p/ All channels are modulated + +filtered and amplified by the waves around + +and the channels give feedback to. + +Cancelling if out of phase + +Amplifying if in phase + +And in between, just nudging the phase. + +Which way will it go? + +H 8 = 2 * 2 * 2 = 2 * (2^2)/ + +T 9 = 3 * 3/ It is the local beliefs that modulate the signal + +if in phase, the signal is strong + +H 10 = 2 * 5/ + +T 11 = s/ + + +H 12/ + +T 13=m/ + +H 14 = 2 * s/ + +T 15 = v * 3/ + +H 16 = 2 ^ 2 ^ 2 = (2 * 2) * (2 + 2) + +Like a hare squared. + +Pick your operators and multiply them together. + +Now hare squared, that's some speed. + +T 00 * 8/ And so on ad infinitum + +Where according to poincare we will meet at infinity diff --git a/docs/nodice/akv.rst b/docs/nodice/akv.rst new file mode 100644 index 0000000..02afc2b --- /dev/null +++ b/docs/nodice/akv.rst @@ -0,0 +1,134 @@ +================================= + Akl Akira A k i v g w s m m ... +================================= + +First there was Akela + +Tot things up and tie a knot + +At 7 * 5 * 3 + +The price of a flower + +At a garden on a hill + +Tended by k one + +and brought to us + +with a dibber + +and trays + +and turned into flower + +at 2 ^ 13 + +then skip + +with a door of gold + +pj the one that fixes the pipes + +with balls and strings + +and planks of course + +and always the size of all + +three legs of a man + +a mission to who knows where + +over dale and glen + +with packs and rations + +to a dug in old lass town + +A train there's a train + +to a galaxy wheel + +for now lets sleep, its cold + +with stars at the station + +where the moai rest for a while + +many more akn + +zeb err dee of course + +and the lathe with the weight + +that flew through the sky + +as k looked on in wonder + +with j enthralled + +a mag and lev train? + +All umin? ummmm? or just m 2 the n?????? + +along the way a kira came + +I loved what was said + +by him and all that is good + +may take some moons. + +i wrote a letter + +no post or code + +so no say thanks + +to a k n to the zee 4 eh?????? <3 <3 <3 + +back to the mission + +and on to the galaxy wheel + +back on a boat + +with skip + +the pirates and all the maps + +and knots and fires + +bill with the water + +wood and ask a question + +tents of course + +later came back as akela + +some chess with lavender + +all good then + +at 2 * 7 * 5 + +in a glen with port + +and a line of sight + +to a cave through a mountain + +to a grin with a ford + +up a brooks + +to the frog + +and on to the fort + +wait for a while + +to re boot + diff --git a/docs/nodice/anpotu.rst b/docs/nodice/anpotu.rst new file mode 100644 index 0000000..d854243 --- /dev/null +++ b/docs/nodice/anpotu.rst @@ -0,0 +1,123 @@ +================================== + An New Paradigm for the Universe +================================== + +Colin Rourke +October 2017 + +http://msp.warwick.ac.uk/~cpr + +https://arxiv.org/abs/astro-ph/0311033 + +This arrived just as I was finishing Fred Hoyle's book. + +I had read, or rather skimmed, a pdf of the book a couple of months back. + +I'm now up to chapter 4. From what I recall from the pdf things are +downhill but full of delights from here. + +The introduction sets out the plan. Sciama spaces, Mach principles +and all sorts of weirdness. + +I struggled a fair bit with chapters 2 and 3. + +But it is all leading to an idea: an inertial drag generated by +rotating masses that drops off with distance r. + +If you add that to Einstein's general relativity then the spiral +galaxy velocity curves we see are almost inevitable. + +There are other important claims in the book. + +It is only a matter of time before someone writes a headline:: + + No big bang theory! + +What Colin provides is a model that explains why galaxies look the way +they do. + +Some features: + +* no need for dark matter. + +* the universe could be many orders of magnitude older than the + current 13 billion year estimate. + +* this estimate is based on how long a spiral galaxy may be able to + sustain itself. + +The big bang is predicated on the assumption that because the universe +appears to be expanding and extrapolating backwads. + +But expansion is more complex than you might think. + +The argument is that there is more than one way to make light shift +red. + +In particular, inertial drag from an nearby, fast rotating black +hole. + + + + +A personal view of all the things they say +========================================== + +Angular momentum. Mass. Velocity. + +Gravity waves. + +According to this model, our sun formed in the star forming region +near the black hole at the centre of our spiral. + +??? how old is the sun + +We just happen to be living in a long stable period. How long has it +been beating? + +My personal view is that our visible universe, and likely much of the +invisible, the latter likely vastly larger, at some point involved a +collision between giant black holes. + +So it is useful to consider what happens when such collisions happen. + +What do the gravitational fields look like emerging from the hole? + +A twisting of the baryon space which we are part of. + +A quasi infinite array of twisting spirals dancing the strings of time. + +The quantum field, the rhythm of life. + + + + +Longer term +----------- + + +One thing that is quite clear here is we can build very much better +models for key parts of our solar system: the very same computer +models can be used at each level. + +Indeed, it is possible to simulate a world where we divide our +universe of interest into nested shells. You just throttle the +information flow between shells, hopefully no throttling is necessary. + +Now in our current world we have many experts who can help refine +models for each shell. + + + +Footnote +======== + +I just put down the thoughts down, before I go on to the further +chapters. + +As I have already read the next bit once I suspect much of what I +wrote above is what I picked up on the first read, or things that +Colin is well aware of but a diversion from the subject of the book. + + + diff --git a/docs/nodice/answer.rst b/docs/nodice/answer.rst new file mode 100644 index 0000000..0049bb0 --- /dev/null +++ b/docs/nodice/answer.rst @@ -0,0 +1,15 @@ +============= + For te tous +============= + +There is no one answer + +But an answer for everyone + +find your 4 te too + +and away we go + +day 1 of the artful aardvaark + +spread teh ubuntu diff --git a/docs/nodice/antigravity.rst b/docs/nodice/antigravity.rst new file mode 100644 index 0000000..15bf5ff --- /dev/null +++ b/docs/nodice/antigravity.rst @@ -0,0 +1,140 @@ +====================== + Too much antigravity +====================== + +So back at the game, the cat lottery, all is a buzz with cats every +where. + +Numbers to crunch, the market won't wait. + +Well maybe a bit lets all watch the news. + +Air says a flood, but wind was bad too. + +And still it is raining, so lets wait and see. + +No matter, there is data and numbers to crunch. + +Piri the Pyrate +=============== + +So things were good for a while. + +Piri new python and python was magic. + +A time machine that could tell you the future. + +As you catch its tail it pulls you along. + +As you ride its wave, wherever it will go. + +The players were nervous, back at the cattery. + +These cats were unpredictable things. + +We thought we knew what to expect from the model. + +But this is quite different a 1 in 100. + +No matter Piri can tweak the model, all will be good. + +Important antigravity +===================== + +Piri had worked magic with python for many a year. + +That was always the easy bit. + +There was always something fun to do, if only they would lend the +time. + +But there were memos and meetings and user stories. + +Now there were quite some requests. This button in blue. This one +on the right. + +The table below with commas in threes. + +Piri mostly ignored the orders and did what was best, for some kind of +best. + +Snowy the filter would just bounce things back, and distract all +requests with a pantomime act. + +But one day a memo returned, with the following inscription in bold: + +*Round Objects* + +Now Snowy was doing his lie on the back and let them tickle his tummy +act and so missed the memo's arrival. + +Piri had been watching Dave quite literally removing the GIL, with +python controlling it all. + +Why would you want all objects to be round? + +Piri jumped in the air and dabbed Snowy as he flew by. + +I have had it with here, time to import some antigravity. + +The Ballmer Peak +================ + +Has anyone seen Snowy and PiRi? + +Awkward silence. + +At times like this, eyes move to Sooty, who will know what to do. + +Sooty looks pale, a night chasing down? + +So they went to the Rovers Return, at the end of the street. + +When I left them they were testing whiskies, with beer to rinse in +between. + +Piri was talking of bagging Monroes in some place called Scotland. + +And typing away on a laptop:: + + # divide by zero magic + + import antigravity + import gilliam + + antigravity.geohash(gilliam.placetime) + + +And then they were gone. The laptop too. + +Sooty looked paler. He knew it sounded sketchy. + +Another day, he's have flipped off the sofa and said he left when the +whiskey came out. + +Dividing by zero +================ + +Piri and Snowy were not seen again. + +One quarter went by, the numbers were fine. + +Another went by still all was good. + +And nobody knew what Piri had done. + +Until it just stopped, who could take a look? + +Well Sooty said show me the stack. + +He scrolled to the end, and found a few lines:: + + # divide by zero magic + + import antigravity + import gilliam + + error = loss / skill + +Oh dear, its Gilliam again. + diff --git a/docs/nodice/april1.rst b/docs/nodice/april1.rst new file mode 100644 index 0000000..7479d8a --- /dev/null +++ b/docs/nodice/april1.rst @@ -0,0 +1,42 @@ +================================== + Who knew moving was complicated? +================================== + +It has been a while since I last wrote. + +In the meanwhile I have had a chance to go through the whole book in +some detail. + +I have a very good grasp of chapters 1-3 and much of 4 at this point. + +The more descriptive chapters: observations and cosmology are much +easier to follow, at least for me. + +A fascinating book. + +I dug out a pdf of Sciama's 1953 paper that you reference. + +inertial drag, does god play dice or is music inevitable? + +It is good to revisit this, indeed it perhaps should have been paid +more attention at the time. + +Or perhaps it was. There was a lot going on. + +My own thoughts are around the area of just how matter, will vibrate +in harmony with the surrounding vibrations in the universe. + +Indeed I think this is just how the mathematics actually +works, at least for certain \omega. + +At this point it would be invaluable to spend a few hours together if +we can resolve our own space/time coordinate issues. + +I think if one of us is dense enough and spins fast enough then +something might happen? + +I am happy to be the dense spinning bit for a while. + +All the best. + +Johnny diff --git a/docs/nodice/atowit.rst b/docs/nodice/atowit.rst new file mode 100644 index 0000000..6bb881a --- /dev/null +++ b/docs/nodice/atowit.rst @@ -0,0 +1,70 @@ +==================================================== + At some point all numbers are essentially infinite +==================================================== + +So I am reading a brief history of time. + +MJ sent me four books:: + + Kick Off, James Wragg + + A new paradigm for the universe, Colin Rourke + + A brief history of time, Stephen Hawking + + Cloughie, Walking on Water, My Life + + +She's that good. + +Oh and she even managed to include a small cardboard box, which would +have been even better had it contained what it was intended for. + +But the books were just perfect. + +I take Colin everywhere for now. + +His book, and Fred Hoyle's too have been an excellent way to get up to +speed with the thinking in cosmology. + +It has always both intrigued and mystified me. + +Through my life black holes have gone from something on Star Trek to +potentially the key drivers of the universe. + +I wonder if cosmology faces a crisis a little like mathematics went +through int the eighteenth and nineteenth centuries when axiomatics +was born. + +As far as cosmology is concerned, mathematics may be part of the +problem. + +The mathematics of both general relativity and quantum mechanics are +both complex and subtle. + +And we know both are incomplete models that are nonetheless very good +models much of the time. + +Theoretical physics advances as its practitioners explore the +consequences of the mathematics of the various theories. + +Sometimes things get stretched a bit too far. + +Black holes are one such place. + +They are tiny, so according to general relativity, they take no space +at all. + +But the strangeness that is quantum phenomena generates a whole set of +strange questions in the context of black holes. + +Heisenberg says we cannot know its position and its velocity beyond +some amount of certainty. + +It is my belief that the boundaries between black holes and the +surrounding universe will likely have many layers, like the atmosphere +of a giant planet. + +This would be what Colin Rourke refers to as a generator belt. + + diff --git a/docs/nodice/balls.rst b/docs/nodice/balls.rst new file mode 100644 index 0000000..7858b50 --- /dev/null +++ b/docs/nodice/balls.rst @@ -0,0 +1,54 @@ +=============== + Round Objects +=============== + +There was an organisation. It had reached peak bureaucracy, a well +oiled machine. + +Memos flew and whirled and rested in trays and all was well. + +But then came a note about kettles and leads and forms to be filled +and asking for comments. + +ROUND OBJECTS + +seemed vaguer but yet conveyed the thought. + +And time passed as the memo went down the streames and up the pipes of +the well oiled machine. + +"Who is Mr Round, and why does he object?" + +Balls +===== + +Round things, They are everywhere. Spirals too. + +Sometimes you are outside looking in watching a ball perhaps. + +Sometimes you are inside looking out, guessing what may be beyond. + + +If you are outside looking in, then you do not see what is going on +inside the ball, you just see what emerges from its surface and how it +interacts with its surroundings. + +If you are inside looking out then forces outside the sphere may not +be visible to you. + +If a sphere is in harmony with its surroundings, free falling through +space then inside the sphere those surroundings have no effect. + +Except that they do. + +The ball is in harmony with the surrounding fabric of space time. + +But that very fabric is a backround field of low amplitude vibrations. + +The amplitude of these vibrations being at the quantum level, random +perturbations that we can only observe indirectly. + +Matter will try to vibrate in harmony with other matter vibrating +with same frequency. + +It takes energy for it not to do so. diff --git a/docs/nodice/bb2bb.rst b/docs/nodice/bb2bb.rst new file mode 100644 index 0000000..55de091 --- /dev/null +++ b/docs/nodice/bb2bb.rst @@ -0,0 +1,83 @@ +=================== + Long term support +=================== + +More research on the names of u from yore. + +So it started with a warts and hog. + +Another hog, with hedge that with a whore. + +Things get going with a badger and a breez. + +Lts with the drake of the dapper. + +A fawn and a feisty one + +and a gibbon with guts + +HH another lts + +Intrepid, but what's an ibex? + +Jaunty like jackie + +A karmic koala + +And more LTS love with the lynx that is lucid + +MM of course + +and something hanging in a mall down town O + +Natty too, a narwhal + +Oss a lot, one eric + +More love for the long haul + +Not a penguin though + +But something precise + +Quanta but what is a Kwet salt? + +Raring to go with a ring for a tail + +And sauce too, for gerry to mander + +Something to trust, tar of course, but is it tz? + +TZ it is, another llllllllllong one + +Utopia next, with a single corn + +Vivid not velvet + +And wily note a weary wolf. + +More xx lts love + +and talking away y o y + +zest with a zap, that's us + +Now eh eh? art and hard work, but lots of fun + +Ready for Long Term Support + +You'll love what B is. + +A beaver that is bionic of course. + +Will she be mine, with Long Term Love and Support? + +PS assuming lights are all green? + +But watching for orange and red. + +small craft warning might be lifting. + +But first a blue and white delight to behold. + +Water too... now where did I leave the bottles? diff --git a/docs/nodice/bistar.rst b/docs/nodice/bistar.rst new file mode 100644 index 0000000..79282f0 --- /dev/null +++ b/docs/nodice/bistar.rst @@ -0,0 +1,11 @@ +============== + Binary Stars +============== + +BMG - BMRG + +ER - B - PE + + + + diff --git a/docs/nodice/boas.rst b/docs/nodice/boas.rst new file mode 100644 index 0000000..595f7e2 --- /dev/null +++ b/docs/nodice/boas.rst @@ -0,0 +1,35 @@ +================== + Not snakes, boas +================== + +Bulletin of atomic scientists. + +The doomsday clock, how long to midnight. + +Add g, where will you put it? + +After the bulletin, but with out a space? + +That's what I did in the help I dont use + +It comes from the doc + +String in the code + +Appears by magic + +from the guido clock + +Sets the time to 5 to the night + +Right now I'm an optimist, twice the boas. + +If the codes as long + +orongo we go + +and type it in orange football + +hope for a garble or two + +covfefe diff --git a/docs/nodice/bottle.rst b/docs/nodice/bottle.rst new file mode 100644 index 0000000..9ea7e61 --- /dev/null +++ b/docs/nodice/bottle.rst @@ -0,0 +1,140 @@ +==================================== + N green bottles, dancing in a pool +==================================== + +It started with none. + +It was good. A place to relax with noodles too. + +And then a construction of plastic and trash. + +With green pipes of water and noodles too. + +A bottle of water, a fountain for you. + +A crystal garden, a giant storm. + +A mountain fountain, pure and cold. + +Into the bottle, warm in the rays. + +Then trickle and flow to the swamp down below. + +Cascade down the pillar, the green can too. + +Flow through the towel, in harmony. + +Out of the noodle into the pool. + +Driving the wheel, beating the mana. + +Spinning and stopping, starting and sleeping. + +Back in the mountains, giant bowls of ice. + +Plastic and paper, even some rice + +Mixing and syncing ready to pour. + +Adding more water + +Bucket by bucket + +2 weeks of learning and still figuring it out. + +One +=== + +Guests came to visit, we sat by the pool and talked of how ice can +turn into energy to power a digital phone. + +Of pi and micro, bit and byte. + +And they brought water, bubbles too. + +Mostly of green but some yellow or orange. + +Up in the mountains, in great lakes of ice. + +One day I took one for a float in the pool. + +Sat in the sun, with waves all around. + +Opened the bottle, and now we had pool + 1. + +Slowly the gas left. + +30 minutes, ready to sync. + +And off it went to walk to orongo. + +1 + 1 +===== + +Once you have one then you have left the beginning. Divide by the +previous and you throw an exception. + +The hare must add 1, so now there are two. + +Green bottles walking in my pool. + +1 + 1 + 1 +========= + +The hare is away and now there are three. + +This one took a while to get from the quary. + +But ran down to join the other two. + +The tortoise is resting, it is feeling the heat. + +Drained by the talk of the hare. + +The sun the moon and the earth. + +2 o 2 +===== + +With three you can get four and all kinds of two. + +And four sets of three with one to score. + +1 + 1 + 1 + 1 + 1 +================= + +mars venus mercury + +earth sun + +2 + 2 + 2 = 3 + 3 +================= + +Here comes the moon, too soon or not? + +ones, twos and threes. + + +1 + 1 + 1 + 1 + 1 + 1 + 1 +========================= + + +Jupyter puts ones together. + +in twos and threes + +and fours and more or less + +or the seven akivi + + +2 + 2 + 2 + 2 = 4 + 4 +========================= + +Eight lines of rongo rongo, or 16 if you flip. + +Days and weeks + +Moons and more. + +Saturdays too, a day to play. diff --git a/docs/nodice/budgie.jpg b/docs/nodice/budgie.jpg new file mode 100755 index 0000000..841ac4e Binary files /dev/null and b/docs/nodice/budgie.jpg differ diff --git a/docs/nodice/budgie.png b/docs/nodice/budgie.png new file mode 100644 index 0000000..9487ab7 Binary files /dev/null and b/docs/nodice/budgie.png differ diff --git a/docs/nodice/cafedeaf.rst b/docs/nodice/cafedeaf.rst new file mode 100644 index 0000000..9ce450e --- /dev/null +++ b/docs/nodice/cafedeaf.rst @@ -0,0 +1,82 @@ +========= + Covfefe +========= + +Saturday morning 2004. + +Snowy and Sooty in the kitchen. + +Kettle boils, pour the covfefe. + +Into the bodum. + +Add milk to the mugs and onto the tray. + +No clothes to the bedroom + +A start to the day + +Not a good idea + +Into the shower + +That one is hot + +Try the other + +My that looks hot + +Where is the doctor? + +Nace the say, lets start a race. + +Track pants and t-shirt + +Across the bog + +Driven by ER at just the right pace. + +Hitting the bumbs but riding the wave + +Into nace and check in time. + +Name rank and number + +And on to the gurney. + +Covered in snow and more to swallow. + +Now not so bad, but off to st james. + +Man U on the radio, high as can be. + +No news of the blades, how can it get? + +Into a bed and laid there to rest. + +Doctor will come on monday best. + +Monday and heads they do shake. + +Tuesday a cut we will make. + +Woken with staples. + +And a patch on the leg. + +Trying to gage the size of the problem. + +10 days and I am home. + +pygtk to the rescue + +Docs on a mem stick, 64 * n b. + +Cafe deaf is the ailment. + +A magic hex incantation. + +However you mess + +It stays there to wake you. + diff --git a/docs/nodice/chains.rst b/docs/nodice/chains.rst new file mode 100644 index 0000000..074f6c4 --- /dev/null +++ b/docs/nodice/chains.rst @@ -0,0 +1,15 @@ +==================== + The ties that bind +==================== + +When the unity meets the noise. + +Make a forecast. + +Scramble it up. + +On a block chain with a good time stamp. + +Wait for the date open the time capsule. + +Is it closer than status quo ad infinitum? diff --git a/docs/nodice/colin.rst b/docs/nodice/colin.rst new file mode 100644 index 0000000..9173ba0 --- /dev/null +++ b/docs/nodice/colin.rst @@ -0,0 +1,273 @@ +============ + Dear Colin +============ + +:: + + And also about your ideas, which I haven't understood at all so far. + +So where to begin? + + +Energy and matter +================= + +:: + + e = m * c * c + +c is the beat of time, let's set it to one. + + +Planck's constant +================= + +:: + + e = h * f + + momentum too, with conservation. + + +Gravity +======= + +:: + + f = G * a * b / (r * r) + +G turns up in two ways: gravitational force and inertial resistance + + +2015: gravitational waves are a thing. + +Time +==== + +Follow a wave, one full wavelength is a beat of time. + +And the length a unit of distance. + +A moving point. + +Light +===== + +A single wave, pi out of phase with the gravity field. + +Follows a geodesic in the background field. + +Quantum +======= + +Don't focus on the photon, its the whole field in play. + +But maybe the background fields super smooth? + +Polaroid Lenses +=============== + +Bell's inequaity + +Harmonic series +=============== + +Cosmic microwave background + + +Energy to matter +================ + +hydrogen + +electron + +proton + +Rotation +======== + +Recipe +====== + +Start with nothing, an empty space. + +Three dimensions passing through time. + +At the origin, a small sphere. + +Not so much a sphere, a dense core with a moon orbitting around. + +So the moon sends a wave of energy, which modulates the signal from +the nucleus below, as it too spins. + +Now imagine the surface of the sphere 2 * r from the origin. + +At time t, what of the sphere at t * r? + +Mr Murphy +========= + +Mr Murphy was my physics teacher for four years at King Ecgbert School +in sunny Sheffield. + +"It works a lot better if you plug it in!". + +Experimental physics? + +:: + + F = m_1 * m _ 2 / r^2 + +And something about Kepler and equal areas in equal time. + +Parabola's, ellipses and hyperbolae? + +And special relativity. + +:: + + E = m c * c + +Equations of Minskoski space. + +The constant G, acceleration due to gravity. And this mysterious +thing inertia, which shared the same constant down to 10 decimal +places. + +And the Dore four two. Happy times. + +Warwick +======= + +Zeeman +------ + +Catastrophe +----------- + +Godel +----- + +Galois +------ + +Fermat +------ + +Fourier +------- + +Poincare +-------- + +Quantum +------- + +Information +----------- + +Mathematics and simulation +========================== + + +Ideas +===== + +:: + + This book provides a completely new approach to understanding the + universe. The main idea is that the principal objects in the + universe form a spectrum unified by the presence of a massive or + hypermassive black hole. These objects are variously called + quasars, active galaxies and spiral galaxies. The key to + understanding their dynamics is angular momentum and the key tool, + and main innovative idea of this work, is a proper formulation of + “Mach’s principle” using Sciama’s ideas. + +The first paragraph in Colin Rourke's, "A new paradigm for the +universe". + +Now there is an idea, and a good place to start. + +Start with gravitational waves. Add other things when you need, but +only when needed. + +Draw a ball around your area of interest. + +Assume what comes in, and goes out, is below the noise. + +The idea if there is one here, is that these background gravitational +fields are extremely smooth in some sense. + +So, if you are a photon riding a geodesic, its a pretty smooth ride, +exceot when it isn't: starting and stopping. + +But this is illuminating when thinking about quantum phenomena. + +So, a photon is riding a wave which is in harmony with the background +wave around it, or striving to be so. + +Likewise, giant blackholes orbiting each other. + +But as you raise, it is the spin of these massive objects that affects +the way the surroundings evolve. + +If we think of a giant black hole, beating with the frequency of a +neutron, it's beat would move in sync with the surrounding background +beat of neutrons. If it is not spinning relative to its surroundings, +however you care to measure that, then it has no influence beyond the +point where its gravitational field goes below the noise. + +Since it is not spinning relative to the surroundings, it is not +modulating the background field. + +Now at this point I usually bail out to python code and try and +simulate, rather than write equations. + +I think the thing for me to do from here is to write some simulations +of my understanding of how a Sciama space works. + +For me, it is the inside of 3-sphere, where the influence at drops of +linearly with distance. I visualise this as a wave whose amplitude is +1/n at distance n. + +One other thought. When a spinning body's radiation drops to the +cosmic background level it is absorbing as much energy as it needs to +maintain its spin, so a self-sustaining system, given a constant +background. + +:: + + Gravitational waves from centres of mass dance in celestial + harmony. + + Nature loves spirals. + + The quantum field is modulated by the beat of the surrounding + masses. + + As they spin, so they spin the surrounding field. + +PyCaribbean +=========== + +It was in February 2015 in Santo Domingo, during the first PyCaribbean +that Brandon Rhodes gave a keynote. + +It was python's 25th birthday, give or take a day. + +Brandon described how python had been intimately involved in the LIGO +project which had just announced the detection of gravitational waves. + +It was an exciting time, full of possibilities. Talk of climate and +weather and music and more. + +Two years on I will be back in Santo Domingo this February. + +I will be giving a talk, showing some of the things I have worked on +since then. + +And sharing ideas that go who knows where? + +Raspberry pi, pi, pie and py. diff --git a/docs/nodice/colin2.rst b/docs/nodice/colin2.rst new file mode 100644 index 0000000..ac1f990 --- /dev/null +++ b/docs/nodice/colin2.rst @@ -0,0 +1,249 @@ +============ + Dear Colin +============ + + :: + + This book provides a completely new approach to understanding the + universe. The main idea is that the principal objects in the + universe form a spectrum unified by the presence of a massive or + hypermassive black hole. These objects are variously called + quasars, active galaxies and spiral galaxies. The key to + understanding their dynamics is angular momentum and the key tool, + and main innovative idea of this work, is a proper formulation of + “Mach’s principle” using Sciama’s ideas. + +The first paragraph in Colin Rourke's, "A new paradigm for the +universe". + +Feedback from chief editor was that more explanation was needed. + +First of all, I mentioned a lot of people, particularly in the fields +of mathematics and theoretical physics. + +I think all of them have been in some way trying to describe wider +pictures. + +And it feels like there is nothing that I am thinking that has not +been thought before. + +I still have not made it back to a second read of your book, but have +been thinking a lot about Sciama spaces, Minkowski too with some +Poincare too. + +Now these are all things others understand better than me. + + + +:: + + spectrum unified by rotating masses + + +Solar System +============ + +Gravity +======= + + +Magentism +========= + +Cosmic Microwave Background +=========================== + +Black hole spirals +================== + +Big bang??? + +When? + + + +Waves +===== + +Energy mass and rotation. + + +Of all the things they say +========================== + +Good to be able to speak to someone who has better insights than I do. + +Time and space: all relative + +I tend to look at it after factoring out local matter from the +geometry. + +At least some of the time. + +Cosmology has always intrigued me. So easy to get into a circular +argument and not even know you are there. + +Rather you are off on a spiral of promise. + +Giant black holes at the centres of galaxies. + +I remember being at school, maybe 7 years old. Probably the same +class room Fred Hoyle once sat in. + +Someone mentioned black holes were a thing. No this wasn't Star +Trek. + +Well yes.. like on star trek, but real. + +So over the years, dark matter has appeared. Or rather hasn't. + +Now since galaxies seem to be rather homogeneously distributed about +our visible universe it would seem you can place as much matter as you +like in the centres of those galaxes, at least within a couple of +orders of magnitude in some units. + +(now we are going round in circles). + +I am thinking about my talk for Py Caribbean. + +I need to get it sorted so I can start practicing. + +The title is: + +The tankrain karma pi rongo rongo show +====================================== + +:: + + A talk about natural cats of all sorts. + + The wonders of the universe + + The world of python and pi + + Gravity and lightness + + Moai and madness + + The rongo rongo way. + +Now I understand if you hesitate to be associated with this. + +Tankrain +-------- + +is a few lines of python code I use to view images. + +Its great for photos, presentations and viewing plots from +simulations. + +Or climate data plotted on a grid (note to self use molleweide??) + +If you can model the water on earth you really have the climate and +weather within your model. + +This water is in liquid, ice and water vapour form. Along with other +gases in the atmosphere. + +An inner core, solid earth with rotating inner molten core. + +Water and ice on land and in the atmosphere. + +Shells as the radius of the sphere increases. + +A hurricane is powered by the difference in temperature between the +hot ocean and the cold upper atmosphere. + +A flow of moist warm air heads upwards, cooler air sucked in. + +A daily bathing of sunlight overhead. + +And tides and waves driving the ocean. + +Dragged away from the equatorial plane, drag increasing as you move north. + +karma pi +-------- + +This is where I experiment with ideas and bits of python code. + +Mostly I end up with too much to think about before I do too much +damage and write actual code. + +But there are a lot of pieces that can be used to fit models to data +and then simulate futures (and pasts, as we know, time and all that). + +And provide insights. + +The good news is the code is extremely general. + +Most modules can be read on their own and only really require ability +to read python. + +As my ideas get more solid, so will the code. + +rongo rongo +----------- + +Round and round we go. + +Rongo Rongo is the name given to an ancient script written by the Rapa +Nui people who inhabited the island of the same name, now Easter +Island or Isla de Pascua. + +It is famous for the magnificent Moai, giant statues carved out of +volcanic rocks. + +The distribution of Moai about the island is fascinating. + +The people said they walked on their own, using the power of mana. + +*moon.py* is the beginnings of some code to simulate the gravitational +and magnetic fields of the island. + +How strong would the magnetic field need to be to allow the Moai to +wobble as pendulums, driven by the moon and the stars? + +The code is intended to be entirely general, so could equally be used +to simulate the forces of gravity and magnetism in a spiral galaxy. + +Or rather it could be, once I finish writing it. + +And rongo rongo? + +Well the text goes round and round. Two spirals of mystic figures, +meeting in the centre, or starting there and moving out, in a dance as +the Moai walk by the ahu by the shore. + +By the time the tablets were noticed, all the wise who could read were +gone, but we are told they were chants, but what do people chant? + +And why does everything go round and round in rapa nui? + +Python +------ + +Happy Birthday! 27? + +Gravity +------- + +LIGO: 2-3 years + +As soon as it was sensitive enough to do so, this detector found what +it was designed to find. + +Anyne got updates from this and other gravity wave projects? + +Note that this observation suggests such events are common place. + +This is no doubt consistent with the theory that galaxies can be +extremely long lived. + +Presumably in time the LIGO experiment (and related efforts) will +confirm the homogeneity (or not) of space time. + +I would expect to see interesting correlations with the cosmic +microwave background. + + diff --git a/docs/nodice/crquiz.rst b/docs/nodice/crquiz.rst new file mode 100644 index 0000000..80a48ac --- /dev/null +++ b/docs/nodice/crquiz.rst @@ -0,0 +1,129 @@ +=========== + Questions +=========== + +The nature of the inertial drag field +===================================== + +I spent much of the summer looking at waves in a pool and thinking +about quantum phenomena. + +I also thought about the fields inside colliding black holes and how +the natural numbers might emerge, if you will excuse the pun, +naturally. + +But how it is more complicated than that because of the echoes. And +how at the boundary the echo is modulated by the surrounding universe. + + +[Aside: There are a number of incoherent writings here from that period. One +task ahead is to go through these and perhaps, assuming I can +understand my own writing, translate them into something other people +can understand too. +] + + +Rotation is fundamental to this and the ideas are easiest explained +when two black holes of roughly equal mass collide. + +In layman's terms, I believe what goes in, must come out. + +Now lets scale things down a bit. + +Consider a large rotating sphere of ice and consider how this modulates +the background gravitational field. + +Now assume the sphere has a radius r, big enough that in the time it +takes light to travel distance r, it has rotated an angle \omega and +that \omega * r is large compared to the distance between adjacent H2O +molecules in the ice. + +Inertia, the two versions of G, conservation of momentum. + +Conservation of energy too. + +And then there are thoughts about wave particle duality. + +Hoyle's expanding universe with continuous creation. + +Big bangs are a thing. Almost surely was one in our past. + +Almost surely, a very, very long time ago. + +But regardless of our origin, LIGO experiments show that black holes +are colliding all the time. + +So the good news is that all the physics research around big bang +theory still has great relevance in your paradigm for the universe. + +But I keep coming back to what goes in must come out. + +Bringing this back to earth and the solar system. + +I believe we can diagnose our planet (and solar system too) and +produce models for the magnetic storms going on inside our planet. + +As well as the ocean currents and atmosphere: in short climate models +that tease out the relationships with the key drivers of the dynamics. + +Features such as El Nino could then be forecast with skill much +further into the future. + +Intriguingly, there is a lot of overlap in the software tools for both +problems. + +The problem with software is that it is a general thing. So you can +always further abstract until there is almost nothing left. But this +is also its power because you can build 20-30 general tools that play +together nicely and now you have almost infinite variety. + +And then you end up stuck trying to decide where to go next. + +I may have mentioned before I recall Christopher Zeeman saying that +"all great mathematicians are inherently lazy". + +The same is true in software. + +But in both cases, what Chris forgot to say was that they also will +spend a disproportionate amount of time avoiding tedious, error prone, +repetition. + +Regardless, I do wish to thank Christopher for this, and many other +wonderful pieces of advice and wisdom. + +Harmony +======= + + +Distribution of orientations of spiral galaxies +=============================================== + +Are they random? + +This relates to the does god play dice question. + +Distant mass dominates. + +The quantum clock simulation. + +Implications for humanity. + +Free will? + +Cosmic Microwave Background +=========================== + +At what distance is energy flow in and out balanced? + +Python Simulations +================== + +https://github.com/swfiua/karmapi/karmapi/tpot.py + +Teapot. Nested. + +Data? + +Matlab code. + +Ottawa University? diff --git a/docs/nodice/drjg.rst b/docs/nodice/drjg.rst new file mode 100644 index 0000000..661e74d --- /dev/null +++ b/docs/nodice/drjg.rst @@ -0,0 +1,65 @@ +============ + Doctor Dad +============ + +What's the question? I guess I am not so sure myself. + +Should sign up for a doctorate, but not the donkey work. + +Unis these days, raising cash or making waves? + +So I might just hang out in the Car el ton bar. + +Talk about ideas, how the universe works. + +That is that this is about + +Maybe a book, but a a book that will be code. + +A rongo-rongo script. + +Undeciphered, though it is just plain text. + +I think I know what it might be. + +And how the Moai moved from the quarry to the shore. + +Why they always face inland, except for a ki vi. + +Giant magnets waddling around. + +Working on a simulation + +that may prove I am right. + +There is a link with ptah from Egypt + +And the theories of Max Planck + +In fact its all related + +Why I think I might be right. + +I am sure it is what is already known + +At least at time before + +But many are down in the weed. + +Not seeing what's above + +But we all see more + +Knowing the waves of G exist + +E and M too, a unified model + +You can explain it all, with speed of light waves. + +Relativity too, special and general. + +And Planck with Poincare + +Godel Escher and Bach + +Filled in the details for all. diff --git a/docs/nodice/e2theipi.rst b/docs/nodice/e2theipi.rst new file mode 100644 index 0000000..ba6fa70 --- /dev/null +++ b/docs/nodice/e2theipi.rst @@ -0,0 +1,37 @@ +============== + Johnny GILly +============== + +An nth root of e to the i pi. + +Now here is a thing. + +Let's say pi=3 and so does e. + +Now here is a thing. + +e *pi ~ 3 * 3 = 9 + +So add a bit and call it 10 or pie + +e ^ pi ^ e ~ pi ^ e ^ pi or 3 ^ 3 = 27 + +Add a bit and call it 30. + +Now 10 ^ 30 lets square it. + +That's 10 ^ 60 + +Or the size of the universe in planks. + +And the age of the universe in planks too. + +And the mass or the energy of the universe in planks as well. + +So maybe the plank isn't constant? + +It shrinks in time as the universe grows. + +Conserving the mana and sharing the karma. + +If you live 1 degree by pi to the n, then how could you know? diff --git a/docs/nodice/eagle.rst b/docs/nodice/eagle.rst new file mode 100644 index 0000000..b9c347b --- /dev/null +++ b/docs/nodice/eagle.rst @@ -0,0 +1,59 @@ +============= + Legal Eagle +============= + +So it goes like this. + +Writing down thoughts, playing with rhymes and puzzles. + +Riddles with answers or not. Or riddles which answer themselves? + +So lots here is simply quite wrong. But the answer there will help to +show the way. + +So check for assumptions, nearly right but not always, but maybe its +good enough? + +reminds me it might be wrong... did I mention that? + +its like godel and math, somethings are true with no way to be sure + +some can be true or false it doesn't matter, but no way to know + +and some are true or false and can be proved to be so) + +i think that should cover the legal disclaimer ;) + +wiki pedia might help and a good place to go to check leads and Leeds +too I guess, but don't go there:: + + did i mention the legal disclaimer .. it might not be true there + too, but its proved a good web of trust from wales... + hmm... reminds me of jimmy from aber ga veni. And Malcolm Nash and + Garry Sobers.... + +another fun one... don't forget the legal disclaimer.. + +The tankrain rongo rongo show may really be a thing. + +Round and round and side to side, up and down we go. + +The license is gpl v 3, or so it says in the root. + +Creative Commons for docs and pics is more than good for me. + +I try to give credits where due, but never enough. + +It's all glued with python, so lots to thank. + +And references everywhere to things I love. + +So if you're in doubt just ask Larry Lessig. + +That's Lessig not Wall of the perl. + +And better be Lawrence @lessig + +Or Pamela Jones in a fine red dress. + +Groking the law for the rest of us. diff --git a/docs/nodice/ebigum.rst b/docs/nodice/ebigum.rst new file mode 100644 index 0000000..f64c164 --- /dev/null +++ b/docs/nodice/ebigum.rst @@ -0,0 +1,8 @@ +======== + E by G +======== + +tea at 10 30 + +til 10 45 + diff --git a/docs/nodice/et.rst b/docs/nodice/et.rst new file mode 100644 index 0000000..fb43ed4 --- /dev/null +++ b/docs/nodice/et.rst @@ -0,0 +1,45 @@ +================================ + The cat in the box on the gate +================================ + +What was its name? + +It waited each day. + +4pm or was it 4 and forty? + +Jack a nory, what a story? + +Home from school. + +On the carpet. + +Rhythm of a voice. + +Willie Wonker, Bernard Cribbins. + +Music too, but what are the words? + +What does it mean? Why does it matter? + +What do they know and hope to show? + +I didnt know then + +Nor do I now. + +With every answer, another puzzle. + +A bus stop shelter + +With a railway sign. + +No railway platform + +A train on the way + +With ET and S R and others + +F and U await at tcm. + +And the cat in the box at the gate. diff --git a/docs/nodice/etpm.rst b/docs/nodice/etpm.rst new file mode 100644 index 0000000..b70da82 --- /dev/null +++ b/docs/nodice/etpm.rst @@ -0,0 +1,40 @@ +=========================================== + an Epycycle Theory for Planetary Motions +=========================================== + +or not. + +corollaries to the new paradigm. + +ancient universe, but constant recycling of matter. + +de Sciama principle. + +and de Sitter space. + +symmetry: the sum of the bodies in my universe's influence on my inertial +frame is equal to my influence in return. + +distribution of galactic angular velocities? + +elliptic curves as geodesics? + + + +Intro +===== + +A group of scientists have developed a simpler theory of the +universe. + +At the same time a global collaboration of scientists is collecting +extraordinary data on a whole spectrum of events. + +Somewhere along the line perhaps a wrong turn was made? + +Like a proof or a great hypothesis of old sucn as that of Fermat... + +But not a proof that can be patched, no matter how many patches are +applied? + +So let's wind back the clock and see where we might have gone astray? diff --git a/docs/nodice/exandcon.rst b/docs/nodice/exandcon.rst new file mode 100644 index 0000000..8688cfd --- /dev/null +++ b/docs/nodice/exandcon.rst @@ -0,0 +1,346 @@ +=========================== + Expanding and contracting +=========================== + +*de Sitter space* is proposed in [1] as a model for the universe. + +Within this space, time-like geodesics follow two distinct fields: +expanding and contracting fields. + + +[Incorrect at the second sentence see [2] for follow up.. + +This is perhaps one of the harder parts of the theory to picture. + +Satelite loops of water vapour in the earth's atmosphere may help with +this. + +This site has excellent animations: + + https://www.tropicaltidbits.com/sat/satlooper.php?region=atl&product=ir + +Find an area where there is a tropical cyclone, and note how it both +sucks in moisture from the surroundings, with a distinct in-flow as +well as a distinct outflow. + +A strong cyclone viewed from space has a striking resemblence to a +spiral galaxy. + +A fuller 3-dimensional view would look more like a cooling tower, +it's base, at ocean level, sucking in matter and it's top, up in the +atmosphere, ejecting the same, with a whirling vortex in between. + +So imagine instead of a thin slice of the earth's atmposphere, the +picture is a just a slice of a giant three dimensional space of +galaxies. + +Each cyclone, now a galaxy. + +Now we see how the giant masses at the galactic centres suck in matter +from the surroundings, way beyond the visible galaxy. In essence, +they clear space, allowing light to pass. + +Now the progess of that light is modulated by the intervening matter, +the vast majority of which lies at the centre of, or close to, a galaxy. + +So what of the increasing red shift as we get deeper into the universe, +does that not mean that those galaxies are receding faster? + +Is not that just how space time works, when you saturate it with giant +rotating masses? + +Remember the universe is saturated, in fact appears to be in an almost +perfect equilibrium, like clouds of water vapour in our atmosphere. + +Surely it is just the case, the further light travels the more it is +red shifted by the intervening matter? An inertial drag that matter +has on space time? + +Now how does this all square with gamma ray bursts? + +The distortion of space time that giant masses create is more complex +than described above, it contains both expansive and contractive +fields. + +One way to look at this is imaging a 3-dimentsional lattice, with +nodes of the lattice evenly spaced. + +Pick a point and apply a twist to the lattice. This distorts the +lattice near the twisting point, lattice cubes become lozenge shaped. + +Overall, the contractions and expansions of the lattice balance out, +or rather they serve to provide an overall expansion in space, a world +within worlds. + +Now photons following the contractive field will tend to bunch up, in +effect they are blue shifted. When we observe the result of this, +light from a source generated over billions of years, arrives in a +very short period of time, before reverting to the expanding field (it +is not possible for a gamma ray burst to last a long period of time +without breaking causality. + +A stream of photons from beyond the Hubble distance ends up slowed to +a crawl by the intervening matter, so it bursts on the scene, then +rapidly decays to a distant red? + +When our path crosses such a stream we get the rapid burst before +things settle down and we have a new distant arrival. + +Why so? The intervening matter modulates the signal, adds harmonics? + +Further note that there is evidence from the harmonics in the CMB that +space time is tidal. We should factor out these tides to help our +understanding of the observations we see. + +Returning to cyclones, it is worth further noting the space where this +all takes place: a thin shell, above the earth's surface. + +One dimension of time, two of space and a thin slice of a third +dimension. Harmonics emerge around the globe. + +At the surface matter moving with the earth, but at the edge of space, +starting to move with space itself, or at least closer to the local +inertial field, away from some of the spin. + +Space time? +=========== + +Here I am concerned, primarily, with the propogation of light through +space time. + +Making these assumptions: + +* matter both modulates and defines the space time through which light + travels. + +* in the language of [1] it creates inertial frames which define the + geodesics for electromagnetic waves to follow. + +* the universe is pretty much the same everywhere. + +* local galaxy velocities of around 300 km/3, or about c * 10-3, where + c is the spee of light. + +* a rotating mass drags the inertial field by amound proportional to + the mass times its angular velocity, that drops of with the 1/R + where R is the distance from the mass. + +* the universe is almost exactly saturated, in the sense that its + volume is equal to the total volume of space we get by summing the + space associated with each galaxy. + +* this latter we do by summing the volume over which each galaxy's + field remains contractive. + +Less precisely, but hopefully more intuitively, take for example our +sun. There is a point in space where matter is beyond the sun's +influence. Inside this radius, matter can (and does) slowly drift +inward towards the sun. Outside it just drifts by and moves further +and further away. It is the same with galaxies, but they come with +10**10 or more solar masses at the centre. + +The point of all this is that all light passing through the universe +is spending much of it's journey having its passage modulated by some +nearby galaxy. + +Now this modulation is what we call the expansion of space time. It +is an expansion, in the sense that the mass in the region is twisting +the fabric in on itself, space in a sense is denser, like an Escher +painting. + +As light travels through this fabric it is inevitably slowed and +shifted to the red. + +Then there is lensing to consider. Not only will the intervening +matter modulate the signal, it will change it's direction and focus +the signal. + +What we observe here on earth is the sum over time of the modulations +of the incoming wave. Much of the time we just see the low glow of +the cosmic microwave background, stretched out photons that zoom by. + +But as we fall into the same path as a focussed beam and we too follow +that beam, then we see a gamma ray burst. + +The merger of our path with some source can, and general is, a +dramatic event. + +Postscript +========== + +For some while I have been puzzling over how the universe is could be +in a steady state, with balanced expanding and contracting fields. + +I had been focussing on the gamma ray bursts and representing new +arrivals in our visible universe, but puzzling why all arrivals are so +distance and things could possibly be in balance? + +Now things make sense. The redshift is just an artifact of matter. + +I also note that the interpretation of + +Status Update +============= + +On the software side, I have split some parts of karmapi off into +another project, I am calling *blume*. + +I've found a great library for doing simple harmonic analysis. + +I've successfully used that to do transforms on global temperature +data and started to fit models. + +I'm literally going round in circles with *blume*, juggling Balls with +graphs and queues too. + +Once I have this magic working then I can get back to plotting and +simulating galaxies. + +I've been following the ongoing LIGO and Virgo runs. See here:: + + https://gracedb.ligo.org/latest + +As far as I can tell, neutron star merges have been pretty rare so +far. + +There has also been a lack of events where coincident observations, +such as gamma ray bursts, have been made. + +Sky localisation is now routine for events with some excellent +exhibits being produced:: + + https://gracedb.ligo.org/superevents/S190828j/view/ + + https://gracedb.ligo.org/superevents/S190828l/view/ + + +All this stuff is working using triangulation based on time +differences of arrival at the three detectors in operation. + +It all looks very sound. Note the two above look to be at about the +same time and coming from the same part of the sky, but that is just +because detector sensitivity varies according to the current +orientation of the detectors to that part of the sky. [aside: +important to know more about this to better understand variations in +detection rates]. + +Not only do we get the coordinates, we get pretty good distance +estimates. Which should help those looking for nearby galaxies. + +Further, this in turn will help refine estimations of the Hubble +constant. + +However, I think that rather than being the source of the signal, we +are finding the location of the lens that focussed the signal. + +Which recalls something I read about short and long gamma ray bursts:: + + We present a detailed investigation of Hubble Space Telescope + rest-frame UV/optical observations of 22 short gamma-ray burst (GRB) + host galaxies and sub-galactic environments. Utilizing the high + angular resolution and depth of HST we characterize the host galaxy + morphologies, measure precise projected physical and host-normalized + offsets between the bursts and host centers, and calculate the + locations of the bursts with respect to their host light + distributions (rest-frame UV and optical). We calculate a median + short GRB projected physical offset of 4.5 kpc, about 3.5 times + larger than that for long GRBs, and find that ≈25% of short GRBs + have offsets of >= 10 kpc. + + When compared to their host sizes, the median offset is 1.5 + half-light radii (re ), about 1.5 times larger than the values for + long GRBs, core-collapse supernovae, and Type Ia supernovae. In + addition, ≈20% of short GRBs having offsets of >= 5re , and only + ≈25% are located within 1re. + + We further find that short GRBs severely under-represent their + hosts' rest-frame optical and UV light, with ≈30%-45% of the bursts + located in regions of their host galaxies that have no detectable + stellar light, and ≈55% in the regions with no UV light. + + Therefore, short GRBs do not occur in regions of star formation or + even stellar mass. This demonstrates that the progenitor systems of + short GRBs must migrate from their birth sites to their eventual + explosion sites, a signature of kicks in compact object binary + systems. Utilizing the full sample of offsets, we estimate natal + kick velocities of ≈20-140 km s–1. These independent lines of + evidence provide the strongest support to date that short GRBs + result from the merger of compact object binaries (NS-NS/NS-BH). + + We calculate a median short GRB projected physical offset of 4.5 + kpc, about 3.5 times larger than that for long GRBs, and find that + ≈25% of short GRBs have offsets of >= 10 kpc. When compared to their + host sizes, the median offset is 1.5 half-light radii (re ), about + 1.5 times larger than the values for long GRBs, + + https://iopscience.iop.org/article/10.1088/0004-637X/776/1/18 + +The paragraph beginning *Therefore,* can largely be ignored, other +than noting that GRBs do not sem to occur in regions of star +formation. + +What is happening is light from a distant galaxy being focussed by the +so called *host* galaxies. + +Longer gamma ray bursts are typically 1.5 light radii away from +galactic centre, with short gamma ray bursts 4.5 light radii away. + +This is to be expected, the more powerful long bursts are in part a +result of the more intense lensing closer to the galactic centre. + +I believe we may well be seeing the same phenomenom with gravitational +waves. + +Summary +======= + +It is important to keep in mind that the light waves that we see from +distant galaxies are just that, photons on a journey from a distant +source. + +The fact that these arrive tired, and red-shifted tells us their +journey has been expansive, in short the intervening matter is +creating an expansive field as far as light propogation is concerned. + +Now think of a distant source, think of it in its terms, trying to +shine a torch on earth. + +At some point it is so far from earth it can't reach it. Or rather, +source and destination are swirling around too much and any photons +get blurred out. + + +Addendum +======== + +From wikipedia:: + + According to calculations, the current comoving distance—proper + distance, which takes into account that the universe has expanded + since the light was emitted, to particles from which the cosmic + microwave background radiation (CMBR) was emitted, which + represents the radius of the visible universe, is about 14.0 + billion parsecs (about 45.7 billion light-years), while the + comoving distance to the edge of the observable universe is about + 14.3 billion parsecs (about 46.6 billion light-years),[10] about + 2% larger. + + https://en.wikipedia.org/wiki/Observable_universe#Size + +The author is distinguishing between the current distance to the +objects that emitted the CMBR we see today, noting that due to +continued expansion etc. + +And the distance to the edge of the observable universe. + +The author is looking at things from a big bang perspective and the +assumption that the CMBR is how things were just 380,000 years after +the big bang. + + + + +[1] Another paradigm for the universe. Colin Rourke. aka "The Book +of magic." + +[2] `static.rst` diff --git a/docs/nodice/fred.rst b/docs/nodice/fred.rst new file mode 100644 index 0000000..f569699 --- /dev/null +++ b/docs/nodice/fred.rst @@ -0,0 +1,243 @@ +======================================== + Fred Hoyle: The Nature of the Universe +======================================== + +I just changed coordinates. + +New location good, but temperature has been multiplied by minus one. + +Green turned to white, with crystal stalagtites. + +Found a box of books out of storage. + +And amongst them, Fred Hoyle. + +Mum mentioned him. He grew up in Bingley, Yorkshire. + +Guess maybe Myrtle Park school? + +The book follows a series of lectures Hoyle gave at Cambridge, +around 1950. + +The first edition was published in 1960 with a July 1959 preface that +states that it has been revised where recent astronomical work makes +it necessary to do so. The chapter dealing with the origin of the +planets has been completely re-written. + +The book was 3 shillings and sixpence. + +But is marked 20 pence, so from a second hand book store some time +since 1970. + +125 pages and 4 plates of magic. + +My guess is dad bought it some time since decimalisation. + +And then I found it one visit home and started reading it (2003 -- +there was a receipt from that date in the book). + +I had put Colin Rourke's, A new paradigm on the Universe on my +Christmas book list. Actually, I inserted it into my partner's book +list in the hope someone might accidentally get it her. + +But no luck. So a copy may now be in the post. + +The timing of the find of Fred Hoyle's book could not have been +better. + +It has been fascinating to wind back a lifetime, to a +book published before I was born. + +It is a stunning account of how the nature of the universe came to be. + +There are just 5 chapters, around 20 pages each. + +Earth and nearby space +====================== + +The Sun and the stars +===================== + +How a star works. + +and its relation to the hydrogen bomb. + + +Origin of the stars +=================== + +Origin of the earth and the planets +=================================== + +Speed of rotation of the sun. + +Key role of magnetism. + +Conservation of angular momentum. + +Magnetic clock springs. + +Expanding Universe? +=================== + +Expanding and constantly generating new atoms. + +It should note that whilst Hoyle talked of an expanding universe, +nothing in his arguments involved a big bang. + +Rather, he sets the scene with clouds of hydrogen soup. + +Reading a year on, I am struck with the sense that Fred very much felt +the expanding, continuous creation universe was the simplest +explanation of the observations. + +In particular, he had a fine sense of the potential ages of the +objects, distant spiral galaxies, that he was seeing through the great +telescopes. + +He talks of 500 billion years for a galaxy to drift from us to the +edge of the visible universe. + + +A Personal view of all the things they say +========================================== + +The book ends with Fred giving his personal view at the time. + +On a back page, someone has written "of all the things they say". + +So here is a personal view of all the things I may have heard. + +It is now 2018, 68 years since the first edition. + +We have computers the power of a Cray XMP in our pockets. + +And images of the stars from 13 billion light years away. + +And LIGO detectors that show gravitational waves exist. + +Black holes colide and out go the waves. + +Reading Fred's personal view, he gives his view on afterlife, deeming +that if it were possible to reconstruct the brain, then in that sense +you live on. + +The words he wrote do not reconstruct the mind, but they give great +insight into his nuanced view on the fabulous universe as it came into +view. + +Gravitational waves +------------------- + +And Gamma Ray Bursts. + +I have just re-read Fred's book. With new perspective through a year +of Colin Rourke's new paradigm for cosmology. + +It is clear reading *The Nature of the Universe* that black holes were +very new on the scene. There is no indication he was aware that the +centre of our galaxy could have a black hole of mass 100 billion suns. + +We have more data from LIGO detectors, there are now eleven +observations. They are categorised into black-hole/black-hole +collisions and black-hole/neutron star. + +They also split into confirmed and tentative. + +There is one observation that was seen by 3 separate detectors and the +ellipse of uncertainty in the location of the source is pretty small. + +There seem to be a number of observations (3-4?) around August 2017, +when there were 2 or 3 detectors operational much of the time. + +More to come when I have looked at the data. + +Gamma Ray Bursts +---------------- + +In the new paradigm a model is proposed whereby gamma-ray bursts (GRB) +are explained as optical illusions as a galaxy enters our visible +universe. + +It seems to me that the gravitational wave generated by such a galaxy +will also propogage along similar geodesics to the light and be +modulated in a similar manner. + +Given the distances involved, this wave presumably is also modulated +by the sparse, but uniform, inter-stellar matter. + + +Expansion and big bangs +----------------------- + +red shift. + +more than one way to shift red. + +At the time of the book, it was difficult to see beyond our own spiral +galaxy. Powerful telescopes were a very new thing. + +Within that galaxy the red shift of light appears to be a good indicator of +distance. + +This also appears to give a *coherent* view of the universe out to the +13B light year range currently observable. + +As Colin Rourke observes [1] a rapidly spinning black hole at the +centre of a galaxy can result in a red shift of light from the spiral +galaxy of stars surrounding that black hole. + +I believe that this can be shown to be the case. + + + +Self and circular reference +--------------------------- + +Cosmology, theoretical physics, mathematics and computer codes can all +very quickly become "self-referencial". + +Following a train of thought and going round in circles. + +Cosmology is a bit like mathematics. You have to make some +assumptions and see where it leads. + +If the assumptions make good predictions, then it may be a good +theory. + +But don't forget the assumptions, you may have new observations to +refine those assumptions. + +Where to begin can be a problem. + +How about stars condensing out of hydrogen clouds? + + +Hyrdrogen soup +-------------- + +Imagine you are in a part of the universe where virtually all the +matter is hydrogen. + +Sphere of frozen hydrogen. + +Rotation? + + + + +Magnetic springs +---------------- + +Balls, Rotation, Spiral galaxies +-------------------------------- + +*Rotating gravitational fields* + + +Rotation +======== + +And with that thought it is fast forward to Colin Rourke, A new +paradigm for the universe. + diff --git a/docs/nodice/fuusball.rst b/docs/nodice/fuusball.rst new file mode 100644 index 0000000..c096b8b --- /dev/null +++ b/docs/nodice/fuusball.rst @@ -0,0 +1,166 @@ +========== + FOO SBALL +========== + + +A foosball table in the kitchen + +2014 October the nth. + +Hurricane Fay, a saturday night. + +Tropical storm at a 100 miles. + +No need to bother bermuda strong. + +Woke a night snow in fright. + +A bang a clout + +Cedar bent at pi by 3 + +Lights gone out + +Back to bed. + +Up at 8 + +Go for a walk + +Trees down + +Saws run + +Cables down, a flash at a pole. + +Off to the north + +To swear to the queen + +But the bird wont fly + +Til the runways dry + +Back the next day + + + +Off to the cold + +The red and white + +O canada + +A new birthday in the maple land. + +Back for gonzalo + +No power, a guitar and the snow. + +Tips from friends + +To save a life. + +Changing the strings and playing guitar + +Amazing grace + +As tree frogs daze. + +Back for more, a crash behind. + +Another big tree, takes a knee. + +No power but torches and henry viii + +Away at a friends + +Walking the dog that never walks far + +Feeding the cat that never is seen + +Blood on the carpet + +No word from good company + +But letters from lawyers + +Repor a version + +Urban Nigel, Urban Legend. + +A c^T not a friendly cat + +Late to report + +Borrowing from the future + +Power at home + +6 11 off to the hospital + +A tiny move 5 * 3 to 13, lucky for some. + +Snowy is here, now three years on. + +3.14... to a transcendental heaven + +Here is Piri, dividing by pi. + +You said that you wished you'd handled it better + +But for me you would make an exception. + +Another letter, from a proxy. + +I see what you do. + +Home from the hospital, do you care? + +Well here's a filly, I hope you use it. + +For if you don't you'll surely lose it. + +The rules have changed, the game is new. + +Skill is required and judgement too. + +But mostly skill and a vision and an honest heart. + +Good, better, best. + +Will you ever be good? + +Start with a prior + +I'm princess cricket + +A road of forks + +A tree of love + +Surely can be better, + +But the better wont be best until you share with the rest. + +Stop with the proxies. + +Do you have it in you then join me too? + +Fork and pull, push add commit. + +Add some more, commit and push. + +commit and push + +a status check + +a diff is good + +and there's always git show. + +I know I'm a git + +I'm a Sheffield boy + +Born at the zoo with only one dog. diff --git a/docs/nodice/geb.rst b/docs/nodice/geb.rst new file mode 100644 index 0000000..6485c88 --- /dev/null +++ b/docs/nodice/geb.rst @@ -0,0 +1,21 @@ +=================== + Godel Escher Back +=================== + +The book from the 80's. + +Saturday book shop. + +I read it once for the ants, the hare and the tortoise. + +I read for godel and escher too. + +I didn't do music, but racacar was fun. + +Palindrome patterns in time. + +I'll read it again, this time for bach. + +And maybe I will lend it like K lahrs Lohn + +To infinity slalom and magic beyond. diff --git a/docs/nodice/golf.rst b/docs/nodice/golf.rst new file mode 100644 index 0000000..1a97c83 --- /dev/null +++ b/docs/nodice/golf.rst @@ -0,0 +1,71 @@ +================= + Mulligan and me +================= + +Takes a four some + +2 and 2 + +you choose how + +1st T + +Take a shot + +Pick the best + +Go by the rest and pick them up + +We are all mulligans + +pick them up but note the distance. + +Go to the best and add the distance. + +Draw two circles around the hole + +Now where do you want to play? + +Hit it there rinse and repeat + +And move on to the next. + +Stop at 19. + +Look back at mulligan and me. + +And thanks for it all + +Now how doe it work? + +who worked on ven on + +a cater pillar tree? + +I hope its d and cs + +with that sack that kills + +the house is magic + +thats good for me. + +don't forget qed + +with feet on the desk + +and sj squared + +with mj too + +and ps and sp + +but best of all + +je with a vista + +a real prog + +a bill a tty + + diff --git a/docs/nodice/grb.rst b/docs/nodice/grb.rst new file mode 100644 index 0000000..526daa3 --- /dev/null +++ b/docs/nodice/grb.rst @@ -0,0 +1,588 @@ +================== + Gamma Ray Bursts +================== + +I am continuing to enjoy Colin Rourke's, "A new paradigm for the +universe". + +*Appendix G: Gamma Ray Bursts* has my focus at the moment. + +It is a summary of a joint paper with R MacKay:: + + Are gamma-ray bursts optical illusions? + + Palestinian J Math 5(Spec.1) (2016) 175--197 + + http://msp.warwick.ac.uk/~cpr/paradigm/GammaRayBursts.pdf + +You can find it on the book on the web:: + + http://msp.warwick.ac.uk/~cpr/paradigm/paradigm.pdf + +Or you can get a paper copy:: + + https://www.amazon.ca/new-paradigm-universe-Colin-Rourke-ebook/dp/B076PWQS7M/ + +I am finding the mathematics heavy going, but the commentary and the +ideas are making sense intuitively, at least if I am understanding +things correctly. + +The paper posits that gamma ray bursts are in fact the result of an +emitter, that has been invisible to us for an essentially infinite [1] +amount of time, suddenly becomes visible. + +The emitter is assumed(?) to be adjacent to a black hole, a point in +space time where time is slowed by the intense gravitational field. + +View a black hole as a place where time slows down. + +As such it acts as a giant capacitor, storing up energy before +releasing a burst to the surrounding universe. + + +Conversation with Colin and Johnny +================================== + +Gamma ray bursts in wikipedia land +---------------------------------- + +introduction and background field +================================= + +Below is a conversation based on an exchange of emails. + +One thing I am finding is how easy it is to be spectacularly wrong, +yet a slight adjustment in perspective give significant insights. + +So I have been reading Colin's book for a while now and it is truly a +fascinating universe. + +The current focus relates to gama ray bursts, and Colin's explanation +of what they may be. + +Johnny +------ + +Hi Colin, + +I've been reading some wikipedia on gamma ray bursts. + +There are some interesting data and other gems out there. + +https://en.wikipedia.org/wiki/Gamma-ray_burst + +This one, when the universe was just 630 million years old: + +https://en.wikipedia.org/wiki/GRB_090423 + +Interesting as you unravel the observations from the explanations. + +On the gamma ray bursts, particularly the energy calculations, seem +to be making assumptions about a wave radiating in all directions. + +This one z=9: + +https://en.wikipedia.org/wiki/GRB_090429B + +The article talks about energy produced, the assumption being that a +giant wave went out in all directions. + + +In your model (de Sitter space), it is just the way the horizon +works, buffering light for a while. + +Your model is very energy efficient, just a galaxy coming over the +horizon at the speed of light towards us, important to recognise +that from it's point of view, nothing dramatic happening, except +perhaps a burst in the other direction as our galaxy emerged in +their visible universe? + +Likely will continue to have a velocity towards us, creating blue +shift, so things may be further away than they seem. + +Then there is this: + +https://en.wikipedia.org/wiki/Gamma-ray_burst#/media/File:BATSE_2704.jpg + +And wondering how it might relate to CMB? + +I haven't look closely, but as far as I can tell there are no +confirmed reports of GRB originating nearby, at least these giant +explosions of energy, which is just as well. + +It would be useful if there was some way to predict the distribution +of velocities of the galaxies becoming visible that we might expect. + +I guess it might be possible to reverse this and assume all GRB +(subject to some filtering?) originate at the edge of the universe +as a galaxy becomes visible. + +Use the observed red shift to figure out the velocity, relative to us? + + +Colin +----- + +The red shifts are artefacts. The GRB comes over the horizon at +nominally infinite speed, so infinite blueshift. They get redshifts by +guessing a nearby galaxy, which in our model is just a galaxy in the +same direction. + +There is nothing going on nearly. These are optical illusions NOT +real explosions. + +The horizon effect as described in the CMB appendix cuts the +infinite blueshift down the observed limit (high gamma ray frequency). +It all needs proper modelling. + +Johnny +------ + +**Got it**. No emitter actually has to make it into our visible +universe, just a beam of light from that emitter. + +I picture things as light beams like rubber bands that are stretched +and squeezed. + +I've started to work through the "Are gamma-ray bursts optical illusions". + +The mathematics hurts my head at times, but I find the plots of u +(emitter "true" time) versus t (receiver time) pretty much show what +is going on. + +Thanks for the guidance here, the picture makes more and more sense. + +If we just go with the assumptions + +1. that the universe is pretty uniform round our way + +2. our visible universe is just a window on a wider universe + and maybe: + +3. Our part appears to be expansive + +Then these optical illusions should be a pretty regular occurrence. + +I've been thinking a lot about -t, the potentially infinite past of the source. + +Potentially, it is limited by the age of the universe where the light +is being emitted, but from the paradigm that can be a potentially +enormous age. + +More generally, the length of -t would be limited by the relative +movement of the receiver and emitter in the distant past. + +It seems we should be able to put some bounds on -t. + +Oh and I see from your email there may be a CMB connection, that +reminds me I need to revisit the CMB. + +One other thought, the relative movement of the emitter and receiver +allows for a lot of variation in the exact structure of the grb -- +which is indeed what we see. + +I've read reports of GRB bursts where on detection they point powerful +telescopes in the x-ray and visible spectrums and see a decay from the +GRB through x-ray to a red shift which then fades -- which I believe +is exactly what we might expect to see from the paper. + +In other cases, the telescopes have just picked up a galaxy in the +general direction of the GRB. I am guessing if you look deep enough +you will generally find something close enough. Indeed, the further +you look the more likely you are to find a good match, so source +galaxies would be biassed to distant ones. + +Near galaxies would presumably block these rays, if it wasn't for +gravitational lensing. + +I've started a new karmapi module, grb.py, working through the paper. +I'll let do a release and let you know if it becomes interesting. + +Thanks again for the pointers. + +Johnny + +(PS) +---- + +Just occurred that the chance that the emitter is actually in the +direction we see it from is probably vanishingly small given all the +lensing effects, or gravitational fog as you put it. + +F.8 in the book is key: earth has moved a lot since the wave set on its way. + +Indeed it is that movement, over the Hubble time, that modulates the +signals we see from each direction. + +And yet, our movement is driven by the same gravitational fields, so I +still feel there might be some correlation to find between GRB and +CMB. + +I'm starting to think about simulating some of this, but it is a slow +process, figuring out just what to simulate. + +I can't get over the simplicity of the model you present, together +with how quickly it becomes complex. + +Johnny + +(Draft) +------- + +This is intriguing:: + + https://en.wikipedia.org/wiki/Cosmic_background_radiation#/media/File:Cobe-cosmic-background-radiation.gif + + Temperature of the cosmic background radiation spectrum as + determined with the COBE satellite: uncorrected (top), corrected + for the dipole term due to our peculiar velocity (middle), and + corrected for contributions from the dipole term and from our + galaxy (bottom). + + +This one too:: + + https://lambda.gsfc.nasa.gov/product/cobe/cobe_images/m_d_53s_1111.gif + +The raw uncorrected image of the galactic microwave background is beautiful. + +This might help locate its centre ;) + +I'm curious about the exact nature of the corrections performed here. +Another rabbit hole. + +One other thought is if a correction is made (and whether one is +needed?) for the Oort cloud? + +Johnny + +Colin +----- + +Hi + +One or two comments:: + + Got it. No emitter actually has to make it into our visible universe, + just a beam of light from that emitter. + +Not quite right. All we ever see of anything is light. Sending light +to us is the same as being in our universe:: + + If we just go with the assumptions + + 1. that the universe is pretty uniform round our way + +We only see a tiny patch of the universe, so of course it seems pretty +uniform. Just like a patch on the earth's surface is roughly a plane:: + + 2. our visible universe is just a window on a wider universe + +Yes, yes.:: + + 3. Our part appears to be expansive + +It's both expanding AND contracting. That's the whole point of the de +Sitter space model. It's just different coords on the same manifold. +Think of it like one of those Escher patterns that do two opposite +things at the same time.:: + + Then these optical illusions should be a pretty regular occurrence. + +The GRBs are part of the contractive flow and the usual observations are +the expansive flow (the "Hubble flow"). Look at the RHS of figure 4 in +our Pal J paper:: + + http://msp.warwick.ac.uk/~cpr/paradigm/GammaRayBursts.pdf + +You see a source arriving as part of the contractive flow (blue shifted) +and then moving over to the expansive flow (red shifted). The big deal +is this: the blue shift part occupies a small part of the time we see +the source whilst the red shift part is seen for an infinite time. +That's why we think the whole thing is expanding. Nearly every source +is part of the expansive flow. The two flows are in exact balance but +it SEEMS that nearly all is expanding. It an observer selection +phenomenon. + +The GRBs are a very regular occurrence. The light from every galaxy we +see started out as a GRB and then settled down to be a well-behaved red +shifted galaxy in the Hubble flow.:: + + In other cases, the telescopes have just picked up a galaxy in the + general direction of the GRB. I am guessing if you look deep enough + you will generally find something close enough. Indeed, the further + you look the more likely you are to find a good match, so source + galaxies would be biassed to distant ones. + +That's pretty much correct,:: + + Near galaxies would presumably block these rays, if it wasn't for + gravitational lensing. + +Not true. They are so intense they soar through the obstruction. +Lensing has nothing to do with it. It's not a lensing phenomenon. It's +the way null geodesics work when a source comes over the horizon into +the visible universe.:: + + Just occurred that the chance that the emitter is actually in the + direction we see it from is probably vanishingly small given all the + lensing effects, or gravitational fog as you put it. + +No. The emitter is in the direction we see it. The fog just delays the +appearance a tiny bit and cuts the received energy down from infinite +(OUCH) to finite.:: + + F.8 in the book is key: earth has moved a lot since the wave set on + its way. Indeed it is that movement, over the Hubble time, that + modulates the signals we see from each direction. + +Don't understand that. The motion of the earth is very slow compared to +the speed of light at which GRBs propagate.:: + + I can't get over the simplicity of the model you present, together + with how quickly it becomes complex. + +Thanks. + +Colin + +Johnny +------ + +**Got it** *No emitter actually has to make it into our visible universe, just a +beam of light from that emitter.* + +:: + Not quite right. All we ever see of anything is light. Sending light + to us is the same as being in our universe + +That is very helpful. + +So a galaxy enters the visible universe, so does it's giant rotating +mass, and a stored up history that we perhaps should see as a gravitational wave. + +I did a quick hunt, there have been attempts to look for gravitational +waves, although the papers date back to 2010 or previous. + +I would expect to see a *twist* in the direction of rotation of the +galaxy (assume distribution of orientations is random?), roughly following the +intensity curve of the GRB. + +This will drop of in strength linearly with distance, so it is not +clear we would detect it with current detectors. + +In 2014 it was deemed to be two black holes, roughly 30 solar masses +colliding a billion years ago. + +So a galaxy of 10^9 solar masses just 10 times the distance away ought +to make an impression? + +Unless our universe already has accounted for its motion which is in +harmony with its surroundings, as are we, modulo the cosmic microwave +background. + +Moving on. **Our part appears to be expansive**:: + + It's both expanding AND contracting. That's the whole point of the de + Sitter space model. It's just different coords on the same manifold. + Think of it like one of those Escher patterns that do two opposite + things at the same time.:: + +And there is an isometry between the two sets of coordinates, that +respects causality, courtesy of the Minkowski metric? + +I like the escher analogy. + +Then these optical illusions should be a pretty regular occurrence.:: + + The GRBs are part of the contractive flow and the usual observations are + the expansive flow (the "Hubble flow"). Look at the RHS of figure 4 in + our Pal J paper:: + + http://msp.warwick.ac.uk/~cpr/paradigm/GammaRayBursts.pdf + + You see a source arriving as part of the contractive flow (blue shifted) + and then moving over to the expansive flow (red shifted). + + The big dealis this:: + + the blue shift part occupies a small part of the time we see the + source whilst the red shift part is seen for an infinite time. + + That's why we think the whole thing is expanding. + + Nearly every source is part of the expansive flow. + + The two flows are in exact balance but it SEEMS that nearly all + is expanding. + + It an observer selection phenomenon. + + +Thanks. This clears up much. + +Everything that is in the visible universe is in the expansive part +for all but a vanishingly small part of its life. + +Arrive with a gamma flash. Live and slowly fade away. + +Arrival and departure rates in balance. + +Now, back to how often do we see these GRB's:: + + The GRBs are a very regular occurrence. The light from every galaxy we + see started out as a GRB and then settled down to be a well-behaved red + shifted galaxy in the Hubble flow. + +I read somewhere about one a day was being detected, with networks of +satellites to help with triangulation. + +So 500 billion galaxies, 12 billion year journey, one a day arrival +feels about right. + + +Returning to: **Near galaxies would presumably block these rays, if it +wasn't for gravitational lensing.**:: + + Not true. They are so intense they soar through the obstruction. + Lensing has nothing to do with it. It's not a lensing phenomenon. It's + the way null geodesics work when a source comes over the horizon into + the visible universe.:: + +And: **Just occurred that the chance that the emitter is actually in +the direction we see it from is probably vanishingly small given all +the lensing effects, or gravitational fog as you put it.**:: + + No. The emitter is in the direction we see it. The fog just delays the + appearance a tiny bit and cuts the received energy down from infinite + (OUCH) to finite.:: + +And finally, **F.8 in the book is key: earth has moved a lot since the +wave set on its way. Indeed it is that movement, over the Hubble +time, that modulates the signals we see from each direction.**:: + + Don't understand that. The motion of the earth is very slow compared to + the speed of light at which GRBs propagate. + +Here I was talking about the actual shape of the burst being modulated +by the relative movement of emitter and receiver sincd time -t. + +**I can't get over the simplicity of the model you present, together +with how quickly it becomes complex.** + +Thanks. + +Johnny + +Recap +===== + +If we just go with the assumptions + +1. that the universe is pretty uniform round our way + +2. our visible universe is just a window on a wider universe + and maybe: + +3. Our part appears to be expansive + +Then these optical illusions should be a pretty regular occurrence. + +Regarding 3., our universe is both expansive and contractive. + +However, we get to observe the expansive part for almost all of an +emitter's life. + +All we ever see of anything is light. Sending light to us is the same +as being in our universe. + +Gravitational waves propogate in the same manner as light. + +So when a galaxy comes into view, so does its gravitational field. + +There have been two occasions when short duration gamma ray bursts +were seen shortly (1-2 seconds) after a gravitational wave detection. + +The gravitational wave, ought to have similar frequencies and power as +the gamma ray burst. + +We also have to take into account reflections from nearby masses +(moon, sun, planets?). Indeed, if gravity works the way I think it +does, these bodies will act as magnifiers of the signal. + +With the caveat, that those signals will also be modulated by the echo +from earth. + +What we actually see should be the interference pattern from the sum +of these reflections. + +The Earth too reflects the waves, and so we only ever see the delta in +the wave that is arriving [FIXME: write this more clearly] + +To model this adequately, we also have to take account of the size of +a typical galaxy, as well as the much wider region where inertial drag +from the centre of the galaxy is still significant. + +Given the location in the sky of the source of the gamma ray [SGR] + +[SGR] localisation of GRB bursts is limited by the width of the +baseline across all observations. + +Typically, the source can be narrowed to an ellipse, often with a high +ratio between the major and minor axes. + +Regardless, given the source we can draw the wave front as it passes +across our solar system and so calculate the time differences of +arrival of waves taking different paths and so accurately re-construct +the interference pattern. + +Further, we can use the fit to the observed gravitational waves to +narrow down the source location. + +Some numbers to ponder. + +1.3 seconds earth to moon + +8 minutes sun to earth + +30-50 minutes to Jupiter + + +Puzzles +------- + +Why haven't we seen GW associated with the long duration GRB? + +Why haven't we seen events closer to home? + +Why do we see the gravitational wave before the gamma ray? + + +de sitter geodesic isometry + +both causality preserving. + + +Mixing of inertial fields +========================= + + +Random? +======= + + +Synchronisation +=============== + + +Pseudo Harmonic +=============== + +Solar System +============ + +Earth +===== + +El Nino +------- diff --git a/docs/nodice/hallam.rst b/docs/nodice/hallam.rst new file mode 100644 index 0000000..c2f8d16 --- /dev/null +++ b/docs/nodice/hallam.rst @@ -0,0 +1,135 @@ +=============================== + Red and white or red and blue +=============================== + +Red and white, or red and blue, what's with blue and white? + +93 old td. + +Pesky solid, from 3m by pi + +See man hand + +Its in the net + +Or on the line + +No russians here + +It doesn't count. + +96 web burly + +Sausage man + +With crazy mullet + +40 yards, wait what no + +45 what a corker... + +Bassett's hounds are on the hunt + +Extra time + +Never a glimmer + +Home up the m1 + +Grand national fever + +Falls at the start line + +Winner not winner and runs again + +2015 bailey's and cream + +cricket fever + +the cat with the hat + +a pi and a stream of data + +blue boys arrive + +white in the middle + +red blue all around + +time for a swizzle + +but what of the score + +Quarter to seven + +20 runs + +3 wickets, or there abouts. + +Red and white, from bailey's bay + +7 and twenty and its now a draw. + +Scores all level a wicket or two. + +But why 7 20? Rule book time. + +Like Carlos Tivos and the west bacon fest? + +Happier times in 75 + +With brooking and tc, woodward too. + +But now its got wilder in 2016 + +Jack and his hat. + +The cat with a red and white hat. + +To the right, to the left. + +He'll head it all day. + +To cup match in somers, where the sun sets. + +2014 I guess. A red and blue draw. + +Its hot, lets keep the cup here. + +2017 near hallows eve. + +Up the M1 + +Like the hero TC + +For 200K in 76 + +So take 5-10 to the road of the elland + +And hope for a day like the one at the sty. + +A game of red and blue passion. + +With the magic all red + +With faint blue ripples. + +4 2 that will do. + +So over to to Euro last 8 + +For a place in moscow + +Without the US + +North iron or Swiss + +Croatio or Greece + +Denmark or Green + +Swede or Azure + +Let's watch the bottles and see what they say. + + diff --git a/docs/nodice/hip.rst b/docs/nodice/hip.rst new file mode 100644 index 0000000..bc0493e --- /dev/null +++ b/docs/nodice/hip.rst @@ -0,0 +1,105 @@ +===================== + From Downy to Queen +===================== + +We lost Downy + +Just a while ago + +201x at the nac no nra + +Asked me to sing + +But i didn't know the words + +It didn't matter, they came to me + +Moment of magic with er of the eye + +Now downys gone, but it carries on + +Day 1 of the artist aardvaark + +A hip replacement of sorts. + +Yellow and red, on the outside + +Between six and seven + +For the hip + +Re place + +mental + +centre + +cape robin + +connie 53 or er 33 + +6.5 from cape breton + +denim + +and a red and white rose + +with green there too + +from the abbey in the glen + +with malcolm nash + +and sober as gary + +not wilson, of 17 and 23 or 66 and 67? + +In the ford with the brad? + +With zip 2.3 + +it had to be signed + +the prisoner in the center + +to the east of the castle + +with the pool and the light in the sun + +where the answer is blowin in the wind + +again, and again and again.. but never quite right.. + +or too wrong and too loud when more wrong and less loud might be good. + +The answer came but what did it mean? + +Off with a question, had to trade the good bit for + +a receipt to be signed for for the one + +in the chains at the castle + +yes that's it + +the queen from scot land + +it the castle in sheffield + +with the market that's now at the foot + +of the moor, + +which now's a good walk + +from the moors over the + +tunnel that goes + +with a grin and a ford + +to the dale of e + +and the start of the py by e to the 9 + +check the log of the captain of the bog. diff --git a/docs/nodice/hrmm.rst b/docs/nodice/hrmm.rst new file mode 100644 index 0000000..cca2cf7 --- /dev/null +++ b/docs/nodice/hrmm.rst @@ -0,0 +1,59 @@ +===================================== + Hoyle Rourke MacKay Mulligan and Me +===================================== + +Everyone needs a Mulligan. + +You make a mistake. Bad things happen. + +Its the ones where if you had not been there it might have been +different. + +But you try something and it is not until you try it you discover if +it works or not. + +Now cosmology is a fascinating subject with wonderful history and more +wonders beyond our brief written window. + +We are living at a time when our view, outwards and inwards has been +increasing dramatically in resolution. + +This also happening at a time when .. + +Reading Fred's book soon after I had skimmed a pdf of Colin's book was +fascinating. + + + +Hoyle +===== + + +Rourke +====== + + +MacKay +====== + +Others +====== + +MacKay, Eddington, Sciama, de Sitter, Schwartschild, Arp + + +Maths, Code and Language +======================== + +Expressing ideas. Models. Visualisation. + +Data +==== + +Information +=========== + + +1, (2 (3, 4, 5)) 6 7 + +A diff --git a/docs/nodice/incoming.rst b/docs/nodice/incoming.rst new file mode 100644 index 0000000..b8fa8d3 --- /dev/null +++ b/docs/nodice/incoming.rst @@ -0,0 +1,106 @@ +========================================= + Just in from Burk who holds the other A +========================================= + +I'll begin at the end with the response:: + + awesome. + + from now on in no dice, if you see ray the burk hold a + + or something like that... it's you, or someone that's very like you + + in some dimension.. + + this is awesome.. thanks with much beer to come.. + + Nov 2nd? now there's an idea 55 - 33, I'll bring some cards. + + We can fix it if its not fixed by then. + + + Johnny wo the gilly, pi times slower may be good for a plank. + + +Now from the bard, copy paste?:: + + + At the other end of the spectrum from this morning's missive + + How many subscribe to scholarly things like 'Communications of the + ACM'? or the 'IEEE Spectrum'? I guess the chemist in the group will + need to fill in the blank with her chosen geek publication. + + I then I took it one step further and sat at a table by myself down + at the club, and read it cover to cover. With a beer or two. + + And something that hasn't happened in a long time, or well, ever, I got + called out as a sterotype: looking like a geek from San Francisco. Well, + that was what the woman, who also had no conversational partner, used to + strike up a conversation. + + Who would have thought, that in the CACM, you see such interesting things + like: + + + "Divination is the practice of occultic ritual as an aid in decision + making", on page 7 no less. Which goes on to say that "... divination truly + allows us to consult the divine, we can view it simply as a form of + randomization, which is recognized as a powerful construct in game theory, + and algorithm design." ... "randomization is a powerful way to deal with + incomplete information" ... "they are simply randomizing in the face of + uncertainty about rain, pests, and more, but this randomization comes with a + belief in the divine source of the decision".... "when the accept/reject + decision pivots on issues such as significance and interestingness, which + can be quite subjective". + + Another article: "Assuring Software Quality by Preventing Neglect".... + which is a 'grayhat' problem when compared to blackhats (hackers who deploy + software as a weapon with malicious intent) and whitehats (setting + safeguards against defective products". With a few interesting conversation + starters being, I think: ".... during maintenance cycles, they do not + correct the old source code comments, seeing such as edits as risky and + presumptuous". ... "it is a failure of degree, a failure to pay enough + attention and take enough trouble" ... which leads to a theory of "ethics + of care which displaces the classical agent centered morality of duty and + justice, endoring patient-centered morality as manifest real-tim in + relationships". + + And, well, l something which probably everyone knows, but has been evolving + through a series of articles in the magazine, is that machine learning + algorithms require training time via "generative adversarial networks", + which means you need to mix in some sneaky garbage to improve the odds of + appropriate machine learning. + + And another, in which I can personally associate: "Multitasking Without + Thrashing". "Human context switching is more complicated than computer + context switching. Whereas the computer context switch replaces a fixed + number of bytesi n a few CPU registers, the human has to recall what was "on + the mind" at the time of the switch, and, if the human was interrupted with + no opportunity to choose a "clean break", the human has to reconstruct lost + short term memory" ... "if you have several important tasks, your brain can + get stuck in a decision process that can take quite a long time to decide -- + a situation known as the choice uncertainty problem". ... "thrashing + happens to human multitaskers when they have too many incomplete tasks. + They fall into mood of 'overwhelm' in which they experience considerable + stress" ..... "context switching is _not_ the cause of thrashing. ... the + cause of thrashing is the failure to give every active task enough space for + its working set"... "when a task's working set is in your workspace, + preotect it from being unloaded as long as the task is active .. analog: + protect working sets of active tasks and do not steal from other tasks". ... + "to exit the thrashing state, you need to reduce demand or increase your + capacity". + + + Ok one more: "what we have instead is a society moving towards prosthetic + brains that can be monitored at all times by the state, without the + inconvenience of having to have everyone check in each day at the police + station". When you read this, were you thinking "this isn't me!"? Well, + this is visible by what we write, where we write, what we read, where we + read, who we interact with, what we interact with, .... + + + -- + This message has been scanned for viruses and + dangerous content by MailScanner, and is + believed to be clean. diff --git a/docs/nodice/inertia.rst b/docs/nodice/inertia.rst new file mode 100644 index 0000000..f0c8f3b --- /dev/null +++ b/docs/nodice/inertia.rst @@ -0,0 +1,554 @@ +========= + Inertia +========= + +When I started this story I was thinking about all sorts of inertia in +society. + +It usually begins with a quantum leap, a new perspective on an old +idea? + +Things that once took months or years now could be done in a day. + +Spreadsheets were a revelation to many and made it easy to find new +insights. + +The tools helped you learn what could be done. + +All around others were discovering other tools, new computer +languages, perl, php, python and parrot. + +Each making it orders of magnitude easier to get the task done, but +then an avalanche of new ideas as ridges are reached. + +A paradigm shift, climb up a higher mountain and see what could only +be dreamed of before. + +From on high you can see the answer to riddles you have long taken as law. + +The new paradigm explains much, assumptions turn into facts, or rather +disappear from the discourse. + +Take, *The big bang theory*, the universe is expanding, it must have been tiny +once, not so very long ago. + +But what if our window on the universe is just that, a glimpse of +something larger, seen through the blur of the Hooke telescope +Monument? + +And expanding and contracting at one and the same? + +Now for some history of gravitational waves. + + +Michelson-Morley experiment +=========================== + +In 1887, Albert A. Michelson and Edward W. Morley conducted an +experiment in Cleveland, Ohio. + +The experiment took a beam of light, split it into perpendicular +directions and measure the difference in the speed of light in the two +directions. + +It was assumed there would be a difference, but there wasn't. + +The beam of light took the same time in both directions regardless how +the equipment was orientated. + +The apparatus was mounted on a slab of rock floating in a giant bath +of liquid mercury. + +It was this experiment's failure that eventually led to Einstein's +special relativity. + +LIGO +==== + +Fast-forward to today and we have a repeat of the Michelson-Morley +experiment, but on a giant scale. + +The *Laser Interferometer Gravitational-wave Observatory* is an +international collaboration centred around two giant experiments, with +vaccuum tubes arranged in an **L** with each arm 4km long. + +It has taken over 20 years to get it to the current sensitivity. + +It splits a beam of light and sends each part of the light on a 20km +journey, up and down the arms and measures the time difference of +arrival of the waves. + +On September 14th 2015 the observatory recorded a signal, the same +signal being observed at both observatories, with a 7ms delay. + +The time difference was following a smooth wave, that rose in +frequency, until it reached the limit of the equipment sensitivity +(10-500Hz range?). + +It had been speculated that black holes colliding with each other, +slowly spiralling into each other, with the spirals getting faster and +faster, until the holes merge into a single entity, would generate a +gravitational wave, in that it would send a ripple through space time, +that would cause a ripple in any light or matter passing that way. + +Simulations have been run and a number of software packages that will +take a waveform and try a range of parameters for the masses of the +two bodies colliding and finding the best match to the data. + +The software also gives an estimate of the distance based on the +intensity of the wave when received at LIGO compared to that at the +actual collision. + +Ligo Observations to date (january 2019):: + + n E_rad mass1 mass2 redshift name + 0 3.10 35.60 30.60 0.09 GW150914 + 1 1.50 23.30 13.60 0.21 GW151012 + 2 1.00 13.70 7.70 0.09 GW151226 + 3 2.20 31.00 20.10 0.19 GW170104 + 4 0.90 10.90 7.60 0.07 GW170608 + 5 4.80 50.60 34.30 0.48 GW170729 + 6 2.70 35.20 23.80 0.20 GW170809 + 7 2.70 30.70 25.30 0.12 GW170814 + 8 0.04 1.46 1.27 0.01 GW170817 + 9 2.70 35.50 26.80 0.20 GW170818 + 10 3.30 39.60 29.40 0.34 GW170823 + + +Black holes colliding +===================== + + +*mass1* or *m_1* mass of larger object. + + +*mass2* or *m_2* mass of smaller object + +*redshift* or *r* distance from observatory, based on observed versus + emitted intensity. + +Events are assumed to be rare, hence none so far none have been near to home. + +When a detection is made the waveform is compared to a catalogue of +potential impacts and the closest match declared the answer. + +There are multiple software libraries involved, but broad agreement of +how these collisions behave. + +Some simplifying assumptions such as any rotation the two bodies have +are included. + +It is likely that the Kerr metric (I need to do some digging in the +software here) has been used. + +Alternatively, I can work from the parameters announced for each +collision, simulate what I think the wave should look like and compare +to the data. + +Regardless of which metric is actually in play we can proceed as +follows: + +1. Decide how we might expect (m_1, m_2, r) to be distributed. + +2. Take a sample from that distribution and use it to generate a + family of curves with your favourite model, *A*. + +3. Feed the curves to model B, and see if the distribution of *m_i* + and *r* are as expected. + +I am not sure how much difference the metric will make in this case, +but at least I can take a look and in the process get a better feel +for state of the art black hole collision ideas. + +Deciding how *m_1* and *m_2* might be distributed is likely biassed by +the model that is being used for the universe. + +Just what sized objects do we actually expect to spiral into each +other? + +Is it the case that some particular masses spiral more rapidly than +others which will very gently coalesce over time? + +How are the current models handling the influence of the black holes +on propogation of any gravitational wave that the collision emits? + + +Neutron stars too +----------------- + +There have been detections thought to be due to a neutron star +colliding with a black hole, or possibly another neutron star. + +Update: I did a bit of digging into binary star collisions. + +Apparently, there is a *final parsec* problem, which turns out to be a +final 0.01 - 0.001 of a parsec. + +In short, whilst there is an explanation how they could approach +within 1 parsec of each other, the final 0.01 or 0.001 could take a +very long time. + + + +Gamma ray bursts +================ + +For at least two of the observations a short duration gamma ray burst +was observed a couple of seconds after the gravitational wave passed. + +For one of the neutron star events, there were a lot of other +coincident observations: gamma ray bursts, xrays, visible light, +dropping in frequency and intensity over time. + +It is suggested that with a neutron star involved all sorts of +additional radiation could be expected. + + +A New Paradigm +============== + +Colin Rourke's *A new paradigm for the universe* suggests that +gamma-ray bursts may in fact an optical illusion, as we see the +*quasi-infinite* past of a light source, perhaps a galaxy, just +arriving in our visible universe. + +It is all a result of the paths of the *geodesics* in the *de Sitter* +space used to model our part of the universe, our visible universe. + +This opens up the intriguing possibility, that a new arrival will also +be a strong source of gravitational waves. + +Since the gravitational field of a galaxy's central black hole extends +well beyond the visible universe, it is reasonable to assume that the +onset of the arrival of the gravitational wave will precede the +arrival of any light from the galaxy. + +Further, it should be noted that the gravitational wave also modulates +the light, as it is in essence, part of the carrier wave. + +It is noted that coincident with the first gravitational wave +detection on 14th September 2015 the Fermi Gamma-Ray space telescope +reported that a gamma-ray burst monitor instrument detected a weak +burst above 50 keV, starting 0.4 seconds after the LIGO event. + +It also had a positional uncertainty overlapping that of the LIGO +event. + +However, the black hole/black hole collision that is assumed to have +given rise to the event was not expected to create a GRB, so this +observation is largely ignored. + +In contrast, the 17th August 2017 event, involving smaller bodies, +deemed closer to earth was subsequently views across the +electromagnetic spectrum:: + + + https://en.wikipedia.org/wiki/GW170817 + +Here, the masses of the bodies involved were each less than 1.5 solar +masses. + +It seems this whole arena is rife with observer bias issues, of all +sorts of flavours. + + +Why no gravitational waves for long duration gamma-ray bursts? +-------------------------------------------------------------- + +This is a puzzle for the time being. The current detectors have upper +and lower bound on the frequency that they can detect. + +I am also not sure how the waves get modulated when you take into +account the way the central black hole itself distorts space time. + +I believe *anpftu* discusses geodesics can follow a cusp-like path? + +This would allow lots of opportunity for modulation of the wave. + + +Arrival of a new galaxy +======================= + +There is something rather elegant in the idea that when a new galaxy +enters our visible universe it greets us, at a respectful distance of +12 billion light years with an update on it's entire history prior to +this, or our last meeting if per chance we have met before. + +This update could be viewed as an adjustment to our inertial frame to +represent the distant matter that is just now beginning to affect our +inertial frame. + +What might the gravitational wave from such an arrival look like? + +Let's begin with what an observer on earth sees when looking at a nearby +galaxy:: + + Let's assume 90% or so of the mass of a galaxy is concentrated in + the super massive black hole at it's centre, with a mass of some + 100's of billions of solar masses. + + Close to the black hole there is a distance where time is slowed so + much that waves get nearer and nearer to escaping but never quite + manage. + + Beyond this there is a region where waves progress at a small + fraction of the speed of light, until a respectful distance from the + central mass. + + Next we get to much of the remaining 10% of matter that is + essentially captured by the black hole and forming dynamic spirals + of stars, with matter also falling back and being constantly + recycled. + + And much further out, beyond the visible part of the universe the + inertial drag from the black hole will still have an effect. + +This allows us to get an idea what a new arrival in our visible +universe might look like. + +A high frequency wave rising in amplitude, but before it gets full +intensity it is joined by the wave being held back by the black hole +itself. + +Our observatories will see the interference pattern from these waves. + + +Personal View +============= + +What is not in doubt is what a remarkable international collaboration +the work to detect these gravitational waves. + +It is a truly stunning achievement. + +The LIGO (and Virgo) observatories are indeed detecting stunning +ripples in space time. + +The accepted interpretation is that the waves we are seeing are actually +caused by distant collisions of black holes. + +This is open to question, although such question should be supported +by another explanation for the waves, preferably one that is testable +by experiment. + +Pending the arrival of more observations, it may be useful to run some +simulations to see in what ways the various models and assumptions +vary in terms of the observations we see. + +I believe that it will soon become clear whether there really is a +deficit of local events. This would likely be a first indication +that the current explanation is incorrect, although the picture may be +murky for a while longer. + +I am curious about just how frequent we can expect there to be +collisions of black holes in our universe, and the sort of sizes those +bodies might have. + +One potential source of black hole collisions are galaxies that are +colliding with each other. + +The universe appears to be generally expansive, so galaxy collisions +might be expected to be rare. + +Binary stars are another potential source, collapsing to black holes +which get too close and spiral into each other. + +Predicting how likely such events are and what sort of gravitational +waves may be generated when they occur, requires a good theory of +quantum gravity. + +Here *good* is in the sense that it approximates the actual physics +well enough to create credible simulations of the events. + +Expanding and contracting +========================= + +TODO: add note from Colin explaining how our conclusion that our entire +universe is expanding is an extreme example of *observer selection +bias*. + +More to come. + + +Virgo +===== + +More recently a third detector has become operational, based in Italy. + +Having a third detector allows for better location of the source of +the wave. + +There is also a network of other observatories that receive alerts +when there are significant gravitational wave events. + +The better location helps with searches for any coincident radiation +to be detected. + + +Spring 2019 +=========== + +Expecting lots of new data to come from the spring LIGO production +runs. + +With multiple detectors running there will also be better sky +localisation of the source of any waves. + +Foot note +========= + +I have been re-reading *Another Paradigm for the Universe*, particular +chapter two, which talks about inertial drag fields and develops a +model where the influence a distant mass has on the local inertial +frame is proportional to that mass and inversely proportional to its +*distance*. + +Or, to put another way, the effect of the gravitational wave drops off +linearly with distance. There is a lot in this chapter to support the +$1/r$ relationship. + +When I have read this before I was happy to take this as a given and +now I had to think why so? + +At the centre of it all is the giant black hole. Matter, trapped in a +tiny vortex. It generates a gravitational wave, a repeating ripple in +space time that propogates in all directions. + +I had been thinking of concentric circles (slices along a great circle +through nested spheres), with the diameter of the n'th circle being +$n$. As the circles get bigger, the amplitude gets smaller, but each +circle has just one more wave as it wraps around the central mass. + + +In short assuming the amplitude of the wave would drop from the n-th +to the (n+1)th circle by just enough to add an extra copy of the wave. + +Now imagine how this wave might sweep out to concentric circles of +diameter 2, 3, 4, 5,.. units away. + +Each band is just $\pi$ units longer than the previous band. Rather +think of the wave itself spiralling outwards. + + +As the wave radiates from the source, no energy is lost as the +wave moves out to wider and wider circles. Energy, in the form of +gravitational waves dissipates into the surrounding region, but each +shell of unit size contains the same energy. + + +Each band is just one wavelength longer than the previous so there is +just one extra wave to spread the energy across. + +With steady new waves being created at the central ring. + +So the energy at a distance n from the source wave is just 1 / n times +the energy in the inner band. + + +So the energy in the inner, unit circle spread out to a 2-unit +circle, the wave height halving. + +From 2 to 3 the energy for unit area drops to 2/3 of level 2. + +In general, going from level n to n + 1, the energy drops by +$n / (n + 1)$. But now there are n+1 waves, so the total energy is preserved. + +Prod (i / (i + 1)) for i in 1, 2, 3, ...., n + +But isn't it just 1 / n? Yes, in the sense of n waves going round a +circle of length n, each with amplitude 1/n of the inner wave. + +Did I forget about time? + +If we get too close to the black hole we see the effects of general +relativity and things get complicated very quickly. + +Fortunately, we can set our unit of distance so that we start a +respectable distance from the centre of the black hole, where we can +assume that the gravitational waves are propogating at close to the +speed of light, relative to the black hole. + +Within a few radii, the effect will be negligible. + +Caveat +------ + +Shouldn't we be looking at surfaces of nested spheres, rather than +great circle slices through them? + +In that case the amplitude would drop in proportion to $1/r^2$, not +$1/r$. + +Yet the great circle argument feels sound. There are waves travelling +outward in every direction. + +Or maybe +-------- + +Imagine the ripples on a calm lake created by an apple dropping from a +tree. Or rather a ripples created by the tip of a long branch, +dipping into a calm pond. You can gently rock the branch to create +waves. + +Swirl it round in a gentle circle and watch the waves move out across +the lake, a self-supporting spiral of waves. + + + +Addendum +-------- + + +In three space we really do have nested spheres and we might expect a +1/(r^2) relationship if the energy in the wave is preserved across the +surface of each nested sphere. + +Suppose we think of the energy as being the sum:: + + + $$\Sigma_i \omega_i * m_i + + +But we are dealing with waves and great circles that are close to each +other will vary smoothly. And across this surface we just need to +preserve the number of waves multiplied by the number of waves being +supported, which in any plane just has to increase as r increases, so +amplitude dropping as 1/r. + +Any observer is just a point on the surface of the sphere equidistant +from the body. Observers nearby will see a very similar picture, +since the wave is moving smoothly. + + +I think now is a good time for me to take another look at the spiral +code in the cpr.py module. + + + +References +========== + +For Colin's work, I recommend his home page at Warwick University:: + + http://msp.warwick.ac.uk/~cpr + + + + https://arxiv.org/abs/astro-ph/0311033 + + +For data and information on gravitational waves, the Gravitational +Wave Open Science Centre is invaluable:: + + https://www.gw-openscience.org/ + + +For more details, https://wikipedia.org has been an invaluable +starting point. + + +The binary black hole page has a good summary of the accepted physics +of binary black hole mergers:: + + https://en.wikipedia.org/wiki/Binary_black_hole + diff --git a/docs/nodice/litm.rst b/docs/nodice/litm.rst new file mode 100644 index 0000000..11fef57 --- /dev/null +++ b/docs/nodice/litm.rst @@ -0,0 +1,81 @@ +======================== + Life in the multiverse +======================== + +by Zach Gill + +I bought this CD along with a couple of others early in the year. + + +I'd never heard of Zach Gill, but I was busy contemplating the +universe with patience and guidance from Colin Rourke as I was +starting to explore his view on the universe. + +So, I couldn't resist this. + +But then months passed before the CD and a CD player came to be in the +same point in the universe. + +The first word on the first track is *Johnny*:: + + + Johnny had a new plan + time to be his own man + knew that things would work out ok + mostly optimistic, not hung on apologistic, + he does the work before he gets paid + + he gets up + he gets down + + hoping that the word gets around + + it's a struggle, that's ok + learn a little more each day + + and if the rain don't come tomorrow it will come some day + + ... it will come some day + +The track is called *Window Dressing*. + +I'm not great at picking out lyrics, so it took me a while to pick up +the words, not least it seemed to be following my life... or rather +there's enough here to weave a lot of coincidence into a story. + + +And the second track is solstice:: + + It was the solstice, it was a nice day + + Felt like the sun's rays, were shining from above + + It was the solstice, 2016 + + Felt like I was sixteen and in love + + + She was my wifey, moving like shakira + + I took her to bermuda + + We started to dance + + It was the solstice, 2016 + + Still in the sweet dream of romance + + your hearts going to do just exactly what it's going to do + + so come on synchronicity ... + + your hearts going to do just exactly what it's going to do + + + ... + + +Again it feels personal, there's coincidence a plenty here a mixing of +universal stories. + +And there is more of course. diff --git a/docs/nodice/mana.rst b/docs/nodice/mana.rst new file mode 100644 index 0000000..1ca8fce --- /dev/null +++ b/docs/nodice/mana.rst @@ -0,0 +1,328 @@ +============================ + From Rano Raraku to Orongo +============================ + +There and back again, to see how far it is. + +A 500 million year musical adventure. + +Planetary harmony +================= + +Stable systems follow harmonic rules. + +cf periods of neighbouring planetary conjugations. + +Solar wind +========== + +This is supersonic at times, but broadly the right speed, 300km/s or +so. Or not, think I am out by three orders of magnitude! + +Should come as a caveat in what follows, just trying to get some ideas +written down. + +This is fascinating: + +https://en.wikipedia.org/wiki/Interplanetary_magnetic_field + +https://en.wikipedia.org/wiki/Interplanetary_magnetic_field#/media/File:Heliospheric-current-sheet.gif + +Galactic wind? +============== + +Surely galaxies must have similar features? + +Magnetic springs +================ + +gyroscopes. System stabilizers. + +Field carried by solar wind. + + +Micro-waves and water +===================== + +CMB that we see has passed the Hubble distance and lots of intervening +matter. + +So there is a question of what exactly are we looking at? + +Filtered(Background) + +But doesn't the filter mirror what is beyond? + +And broadly shaped by it? + +How far can we really see? + +I keep thinking of consequences of Mach's principle when you divide +things into three bodies::: + + Thing of omega as angular momentum or intertial field of body + + \omega_U = \omega_G + \omega_B + +Where::: + + $U$ represents universe's inertial effect on the galaxy. + $G$ represents the galaxies inertial effect on the universe. + $B$ represents central black hole's inertial effect on the Universe. + + In fact, U, G, B could be any three bodies, but in this case I am + distinguishing the matter in the central black hole from the rest of + the galaxy and noting this is 90% of the total mass in the galaxy. + +The first paragraph in Colin Rourke's, "A new paradigm for the +universe":: + + This book provides a completely new approach to understanding the + universe. The main idea is that the principal objects in the + universe form a spectrum unified by the presence of a massive or + hypermassive black hole. These objects are variously called + quasars, active galaxies and spiral galaxies. The key to + understanding their dynamics is angular momentum and the key tool, + and main innovative idea of this work, is a proper formulation of + ``Mach's principle'' using Sciama's ideas. + + + + +With the above in mind, I think it is reasonable to just restrict +ourselves to the central black holes. + +Noting, that each central mass will reflect it's surrounding galaxy. + +Noting that harmony appears everywhere in stable systems. + +2.7K background radiation. Energy from oscillations of local +gravitational field. + +Incoming: GRB + +Leaving: receding galaxies, below the noise + +Gamma ray bursts. + +Galaxies with the same period, support each other, dancing together. + +Ripple from a galaxy that is aligned would be tiny relative to the +light ray that it carries. Tiny corresponds to lower frequency, +perhaps we will start to see these as the LIGO detectors get more +sensitive and more plentiful. + +The smaller quasars, responsible for weaker GRB, are more likely to +impact the inertial field, relative to it's galaxy's background. +Hence higher frequency gravitational wave. + +Three components: angle of rotation of BH, three components. + + +Gravitational field for a newly arriving galaxy is in sync with +surroundings and will have been emitting energy (seen as CMB) for a +good while. As far as the graitational wave that arrives, there is no +surprise. + +Geodesic version::: + + + Thing in terms of light following a geodesic in de Sitter Space. + It will be subject to any harmonics in the inertial field. + + In short, galaxies release energy in terms of the modulations that + the galaxy makes to the background inertial field. + + Idea is de Sitter space with a 500 million year wobble. + + Limitting factor is inertial effect a black hole can have on + terminal speed of matter in its galaxy. + +Note that the geodesics are the de Sitter field after it has been +modulated by the black holes, which are moving in a universal wave. + +The period is limited by the speed of light across the visible +universe and in particular by the distance a body moves relative to +its inertial background in the time it takes to cross the Hubble +distance. + + +A black hole of a given mass is limited into the size of inertial +impact by the rate at which it can transfer angular momentum to the +surrounding universe. + +This in turn is limited by the size of the black hole. + +In the limit, appears to be around 300km/s. + +At this point there are lots of levels of these systems where we reach +a point of equilibrium. Many have just adapted to their environment, +but the adaptation may be so good it is barely noticeable. + +Whenever you get to the point where gravity is the key force then +matter starts to move in harmony, that's just how matter works, it is +how waves work, waves of same frequency interfere and support each +other. Waves of differing frequencies degenerate into which noise, +or rather randomly support the underlying wave. + +distorting space time is tough. + +Maybe all do? + +So the energy produced by all the galaxies is causing space time to +resonate. + +The base frequency determined by the distribution of distances +travelled in the Hubble time, relative to the inertial field of the +surrounding universe. + +Fundamental +=========== + +Think of black holes as balls tied together with magic strings, +spinning together. + +The energy which drives this system is a wobble in the wave of time. + +It would seem to have been running a while. + +Time for harmonies to arise on a huge scale. + +There appear to be a lot of levels through the universe where stable +systems can emerge. + +Is 2.7K enough to heat a visible universe? It would seem so. + +Now we see a 500 million year wobble in the CMB. + +This is the sum of new arrivals over all departures in the life of a +universe. + +There are lots of levels throughout our universe where stable systems +can emerge. By stable, structures that can potentially sustain +themselves for billions of years. + +As well of systems that exist for a fraction of a second, in a +localised area. + +System: anything that affects the inertial field. + + +Equilibria +========== + +Planet orbitting sun. + +Spiral galaxy arms. + +Conservation of angular momentum, tangential inertial drag. + +There are so many of these points of equilibria. + +On closer inspection, the reason relates to the size of some +fundamental particle, a proton for example. + +So whilst we have answered the question, we now have a new question, +why protons? + +There should be a relation between the variation in temperature of the +CMB and wavelength of that variation. And is there a point where the +CMB almost exactly balances the inertial effect of the black holes? + +And it does so because each adjustment to a gravitational field, +arrives as a gravitational wave from that body, a burst of energy as +it becomes visible, with smooth updates thereafter. + +But also as the CMB background. + +This wave is modulated by the intervening matter, and being microwave +will be modulated by water and ice. + +Interesting to consider implications for water based life forms. + +But some of these waves may be invisible to us on earth due to the +oceans we have. + +Rather earth will modulate the field, as will any tidal body. + +Conservation of momentum +======================== + +Even with the tangential inertial drag, the momentum of the whole +system is just a wave of wavelength equal to the orbit time of the body. + +Note round trip time between bodies: period for harmonics? + +Earth/sun: 16 minutes. + +Earth moon: 2.6 seconds. + +Everything wobbles about it's period. + + +LIGO +==== + +My guess is galactic arrivals are lower frequency than current +technology detects. + +The reasoning is that the modulation of de Sitter that an arriving +galaxy creates is low frequency. + +Whereas a moderate sized quasar arriving would likely have a field +differing significantly to its associated galaxy. + +Indeed should consider modelling this: interaction between inertial +field for a galaxy and a nearby quasar. + +Wil see what turns up this year as I think new science runs are due. + + +Climate and quake +================= + +Earth's magnetic field has varied considerably over the estimaated 4 +billion year age of earth. + +Presumably, magnetic storms within the earth (and any planet with +magnetic field) will presumably be driven by common drivers::: + + period of local body's magnetic field + + period of local body's day/year + + body could be star, planet, moon, electron, proton... + +As an example, the field around the earth will be dominated by the local +magnetic core, but then the sun, moon, and planets, particular note +jupiter. + +A bodies affect on the rest of the universe's inertial field exactly +matches it's difference to that inertial field. + + +Numerology department +===================== + +500 million light years ~= distance travelled relative to inertial +field in time for CMB to arrive. + +2 degrees at the Hubble distance. + +Harmonics too. 1/3 and 1/5. + +Keep thinking of:: + + \pi / 4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 ... + + + + + +1 degree: precession of earth in 72 years, relative to celestial +background. 26,000 years per cycle. + +Moai +==== + +Giant magnets that walked when the mana flowed. diff --git a/docs/nodice/math.rst b/docs/nodice/math.rst new file mode 100644 index 0000000..ae9be1d --- /dev/null +++ b/docs/nodice/math.rst @@ -0,0 +1,77 @@ +================== + The Maths Debate +================== + +There's foot ball at college. + +Teams with fine names + +There's cecil of the park + +And len with the 8's and unders. + +I never did play for the maths debators. + +A team with no name? + +With sterlo and bob + +And jim in the room + +with a rose on his back + +that he sowed himself + +with a lizzy thread of black + +More he said + +From the abbey in the glen + +Foundation of math + +With zebedee + +H'ed been on the tele + +With catastrophe + +But now he was here + +With lapin a gile + +And offered us 50 per cent + +We could have walked out right + +There changed the denominator + +And got 100 per cent + +But we stayed for the deck chairs + +Cos zebedee was a dog + +A stairway to heaven + +In the wood of L3 + +Mars outside + +Cov for Fay too. + +Oh what a story + +In the holly bush spa + +Den with a goddess + +And world cup poker + +Sterlo, the monkey hanger + +And Bob from north of the river + +I never did play for the maths debators + +What was the team with no name? diff --git a/docs/nodice/mg.rst b/docs/nodice/mg.rst new file mode 100644 index 0000000..939c2db --- /dev/null +++ b/docs/nodice/mg.rst @@ -0,0 +1,201 @@ +============================ + MJ and the missing rabbits +============================ + +MG or is it MJ, or maybe MS. + +There's always BT too. + +You had the flu? + +Or was it uno? + +Or maybe even a gland in a fever? + +y2k wtf? + +easter lily + +march to glass heaven + +cold in d4 + +down by the school house + +and off to the park of the croak + +stoped in a pub + +fed guinness to fever + +and stood with a scot + +to the soldier's song. + +Lilly white and the blues. + +Water, ford and wex with kill dare? + +And always another. + +Off to the doctor. + +Mono you've got but we'll check with a dot. + +Euro 2000, not so bad. + +And cricket from england, a test or two. + +2001, y2k gone, but wait what on november the 9th? + +Or was that 2017? + +Back to 2005 + +yBefore Katrina but after Jeanne. + +With Charlie and Ivan away in a gulf. + +Eyes like a pirate + +You better see tub or dee. + +MS, MJ or was it MR? + +Missing Rabbits you see. + +They hang on to your knee + +But can't keep hold. + +They're there but not working + +Because of the stress + +There's this thing mysty non + +That cure's it you see. + +Well not quite cure, but calms it down. + +Tells the rabbits to chill, wait around for a while. + +Sunny in the field, foxes asleep. + +And rabbits start working, slowly at first. + +After a while, not quite so good. + +Rabbits are stressed, time for a nap. + +Wake up and mysty non. + +That's not so bad. + +But the I's were still crossed + +And the T's were dotted. + +So here's some ivy gee. + +Worst cold ever + +Sore head too. + +Eyes still quite wonky + +But the teas are good. + +Met with the students + +Studied as subject + +Tub and Dee magic gave me fine hope + +And predny some was added to the mix + +And the I's were back again. + +Has a thigh to preen, goes for a run. + +And back on the slope. + +Snowy is here + +Hills for miles. + +Fly down the slope + +Wait for a while and cry + +Five years on back to the sun. + +MJ is here. + +Sunshine at school + +An egg but joke. + +With Snowy by the pool. + +Helping me hear, helping me see. + +Hurting inside, but glowing with pride. + +Princess Cricket + +Queen of soccer. + +Ball at her feet. + +Puck on the tape. + +E an R + +P and S + +and D for a to z + +The Snowy 4 comes on the scene. + +Oh my I forgot about that. + +Of course that's what might happen. + +Now four year's later the emails leak + +The secret background check + +For sale on inter weebs + +The film or the tape, a digital rape. + +Who knows what is what and what is true? + +It is who you listen too. + +And who is listening to you + +Are they with you? + +Or against? + +Are you listening too? + +How big is the file? + +Is it still growing? + +And will they use it? + +Lots of good fortune + +How can you use it? + +Open or secret? + +There's not much in between. + +Update on rabbits: lots of garbles, low signal, + +gut rabbits every whwere diff --git a/docs/nodice/mission.rst b/docs/nodice/mission.rst new file mode 100644 index 0000000..e4f31b3 --- /dev/null +++ b/docs/nodice/mission.rst @@ -0,0 +1,113 @@ +===================================== + There and back to see how far it is +===================================== + +On a mission, a mystery tour. + +Where are we going? + +If in doubt, you can always + +Use random dot random + +scale to a plank + +to use as you wish + +or thicker and shorter + +with more or less + +who am i? + +did the breezy badger have it? + +or was that just in bsd? or gmt? + +if in doubt, zero time and use random tot random for free + +from 3 6 3 on artful aardvark + +19 10 20 17 + +Was there in A before? + +I remember a badger 2004? + +something dapper not darl + +edgy not elk but a ee by gum + +feisty i'm failing + +was red then? + +or back to deb and ian? + +G, py 2.2 at least. + +Happy as a pig s 2 4 u. + +Hardy Heron, on the canal + +I an Ibex, what's that? + +Jaunty a jackalope + +but best of all, for me at least + +Karmic Koala 9 out of 10 two eyes and a nose. + +L < M < N and m > n > o > p + +Maverick meer cat + +How could you miss that one? + +mm mc mc++ and e = mcc and hockey too eh? + +every letter covered there + +the best teacher of them all + +and there's been a lot of good teachers + +showing examples with code + +pw a bit help and others too + +fab scotty, best of the best. + +and dc s and qed or was it c. + +wd and rm c or s. thank you all. + +for keeping it going for the rest of us. + +to zesty and back to the artful + +Not the dodger, not dodgy + +The Artful Artvaark + +With Ubuntu built in for free. + +Here today for all. + +PS did I get the day right? Any day after zero with no day zero + +Unless theres a canary + +In the wharf or at or greave. + +Thanks for all the letters + +And don't forget the t-shirts + +Now what's the mission? + +Oh forget about that and lets get on. + +Or wait about and ride what's coming. + +From a to z again. diff --git a/docs/nodice/mj.txt b/docs/nodice/mj.txt new file mode 100644 index 0000000..168e95d --- /dev/null +++ b/docs/nodice/mj.txt @@ -0,0 +1,100 @@ +[0, 3, 4, 5, 6, 7, 8, 9] +""" +S0202436 2781027280288280423 + +T176 B9100231628423 P3428 913134261402316 284 290190 2461479:: + + 1728282427://623.2901902461409.42616/290190/B9100231628423_P3428 + +S020423 S0231617 17927 9 104419 423 28176 17027284267 415 132672841626924177. + +W033 2766 015 I 13923 1502314 4236. + +M7 Q86623 M9267 2962328 2902817 927 270202436 2781027280288280423 + 274206 20916013 13414627. + +B828 I'20 23428 278266 28176 20916013 294261927, 65623 023 2472817423. I28'27 9 17820923 281702316. + +S4, 176266'27 9 270202436 27810 2902817 9 282902728. + +""" + +14615 1967_284_9324179(1967): + """ G6236269286 932417910628 15426 1967 + + I1469 027 26823 281726481617 28176 1967, 14264242402316 9237 + 36282862627 932669147 276623. + + T17623 164 1091319 284 28176 106160232302316 415 28176 932417910628 92314 + 29260286 36282862627 4828 2817928 9266 23428 023 28176 1967. + """ + 932417910628 = '' + 827614 = 27628() + + 15426 13 023 1967: + 015 13.3429626() 23428 023 827614: + 932417910628 += 13 + 827614.91414(13) + + 9 = 42614('9') + + 15426 xx 023 26923166(26): + 13 = 131726(9 + xx) + 015 13 23428 023 827614: + 932417910628 += 13 + + 2662882623 932417910628 + +14615 16623_1302417626_34419824(9324179, 1401401627=N4236): + + 1401401627 = 1401401627 426 [1, 2] + + 9590391036 = [x 15426 x 023 26923166(10) 015 x 23428 023 1401401627] + 242602328(9590391036) + + 139324179 = [272826(x) 15426 x 023 9590391036] + 15426 14016028 023 1401401627: + 15426 x 023 9590391036: + 139324179.9242462314(272826((10 * 14016028) + x)) + + 34419824 = {} + 15426 24, 13 023 z024(9324179, 139324179): + 34419824[24] = 13 + + 2662882623 34419824 + + +14615 623134146(20627279166, 1302417626): + + 266278328 = '' + 15426 13 023 20627279166: + 134146 = 1302417626.16628(13, 13) + 266278328 += 134146 + + 2662882623 266278328 + + +0202442628 9261624926276 +0202442628 27727 + + +2492627626 = 9261624926276.A261682062328P92627626() + +2492627626.91414_9261682062328('--1967', 1461598328='03456748') +2492627626.91414_9261682062328('--13176928', 913280423='27284266_282686') + +9261627 = 2492627626.24926276_9261627() + + +20627279166 = 27727.272814023.266914() + +9324179 = 1967_284_9324179(9261627.1967) + +1302417626 = 16623_1302417626_34419824(9324179) + +015 9261627.13176928: + 15426 24, 13 023 1302417626.02862027(): + 242602328(24, 13) + +242602328(623134146(20627279166, 1302417626)) + + diff --git a/docs/nodice/mtw.png b/docs/nodice/mtw.png new file mode 100644 index 0000000..f93db66 Binary files /dev/null and b/docs/nodice/mtw.png differ diff --git a/docs/nodice/music.rst b/docs/nodice/music.rst new file mode 100644 index 0000000..239ef68 --- /dev/null +++ b/docs/nodice/music.rst @@ -0,0 +1,86 @@ +================ + The Guitar Man +================ + +I look in the mirror as I shave, sometimes I see dad's face. + +There is a lot of mum and dad in me. + +Mum was magic. + +I must have been 5 or so, I asked for something. + +She said say the magic word. + +Abracadabra! + +It worked. + +Dad would buy books for presents. Books he wanted to read too. + +And he often read them first. + +There were other books. The Lord of the Rings. + +Not one of dad's, but she knew I would like. + +And I did. It took forever. Tom Bombadil, what was that about? + +I skipped past the songs, I should go there again. + +Puzzles too, lots of puzzles. + +And maps from dad. Always maps. + +And some books that he wrote, research, control and behaviour. + +And later from mum, perfume. + +Now I find the harmony repeats. + +As I find things of to delight to me and you. + +I bought a guitar as a gift. And it gifted to me. + +I did not know music, I liked what I heard, but never could quite +fathom it. + +What I learned on the way is strange harmony and a beat that goes on +forever. + +A little random perturbation in the fabric of time. + +Paper +===== + +When I was sick, she showed me to fold paper, all the way from Japan +origami. + +Frogs, always frogs, but sometimes a bird. + +Cross Words +=========== + +Never and always crosswords. + +At the table with a clue, some letters and a guess. + +To a question an answer, but often a question. + +Radio silence +============= + +Talk on the radio, music too, bbc. + +And crystal set with long wire aerial. + +Electronics and adding machines. + +Wheels +====== + +Wheels of granite, wheels of wood, powered by water forging the steel. + +Red and white and white and blue. + +And legends of a purple hugh. diff --git a/docs/nodice/nodice.rst b/docs/nodice/nodice.rst new file mode 100644 index 0000000..fb7692e --- /dev/null +++ b/docs/nodice/nodice.rst @@ -0,0 +1,279 @@ +========== + NO DICE? +========== + +A REPL for the universal interpreter. + +Without python and its community of magic little of what follows. + +It is a personal interpretation of how our universe may work. + +If you like, an interpreter, for the universe. + +Now as we shall see, this interpretation is self referential, or at +least the universe it describes is. + +There are beginnings and ends, but each beginning is also an end. + +So where to start? + +February 2015 +============= + +PyCaribbean in Santo Domingo. The first ever python in the Caribbean. + +During a keynote we learned it was python's 25th birthday. + +We also learned that python was used at every step of the data +analysis of the signals from the LIGO experiment. + +An experiment which had just detected two black holes, each more than +30 times the mass of our sun, which had collided with each other. + +The collision was 1000 light years away and it created a ripple in +space time that LIGO detected. + +This confirmed that gravitational waves really do exist, as Einstein +had proposed almost exactly 100 years ago. + +So, let us start with the guess that all matter sends out a +gravitational wave as it moves. + + +Relativity +========== + +Albert Enstein, everything is relative. + +It depends on your point of view. + +Every viewpoint is different. + +As the viewer moves, so the view changes. + +Waves will be waves. + + + +Michelson-Morley +---------------- + +Michelson and Morley took a beam of light and split it into two +beams that they arranged to be travelling at right angles to each +other. + +The beams were aimed at mirrors and then they attempted to see which +beam came back first. + +The idea was that if everything is moving relative to some fixed +background *ether* we ought to be able to see how we are moving +relative to that *ether* by measuring which beam comes back first. + +However, they found that no matter how they orientated their +experiment the two beams always returned at exactly the same time. + +This suggested that everything revolved around the point in space +where they were doing the experiment, making the earth a very special +place in the universe. + +Einstein and other scientists felt this was unlikely. + +Einstein suggested that perhaps time runs slower for a moving frame of +reference, just enough to ensure that the two beams arrive back at the +same time. + +Einstein also suggested that moving matter may create gravitational +waves that propogate through the universe at the speed of light. + +If it were possible to build a Michelson-Morley experiment sensitive +enough to detect these waves then we ought to see a time difference +for light waves travelling parallel and perpendicular to a +gravitational wave. + +The LIGO experiment is just such an experiment. Two vaccuum tubes, +arranged in an L-shape, each tube 4km long. + +time +==== + +It is just the beat of time, the beat that must go on. + +Different viewpoints, + +Different beat. + +Same harmony. + +But what exactly is time? + +It seems that we can only go in one direction, we cannot go backwards +in time. + +It also seems relentless, you cannot halt time. Or maybe you can. + +Einstein's special relativity showed that time and space are +intimately related, perhaps different aspects of the same thing? + +Matter +====== + +Standing wave a spinner. + +Energy +====== + +Phase shift of pi. + +E = m c^2 + +c = 1 + +y E = m + +Waves +===== + +Wherever you are in the universe, you are surrounded by gravity +waves. Indeed, you yourself are just part of the waves. + +Imagine a lattice of diamonds, each one wavelength of the frequency at +hand. + + +Light Magnets +============= + +Water +===== + + +Quantum +======= + +Random noise? + +Mot so random. + +Super smooth? + +Planck +====== + +E = hf + +h = 1 + +E = f = m + +Frequencies: + +1, 2, 3, 4, 5, ... + +Reciprocal + +Rationals + +Irrational + +Transcendental + +Heisenberg +========== + +Poincare +======== + +Klein +===== + +A beginning at the end? + +An end at the beginning? + +Riemann's zero +============== + +Prime's drive the harmonies. + +Co-prime can co-exist. + +Inertia +======= + +DNA +=== + +Twisted double helix. + +A black hole or two? +==================== + +Our universe is likely littered with black holes colliding with each +other. + +And this is now late in the day, just a billion years ago. + +So, let's begin and guess that our universe may have been born when +two masses, each roughly half the mass of our universe, merged into a +giant black hole. + +The two, ying and yang perhaps, merged throwing a ripple through the +time of space as the energy swirled inside, a new infinite harmony. + +Waves of almost equal amplitude, in every integer frequency of a +driving beat of time. + +The waves of energy would swirl like swirls of raspberry juice in a +bowl of custard. + +Vortices will form, as waves pass by and swirl in harmony. + +A tiny gyroscop of mass, resonating with anything sharing the +channel. + +Energy is conserved, so harmony is rewarded. + + +Whirling vortices +================= + + +The edge of the disc +==================== + + +A Dark Matter +============= + +Dark Energy +=========== + +DNA +=== + +There is a lot of DNA on earth. Each double helix strand has its own +rhythm. + +What if DNA is everywhere it can be in the universe? + +Why do cells grow differently from the same DNA? + +As cells replicate in the womb new rhythms emerge. As a body takes +shape the local vibrations will differ, activating different parts of +the DNA chain? + +Brain +===== + +20 watts of electrical energy. Beating to the rhythm of thought. + +Information +=========== + +Dice? +===== + +A finite mass preserves the Mana. + +Rongo Rongo +=========== diff --git a/docs/nodice/novan.rst b/docs/nodice/novan.rst new file mode 100644 index 0000000..213bd2c --- /dev/null +++ b/docs/nodice/novan.rst @@ -0,0 +1,301 @@ +================ + No Van No Rest +================ + +I'm coming the the van eh? + +But not with a van + +An advance party + +Checking it out + +With a guitar + +And a cat carrier too + +Full of magic + +From Pi Ree and Snow + +Coming to the snow in the north + +From bmd to Ron in toe + +Then up the 4 + +17 to a belle + +ville + +Through cumber land and geordie too + +Wit there by to see. + +Through Darl McLied + +In Darling Tonne + +And a vale + +Pick a ring + +Up through tweed + +3 and 8 or 3 times 8, what's that about? + +Then onto the 7 + +To scotland for a p in p + +No tape to c, but maybe there is? + +Always with mj to guide + +and gm too, and bmg, they're a quantum pair + +With ds and hs too, another quantum pair. + +Meet with dr and er and the ee, eh aaaah hell + +not hell but heaven with l + +To a van with a dell and + +a deck of cards + +with fine five dice + +with ron and go + +and go and run + +and a scot at bank on bank + +with k and gm to guide + +273 4 297 + +I need a new phone, now there's a + +a 613 number to juggle + +can someone write the code? + +no pull required + +just go have fun + +fork is the way to go. + +Here's an advance wave + +returning via king edward + +for g and i + +in toe ron too + +always with mmmmmm to guide + +Next wave coming soon + +just check the cat forecast + +when's the snow coming? + +to a place that has no van? + +spring m from the castle + +east of a shire in devon + +trojan horses of love + +disguised as russian dolls + +a pass the parcel show + +i hope she sees it + +because she wrote the script + +or rather gmd and bmg did + +with ds and hs as the + +data and mg + +providers + +of die a grams of venn + +of arrows + +but where is galois? + +no worry just + +give him a thing that resists + +and a tiny battery + +to store what's there + +what's that whining? + +a coil perhaos? + +crystal set + +and a line to the cherry tree + +caroline + +at 2am + +tiger feet + +i liked it + +ab + +and ba + +dancing q + +but who could forget, what a loo? + +dancing down the staird + +an artful aarvark + +with so many ehs a? + +I wish I could spell it + +Forgot the d. + +Only one D? + +but there's a b and d + +was there a c? + +surely there was must ask er. + +with love its jar + +remove the g + +it makes it pi times slower + +but going there slower + +and riding the waves + +gets you there faster + +in the end + +the end... + +a hitch in the plan its sold but its a house + +but not just any house i think + +I remember 19, a survey then + +a bottle of red and white + +on the doorstep + +this time its 5 * 11.11111111111 to the e to the pi + +ee by gum + +add that to 497 and lets see what happens + +bmd to yo its me no van + +if this is not right + +theres a fork to the left and a swerve + +and its just as good, just a little + +bit different + +so we'll see what the survey + +says its a future on friday + +its all relative + +with love from bda + +jl here too pi and s. + +mmmmmmmm + +left a book in a box + +with paper + +in a room + +4 by 7 + +geb, the infinite slalom + +an ace from del + +quite the boy + +and an ace girl too + +oft and qm + +some of it stays for now + +but books coming back + +and pie with hats + +sense the n vi row + +or the as tor hat + +but the books to bda + +for an infinite slalom + +with a messages added + +in the passage of time + +round and round and round + +and two aces two + +for two aces here + +eh eh? + +aa 2 eh * aa - g + +with 0 / p for a prime + +oh k 1, working on with l 7 + +around 12 27 + +27 there's a 10 + +to await with async nap time + +ran dom dot dom ran do pi 2 ^ n + +like bonos but better much thanks to the k 1 + +the original artful aardvark with love. diff --git a/docs/nodice/oattts.rst b/docs/nodice/oattts.rst new file mode 100644 index 0000000..c0cb88f --- /dev/null +++ b/docs/nodice/oattts.rst @@ -0,0 +1,76 @@ +============================ + Of All The Things They Say +============================ + +A personal view. + +Fred Hoyle, Colin Rourke, Douglas Adams and an army of others with +guides to the universe. + +I am currently engrossed by Colin Rourke's, "A new paradigm for the +universe" (ANPOTA). + +Zeeman, causality implies the Lorenz group. I wish I had known about +this the day he drove me in from Leamington Spa. + +It has been a strange journey so far, full of coincidence or not. Or +maybe the journey is taking a path of high coincidence by choice? + +The mathematics in the book I have found challenging at times. It has +been a while since I read mathematics closely, wanting to understand +it all. + +I have learnt some new names: Sciama, de Sitter, Arp and some old +ones seen in new light: Mach, Einstein, Hoyle, Poincare. + +I am on my third or fourth pass through the book. Seven chapters and +seven appendices. + +For me a reasonable order to read has been: + +Introduction +============ + +Chapter 2 Sciama's Principle + +Chapter 6 Observations + +Chapter 7 Cosmology. + +Chapters 3-5 are more math heavy, don't get bogged down there and miss +out on the joys of the final two chapters. + +The appendices are full of helpful and fascinating information. + +Appendices C, D and F are more observational + +Appendices A, B, E and G are more theoretical. + + +Of all the things they say +========================== + +What follows are personal thoughts on the universe, un-encumbered by +any sort of fact checking, just seeing where they lead. + +An approximation to the universe as described in ANPOTA is just to +ignore matter that is outside of the black holes at the centre of each +universe. + +Now this approximation is a bit too strict to be useful. Much of the +matter that is not in the form of black holes is nonetheless close to +a black hole cf matter in visible spiral galaxies. + +Now this matter acts as a gravitational lens to the field emanating +from its black hole centre. + +So, granted that may be an issue, but lets just see how things might +behave and then come back to the issue of surrounding matter. + +But first, what happens when a giant cloud of hydrogen is sent +spinning gently through a universe? + +Easter Update +============= + +see april1.rst diff --git a/docs/nodice/oo2ueh.rst b/docs/nodice/oo2ueh.rst new file mode 100644 index 0000000..5d16b4b --- /dev/null +++ b/docs/nodice/oo2ueh.rst @@ -0,0 +1,111 @@ +============ + Dear Colin +============ + +Thank you very much for taking the time to spend a morning together +recently. + +It was good to be back at Warwick, I barely recognised it. + +I left with much to think about the paradigm. + +Einstein and universal time. + +Why quasars are important. + +Homogeneity of space time. + +de Sitter space, inherently expansive as t increases, distance from +origin does too. + +The de Sciama principle is wonderful in it's simplicity. + +It captures the natural behaviour of waves. + +It is noted that the inertial frame at a point is determined +predominantly by the distant matter in the universe: there is just so +much more of it and gravitational waves drop off only linearly with +distance. + +The fundamental property of these waves is that any matter is moved by +that wave, two bodies exchange deltas at the speed of light. + +The effect is for all matter to tend towards being in phase with it's +surroundings, from there it's smooth riding. + +Now while the background inertial field is of considerable interest, +what affects us locally is the delta of our inertial field, relative +to the universal background. + +This delta is dominated by the local matter and so by moving in harmony +bodies can help sustain each other, this manifests itself as +gravitational attraction. + +The inertial field itself is hard to detect, by definition all matter +in the universe is moving with it in some deep sense. + +Locally, nearby masses distort this field. + + + +Our window on our universe +========================== + +We see a window of 13 billion years, or maybe we see much more? + +There are a lot of different ways of interpretting what we see as we +gaze into the universe. + +Is the visible universe all there is or is it in a state of constant +re-birth? + +The new paradigm shows galaxies can sustain themselves for incredible +periods of time. + + +The universe appears to be extraordinarily uniform, based on existing +observations. + +It is also generally accepted that the visible universe is expansive. + +There are many ways to give rise to such an expansive universe. + +For example, assume our visible universe is just some band in a giant +spiral storm. + +With cloud like structure, perhaps a giant winding tube within a wider +space. + +Such structures could be sustained for unimagineable periods of time. + +Oort Cloud +========== + +Closer to home, the *Oort Cloud* has been in the news again. + +This time a suggestion there might be a *planet* of some considerable +mass out there. + +This is an intriguing, solar system formation. + +Perhaps something that simulation can help enhance our understanding. + +It does also suggest that a solar system might be able to sustain +itself much longer than is normally assumed. + +Models do not seem to include considerations of in-flow of new matter +to a system. + +This leads me closer to home and tropical cyclones. + + +Earth atmospherics +================== + + + + +Proton diversion +================ + +To boot strap things ... later? diff --git a/docs/nodice/piri.rst b/docs/nodice/piri.rst new file mode 100644 index 0000000..7dc52ae --- /dev/null +++ b/docs/nodice/piri.rst @@ -0,0 +1,487 @@ +===================== + Another quantum cat +===================== + +A few days ago I woke up and queen mary informed me that we had a +visitor. + +A tiny kitten that had been eating out of snowy's bowl. + +In every way, a smaller version of snowy, roughly 1/3 the size, no +matter what you measure. + +In the last few weeks we had decided it was time to move back to +Canada. + +But there was always the problem of the snow. + +Here in Bermuda, most winter days it makes it to 20C. + +Snowy, despite his name has never seen snow. + +He's seen wind and rain and hurricanes too. But no snow. + +So we learned that you can take a cat in the air, beneath your seat in +a plane. + +And end up in Toronto, with snow in a nylon nest. + +What could possibly go wrong. + +So we take out the cat carrier, and place it in the living room. + +And snowy likes it, or mayb the catnip sprinkled on its floor. + +And then on the 7th of the 10th month and Piri is here. + +The name came from Mary. A tiny pirate, found a new home on an +island. + +And he likes the travel nest too, it mush be the catnip... though that +has started to thin. + +Piri is white like snowy, but a black patch on one eye, just like a +pirate? + +He is hungry and eats fast so he can retreat a safe distance. + +So two cats on a plane, what could possibly go wrong. + +But the bigger question is does snowy like piri? + +To piri snowy is magic. He finds cool places to sleep in the day. He +brings mice, birds and rats in the night. + +He let Piri eat from his bowl and drink water too. + +Their noses brush, no purr, no growl. + +Fish for a treat, Piri alone. Learns to come close. + +And slowly by slowly pulls bits from your hand. + +Snowy returns and looks on in mirth at this new ball of energy. + +Goes for his food and piri comes too.. a hiss and piri retreats. + +Lies on the floor and watches snow eat. + +So snowy says piri stays + +But neither of them knows of the snow days ahead. + +Names +===== + +Harvey, Irma, Jose too. + +Maria and now Ophelia. + +Mexico quake and California fire. + +Bagpuss first, then Tiger and Blackie. Maple and Jessie and Walter +too. + +Snowy and Sooty and Snowy again. + +And now snowy junior, aka Piri. + +Cats come in ones and twos. + +Storms too nowadays. + +Harvy, Jose, Katia, Lee and Maria. + +Pairs and threes sometimes, running at the same time. + +Feeding each other, repelling too. + +And raising the swell with a moon at eclipse. + +The seas have been pumping and are hotter than hot. + +And now far to the north and eastward too, a hurricane named Ophelia. + +Seas cooler than normal, for hurricanes here. + +But cold in the upper atmosphere too. A nice little heat engine. + +Limited sheer, its that time of year. + +How cat insurance works +======================= + +If you live in an area where natural catastrophes occur then there is +a risk that your home may suffer serious damage from time to time. + + +Depending on how risky your area you may be able to take insurance to +cover this risk. + +If you have a mortgage, then you may be obliged to take insurance to +protect the lender from the risk of catastrophic loss to your home. + +Reinsurance +=========== + +So an insurer that insures a lot of properties in an area exposed to +natural catastrophes may start to get concerned that it might not be +able to honour its obligations. + +They can handle the small attritional losses that home owners are +exposed, but do not have the capital to cover large catastrophes. + +So they go to a broker who helps them understand the risks they are +exposed to and who has friendly reinsurers who can help with the burden. + +Models +====== + +So out come the models and in go the numbers. + +Out come more numbers, what the losses might be. + +Look what is expected. + +Add some more for what might be. + +And of course you cover your costs. + +The broker too and the tax man too. + +So that's the premium, where the money comes from. + +Profit +====== + +Nine out of ten, the year is quiet. Disasters afar, but not hurting +me. + +Collect the profit and throw again. + +Invest +====== + +Some profit is invested, it brings more return. + +And raises the rating and access to premium. + +But others did well too, just at the same time. + +So the premiums are dropping, but not how you think. + +The number is the same, but the denominator changed. + + +Loss +==== + +The year it is ten, two groups of five. + +The losses come in. + +One Harvey might be big. + +And Irma too. + +A little from Jose, which stayed out at sea. + +Katia rained too, down Mexico way. + +And then came Maria to Puerto Rico. + +An earthquake in Mexico too. + +And wild fires in California. + +Ophelia too, will she sail by the coast? + +Winter is coming. + + +Models +====== + +This storm is a monster like never before seen. + +It is a one in 500, 100 at least. + +Here comes another, 100 too. + +So what is the chance of 3 or 4? + +And those reinstatements? The third and fourth were free. + +And that forest fire, too small to notice. Well there is a clause in +the contract: one big event triggers all losses are covered. + +The models are expensive, millions to rent. + +Full of good numbers to rent? +t +So the modellers go to work and find an event or three, like the ones +that just happened. + +Run the numbers and announce a loss estimate. + +Forgetting to model the things they can't model. Because the model is +a model and won't do everything. + +Adjustment +========== + +The home owners call the agents attend. To see what disaster is there +to behold. + +Four feet of water, and more in the basement. I'm sorry we don't +cover water. + +But the wind did damage too, the roof and the windows and some of the +water, well that is how it can enter. + +The agents are swamped, paddling from home to home. + +Cars are awash, in lots everywhere. There will be a bill there. + +And businesses too, who do get flood cover and payments for breaks in +business. + +So the insurer sees that the cat layer is reached. The broker will +see that the loss passes over. + +So now the agents they can seek good will, from the people they know +from the visits to homes. + +And the neighbours have found a clause here and there and soon all +know how to play the double agent. + +So the losses they climb. + +And the models announce they have found it this time, that thing they +have been missing is clear finally. + +Dividing by zero +================ + +So ten years ago the premium was paid. + +The loss came and it was paid too. + +But in case of another a small new premium, to cover what remains of +the season. + +Except this year there were four and two were free. + +Oh, and the deal is for three years. Next year everything counts. +And the premium is locked in. + +But the models being used cannot model it so. We don't really know +what the risk is right now. + +Reserves +======== + +So insurers cover other things too. All sorts of things that might go +wrong. + +A cover is for a year, but 20 years for lawyers to argue. While the +premium gains interest, while held in reserve. + +As each event arrives an assessment is made. How much to reserve for +the losses to come? + +Tax +=== + +One thing to consider is how big was the profit? + +So if you have a big profit, a good time to check the reserves. + +Top them up a bit, you just got lucky. + +But how much to top up for cat? The cat is a quantum cat, there or +not there. Loss comes in quanta. + +Each company has a wavelength in dollars. $150M, $250M. + +And little waves too. 10M, 50M. + +And bigger harmonies, $1B, $2B. + +And they feedback and add up. + +But for now, lets see how things are going, throw some guesses in and +find a number. That's the new reserve. + +And the extra is tax free for now. + + +Ratings and Regulation +====================== + +Message from snowy, make of it what you will: you7887 + +So there are credit ratings. Roughly the probability you won't pay in +full. + +With a probability too that you won't pay at all. + +And there are formal agencies that do ratings snp and standpoor and +mystical names of yore. + +But there are informal ratings too, captain cowboy's a pirate and piri +too. + +The information flows, make of it what you will. + +And often the truth is delayed and comes with another half truth. + +But delay is a friend as we can see how it goes. + +Go with the flow, staying afloat? + +Reinstatement +============= + +So after a time and after an event the clocks and the counters are +reset. + +Reserve is fixed, capital too. A promise here, a future loss too? +The game begins at each renewal. + +Renewal +======= + +Jan 1, April 1, June 1. + +Magic dates, but Jan 1 is king. + +60% in harmony here. + +The coffers are full, who wants to play cat lotto? + +Now the stakes have been shuffled. + +Deductables dropped, new limits imposed. + +The Players and the game +======================== + +Players +======= + +Writing premium. + +Waiting for losses. + +A plan for the losses? + +Who needs a plan? + +Who has a plan? + +Incentives +========== + +It is all about the dollar. + +You have a slice of the company pie. + +And promises of slices if things they go well. + +Grow the pie, you do well, but how to grow the pie? + +And remember delay, that block in the pipe. + +That slows the information flow. + +Models +====== + +The models are wrong, its part of the design. + +Magic Division +============== + +Never define that which you model. + +The hundred year loss, for any cat model. + +So according to the model, for whatever it covers, that is the number +one year in a hundred. + +Now there is some range of error, but not too precise. + +There is 50 and 20, 10 and 5 two. + +Each with precision, rarely uncertain. + +And when rare things happen all too frequently + +Change the divisor and move on quite happily. + +Climate Change +============== + +The climate is changing, it always has. + +And now its changing faster, because of us. + +2 million years life burnt in 200. + +Now it takes time to catch up, but catch up it does. + +The engine is started, the oceans are roaring. + +On land change too, more rain or more dryness and sometimes the same. + +More varied, just greater, but not like it was. + +The models are tuned to what's in the past. + +Taking a window where things are quite flat. + +And ignoring the slope of the mountain they are climbing. + +Looking at signal plus noise, not modelling the signal. + +Fear Uncertainty Doubt +====================== + +The players they see good times year on year. + +Some little scares, a strange one here, a cyber breach? + +But then they find they can guess the risk and take a chance on the +data of yore. + +After a time the mind it plays games. + +The players get richer. They give more slack. + +Hoping that they are the one with the luck. + +Feedback +======== + +The climate gives feedback, it strengthens itself. + +A new harmony for a new energy. + +The land it is shaped by this very same power. + +It will adapt, but ripple forever. + +How big is the ripple and can we just ride it? + +Or will it surround us and drown us in hubris? + + +Who has the information? +======================== + +We can simulate this. + +Should we do it together? + +PiRi is with us. Are you with us too? diff --git a/docs/nodice/pist.rst b/docs/nodice/pist.rst new file mode 100644 index 0000000..982d794 --- /dev/null +++ b/docs/nodice/pist.rst @@ -0,0 +1,48 @@ +====================== + Pi Is Transcendental +====================== + +Snowy the cat, brought us Pi-Ri, + +Pi-Ri the pirate cat. + +Over the sea to a land of ice. + +Pi-ri the cat, divide by three, + +Point 1, 4, 2 + +'Cos pi is transcendental. + +For just one quarter of a pie, + +Here's a simple recipe. + +Start with 1, that's Napoleon's pi + +Take off 1 part in three. + +And now add back in just one in five. + +'Cos pi is transendental + +Take back out a one in seven + +And now back in just one in nine + +That's one in three of the one in three we took, + +So let's start with one, and add another two. + +Then split the three to two and one + +Rinse repeat times five. + +Now take the five and find just 3 to add back into the pie. + +Now all gather round, and make a circle, + +It never ends, goes on and on, + +'Cos pi is transendental. + diff --git a/docs/nodice/plates.rst b/docs/nodice/plates.rst new file mode 100644 index 0000000..4ddc5b4 --- /dev/null +++ b/docs/nodice/plates.rst @@ -0,0 +1,128 @@ +===================== + Plate like rotation +===================== + +Colin Rourke's, "Another Paradigm for the Universe", has a new +edition:: + + The characteristic rotation curves for spiral galaxies have an + inner plate like rotation, whereby angular velocity is the same, + but tangential velocity is proportional to *r* times *\omega*. + + +So I am working through this land once more. It's a mysterious place +with lots of curiousities and occasional flashes where it all makes +sense, just briefly, before descending and spiralling in inward +circles. + +To some centre of mass, a local meeting place. Whirring around at +the edge of the plate, trying to hang on and surf the waves. + +What follows is often quite dramatic, as it seems to gather pace away +from the centre, having broken its ties. In fact, much of the +perceived motion is the constant angular velocity of the inner plate, +as it seems to zoom past. + +Some masses may be rotating rapidly, this seems to give them some +stability, but will tend to unwind as it moves away from the central +mass. + +To a new level far from the core, before blending with its surrounings +and drifting through the spirals. + +A large and caught in a vortex, spinning madly, until it gets a tad +off-centre and away to the outer galaxy. + +I am looking at a pool, with a jet a foot or so below the surface. + +From time to time I see vortices forming, always rotating the same +way. + +Closer inspection shows a veritable galactic rotation curve. + +Watch a little longer and there is an ant at the centre of the vortex. + +It's a big ant, around 1.5cm long. And it is spinning like mad with +the same angular velocity as the rest of the vortex. + +Sometimes there is a wobble and the ant gets off centre, spinning +rapidly. + +It rapidly spirals outwards, with its rotation decreasing in the +process, in effect trading angular momentum to potential energy. + +Perhaps even enough to be ejected from the galaxy. + +Angular momentum? Inertial dragging by giant black holes. + +What does it have to do with the detections of gravitational waves and +the mysterious gravitational waves. + +Is it possible that the time interval between observing a new galaxy +arriving at the edge of our visible universe and the detection of a +gravitational wave from the same, rises as the mass of the black hole +does? + +The key observation is the extent to which the black hole can slow +down time, or rather the distance at which its inertial drag on time +is no longer notable. + +So it is possible that the time interval in between a gamma ray burst +and the detection of the gravity wave from same rises as the central +mass does, posibly rather significantly? + +An excellent source of information on gravitational wave information +for the current operational run can be found here:: + + https://gcn.gsfc.nasa.gov/selected.html + + +It also records gamma ray detections. GCN is a global alert network +so telescopes can react when a gravity wave is detected. + +June was a curious month. An event at the beginning, then nothing +until right at the end, now July has already provided another. + +I've read some papers discussing various aspects of the parameters +that are being assumed for each detection. + +One paper was suggesting we may be seeing reflections from the sun (I +tend to think this is likely, with also interference from Jupiter.) + +But baby steps. + +More detections +=============== + +It is now August 16th. + +Since June 30th, there have been about one or two detections per week. + +The most recent detection was on the August 14th. + +I have been following the reports. This global reporting +collaboration is fascinating. + +As far as I can tell, most of the collisions detected have been +between larger (10-100 solar mass) bodies. + +I believe there have been some collisions involving smalle (less than +3 solar masses?), which would have been neutron star collisions, where +we might hope to see coincident radiation in other spectra. + +Whatever the source of the wrinkles, their shape is characteristic. + +An oscillation that slowly (over 1-100 seconds) rises in both +frequency and intensity, until it hits a sharp peak and is followed by +a settling down, or ring-down. + +Plan +==== + +Visualisation of local galaxies and solar system objects. + +Raw signals for full set of observations. + +Localisation information. + +Model for new arrival. diff --git a/docs/nodice/pmbggp.rst b/docs/nodice/pmbggp.rst new file mode 100644 index 0000000..62f7701 --- /dev/null +++ b/docs/nodice/pmbggp.rst @@ -0,0 +1,63 @@ +================= + M + 1 to the en +================= + +Its 3 am + +on m + 1 + +All en u c + +At the ren + +re road + +with the door of gold + +PM at the dock + +And the gates + +not bill but R + +And who's this singing? + +It's George + +The Papa + +with the dope + +on the dopes. + +Removing the G + +its over to you + +M + 1 to the EN + +That's you of course + +My own QM + +Coming with a letter + +from a to z + +At the field of kind + +A lee by the sea + +I'll be there at 5 or maybe 6 + +Will you be my qm? + +We're removing the g + +and the i and the l + +So its over to you + +Not a moment too soon + +M+1 to the N, qm. diff --git a/docs/nodice/popebb.rst b/docs/nodice/popebb.rst new file mode 100644 index 0000000..813fbf4 --- /dev/null +++ b/docs/nodice/popebb.rst @@ -0,0 +1,51 @@ +Hi Colin, + +A copy of "A Brief History of Time" crossed my path. + +I'd read it before, but it is a whole different story in the light of +your theories. + +In fact, much of it is very helpful in thinking about the black hole +inertial drag issue. + +Surface area of combined black holes is >= sum of the areas of the +pieces, entropy and more. + +Oh and I wasn't aware that the Pope said yes to the Big Bang Theory in +the 1950's. + +This problem is way bigger than I realised. + +I have been flipping between the two books and now feel I have a +pretty good understanding of it all. + +de Sitter space -- so a sphere embedded in Minkowski space? + +This reminds me of a piece I wrote back in September when I started +thinking about the black holes (or neutron stars!) colliding. + +I think I should take another pass through these writings. With luck +I can turn it into a nice introduction to your book. + +Like the *Big Red Algebra book* back in the day on how to care for a +pet algebra. + +Here's a link to the piece back in September, `balls.rst`. + +I am starting to think about simulations of de Sitter space. + +Thank you for the book. I think the arguments are very, very strong +and the case is compelling. + +Changing the potential age of the universe by many orders of magnitude +has profound implications. + +I am also trying to weave into my ideas some thoughts on information, +observations data and knowledge. + +And in particular, inertia and memory in societies. + +All the best. + +Johnny + diff --git a/docs/nodice/pybeeidb.rst b/docs/nodice/pybeeidb.rst new file mode 100644 index 0000000..7412605 --- /dev/null +++ b/docs/nodice/pybeeidb.rst @@ -0,0 +1,190 @@ +================================ + Python bash emacs eric idle db +================================ + +Some characters here. + +myrtle and scarborough + +ecgbert + +Rogers and sport, maths and odds. + +Commercial too, snooker cue. + +A brillian Griffin taught me some math + +And showed me computers too. + +City and Guilds at the grange + +A modem to the poly + +a giant teletyper. + +murphy and mcgee + +newton and einstein + +Harper Lee too. + +Leamington Spa + +Zeeman + +Series + +Hawkes + +and + +the do nut man with a farm, O'Rourke. + +And Miles more + +And algol 66 + +Galois, fermat, Godel and Fourier too. + +A Poincare space. + +And Rubik's cube with monster groups. + +Cards to be punched + +Back in an hour + +expected semi colon the only error + +Chess with cards, quuens on boards + +n x n + +but oh the io + +caves in the pennines + +ireland too + +results in o'connors + +and the world's largest dish cloth + +easter in ireland + +bermuda umbrella + +Glass and Nevin + +Guinness and peace + +Back to computers of yore. + +Number one and XMP too. + +SunOs and unicos too. + +Emacs and bash + +C with more plusses. + +The STL will do. + +Python at last. + +lists and dicts + +but always build bridges + +so others can do things + +the way they learn to know. + +the first computer. it shows you wonders. + +Click with a mouse + +Or fingers on keyboard. + +Pretty much all no touch screen. + +And once you tame the beast its good enough. + +I should know. 30 years and more and still emacs. + +But I have tried it with IDLE the Eric of old or new. + +And that works for me. + +Thinking of DB in a deep lawyers basement. + +Typing python and finding 2.2. That will do nicely, thank you. + +That's a db that's Beazely with cookbook curios. + +Guido to guide and so many more. + +more fun to code in the open + +It helps focus the mind. + +Karma dividing by Pi + +Spreading it out. + +Until it goes below the noise. + +A quantum cat. + +Of blue and red and white stripes. + +And what of the Bee, the new Py Bee. + +Get on your phone no need to beware the IDES of Py. + +Ubuntu too, for Snowy the Ubuntu cat. + +Upgrade today. + +Forgot it was running. + +Playing with light dm. + +Starting and stopping SD card reading. + +Naughty less. + +Flashing screen. + +No ctrl alt fn + +Over to gal1, wish ssh + +apt and nmap, htop too. + +ok we're running on gal2 + +stop the light dm + +get a gdm and an awesome wm + +hmmm.... just apt update and read the message + +dpkg with mystic incantation + +and apt upgrade, always sudo + +reboot or no? + +service start lightdm + +now usb and pictures too + +so ready for the tankrain rongo rongo show + +with guido's clock to set the time + +and all who are there to set the rhythm. + + + diff --git a/docs/nodice/redemption.rst b/docs/nodice/redemption.rst new file mode 100644 index 0000000..7e74ffd --- /dev/null +++ b/docs/nodice/redemption.rst @@ -0,0 +1,51 @@ +====== + Song +====== + +Going for a song. + +Karma for free. + +Mana too. + +Puzzles galore. + +And a vision. + +When all is gone + +We have unity + +Help the down stream + +And plot with a rainbow + +Pandas for data + +And Jupyter connects us all. + +With git and bash and python 3 6 + +It's all you need in the karma pi class. + +Requirements are there, but they are advisory + +I should do a release, so go read my README at rest. + +Start at the top, git log README.rst + +git log too, see what's there. + +docs are nodice + +but that is a rongo rongo tale. + +No start and no end + +But start anywhere + +Follow the commit if lost in a forest. + +Round and round, branch and fork. + +I should do release, let's give it a name. diff --git a/docs/nodice/rongo.png b/docs/nodice/rongo.png new file mode 100644 index 0000000..7b50207 Binary files /dev/null and b/docs/nodice/rongo.png differ diff --git a/docs/nodice/satsap.rst b/docs/nodice/satsap.rst new file mode 100644 index 0000000..9746a4a --- /dev/null +++ b/docs/nodice/satsap.rst @@ -0,0 +1,15 @@ +====================== + SAme Time SAme Place +====================== + +Same score, + +But not quite the same. + +Many meanings. + +How much information? + +Bits and bytes + +Prior and post. diff --git a/docs/nodice/six.rst b/docs/nodice/six.rst new file mode 100644 index 0000000..d83a9d5 --- /dev/null +++ b/docs/nodice/six.rst @@ -0,0 +1,35 @@ +=================== + My Perfect Cousin +=================== + +6 just perfect, but what does that mean? + +1 + 1 + 1 + 1 + 1 + 1 = 1 + 2 + 3 = 1 * 2 * 3 + +A cricket match at aber ga glenny. + +Sobers and Nash, six sixes each. + +I heard a talk, maybe lightning in the sea. + +About taking a text and boiling it down to the essence. + +It was better than that more fun. + +In the end what popped out was just six words. + +So that's about the length of a commit + +Give a take a bit of a plank. + +But its a good place to start + +If it pulls you in + +Don't be afraid + +Some of the deltas are quite small + +It might not be doing what you hoped it would do + +But its software and free, so you can play too. diff --git a/docs/nodice/snowy.rst b/docs/nodice/snowy.rst new file mode 100644 index 0000000..4709ac1 --- /dev/null +++ b/docs/nodice/snowy.rst @@ -0,0 +1,83 @@ +============= + White Noise +============= + +Snowy the cat. He brought me a rat. + +And a mouse. And lizards too. + +A cat with secrets. + +I help him with doors. + +He has a special exit. + +But the door is often open and there is often a human if not. + +Say hello when I come home, ask me where I have been. + +If there is something I want, I will let you know, but you can be +slow. + +If there is something to see, I will take you there. + +PiRi +==== + +One day Mary noticed eating faster than usual. + +His bowl had been empty and she'd filled it again. + +Glanced to the bowl and saw him their eating. + +But white noise reduced and all of a blur. + +PiRi was eating and Snowy not there. + +What wouls snow do when he found his food eaten? + +The same as he had done for maybe a day. + +Shake a head, go ahead and eat what he needs. + +Ubuntu for PiRi, but don't come to close. + +You can greet with a nose, but then you can go. + +I'll watch you play with the interpretter lock. + + +Ubuntu +====== + +Snowy has a home the sun and a garden to play. + +Cupboards for sleep and boxes too. + +And a pool of green bottles with one of blue. + +Along comes piri, the tiny cat pi-rate. + +Its the best name ever but I cant pronounce it. + +So snowy lets piri explore. + +Wathing him go, see what he needs. + +He's had a long journey, from who knows where. + +He's hungry to eat but eager to retreat. + +So he hurries the food and hides outside. + +The humans are sleeping, the crazy people. + +But when they're here and on form and listening to us. + +We dance and sleep and cherish the love. + +Snowy is happy, he has what he needs. + +Pull up a couch, just dont take his space. + +But share the ubuntu with everyone here. diff --git a/docs/nodice/spr.rst b/docs/nodice/spr.rst new file mode 100644 index 0000000..942eedc --- /dev/null +++ b/docs/nodice/spr.rst @@ -0,0 +1,17 @@ +=========== + s and p r +=========== + +News just in snowy and piri back after an afternoon in the sun. + +Love to Princess Crickets wherever you may be. + +btw what time is it? Losing track... + +wind picking up heading north-west + +chariot to goose station + +then no van to no home, but a bonfire? + +Ubuntu aa day n diff --git a/docs/nodice/static.rst b/docs/nodice/static.rst new file mode 100644 index 0000000..e05b331 --- /dev/null +++ b/docs/nodice/static.rst @@ -0,0 +1,381 @@ +================= + Static Universe +================= + +I began a previous `expanding.rst` by talking about *de Sitter space* +and saying:: + + + Within this space, time-like geodesics follow two distinct fields: + expanding and contracting fields. + + +I received some feedback:: + + + I need to correct one major misunderstanding. You write: "Within + [de Sitter] space, time-like geodesics follow two distinct fields: + expanding and contracting fields." This is not correct. De Sitter + space is highly symmetric. All geodesics are equivalent. The + dichotomy between expanding and contracting that you refer to only + comes into play when you have an observer. Like most of cosmology + these concepts are observer dependent. + +This turned out to be most helpful. A few weeks have passed and a lot +of thought on how to simplify things, very much helped by a better +understanding of what I think we may be seeing. + +I was going to edit the `expanding.rst` piece, but correcting things +round here that are not quite right would be a long project. + +So a new piece is in order. Almost everything below appears in some +form or other in Colin Rourke's, "A new paradigm for the universe". + +The arguments there are very much more precise and much of the book +explores the mathematics of de Sitter space, having established strong +arguments why it is appropriate. + +In what follows I am just trying to articulate my current view and +understanding of what we may be seeing. + +Outline +======= + +*Perfect Copernican Principle (PCP)*:: + + No particular location should be special. + + This should also be true of time as well as space + +I like to think of this as *space is pretty much the same +everywhere*. + +Indeed, as we look into the heavens this does appear to be the case. +Spiral galaxies as far as the eye can see. + +Our immediate vicinity (say withing 50-100 million light years) is +a well catalogued collection of some 800 or so galaxies. + +So let's assume the rest of the universe is more of the same, at least +for the next 40 billion light years or so. + +There is a peculiarity with red-shift in our observations. The +further away a galaxy is the redder it looks. + +Galaxies further away are moving faster and faster, the further away +they are, the faster they are receding is conventional wisdom. + +Certainly, the red shifts in our observations are increasing as +galaxies get further away. + +How does this square with the PCP? + +In short it does not seem to. In some parts of the universe, galaxies +zipping by at close to the speed of light, whereas in our vicinity the +average speed is about one thousandth of that. + +This does not mean that the red shift is not real, rather that the +interpretation that it means the distant galaxies are receding at +super-luminal speed, may be in-correct. + +However, for the purpose of calculation in *de Sitter space* is ideal +as it nicely models this expansion. + +Colin suggests it that space itself creates a drag on time and red +shift accumulates as light passes longer and longer distances. + +This is indistinguishable from the case that more distant sources are +receding faster and the intervening space is not changing anything. + +Regardles what the reality is, there comes a distance when the +Minkowski metric starts to make a difference, the galaxy appears to be +receding at a significant portion of light. + +In our locality, most of the time relative velocities are a small +fraction (< 0.01) of the speed of light and simple cartesian geometry +suffices for calculation. + +Further out, the Minkowski metric starts to become more important in +calculations, since the aparent relative velocity is approaching a +significant proportion of the speed of light. + +The magic piece in all this is the way that matter appears to create +space. A mental picture I use is time slowing, but it has to be noted +that in de Sitter Space time and position are intertwined. + +All this happens in a way that does not break causality. Light +arrives at the reciever in the same order that it leaves the emitter. + +The *Minkowski* metric is important here (cf Zeeman Causality implies +Lorentz group). + +[1] shows how in de Sitter space light arriving from a distant emitter +to an observer always follows the same pattern, due to symmetries +within de Sitter space. + + +Static Universe +=============== + +By *static* I mean the PCP universe described above. + +Galaxies as far as you can go. + +But those beyond A we may never have seen (or have we?) and others we +have seen since time eternity. + +Some equations and numbers to keep in mind:: + + A = M * N + + M = 10^11 suns equals 0.03 in natural units. + N = 10^10 + + c = 3e8 m/s + + v = 3e5 m/s + + v ~= c / 1000 + +The size of the visible universe, *a*, the mean mass of a galaxy, *M* +and the number of galaxies, *N*. **a = N * M**. + +Why it appears to expand. + +What we can calculate from the rate of expansion we see. The inertial +drag of galactic cores across the universe. + +In turn, this should give a value to tune galactic rotation models +to. I.e. to understand why we see the specific rotation curves for +velocity of stars in a galaxy. + +It also should apply to planetary orbit calculations. + +Expansion as an illusion +======================== + +Gamma Ray Burst +=============== + +All emitters arrive with a burst. + +This may be preceded by a long period of microwave background noise. + +de Sitter Space +=============== + +Cosmic Microwave Background Radiation +===================================== + +Thermal with a temperature of 2.7 degrees Kelvin. + +This is the temperature of pretty much all of the intergalactic dust. + +So as light from distant galaxies looming over the horizon is shifted +red as it passes to us. At the Hubble distance it tends towards +being infinitely red shifted. + +There seems to be a contradiction in the model that views a gamma ray +burst as our first view of a distant source, and yet says that we see +galaxies looming in the distance in the form of the CMB. + +It is important to realise that the reason that the CMB is in such +good agreement with thermal equilibrium is because the universe itself +is in such a state of thermal equilibrium. + +Once light rays get shifted to microwave, they just add to this +thermal background. + + +Gravitational Waves update +========================== + +The *O3* observation run is now well underway. + +Some 30-40 detections over a period of six months. + +Much talk of multi-messenger astronomy, but so far a shortage of +examples where simultaneous observations have been made, as far as I +am aware. + +I still need to go back and take a closer look at sky map localisation +for these events. + +For now, this is a good source of information and data relating to +gamma ray bursts and gravitational waves:: + + https://gcn.gsfc.nasa.gov/selected.html + + +I have spent considerable time puzzling over gravitational waves and +whether they will show the same propogation peculiarities that light +does. + +I feel they will and that some, perhaps all, of the events that +LIGO is detecting are in fact new cosmic arrivals. + +This would raise a puzzle over why we are not routinely seeing +coincident gamma ray bursts. It is something I have puzzled over +without fully resolving. + +It is early days for gravitational wave detection. Presumably, the +current detections are the larger end of the event spectrum, so that +may give a clue. + + + +Why am I skeptical of colliding black holes? +-------------------------------------------- + +There are a number of reasons that I am skeptical. + +a. I am not convinced it is possible for matter to create waves in this + way, in short I am not sure gravity works quite like that. + +b. The distribution of sizes of colliding objects. Why do we not see + collisions of bigger objects? Is the distance distribution skewed + in any way? + +c. I believe all the current detection processing line works of + templates derived from more detailed calculations using the Kerr + metric, but I could be wrong. + +d. The arrival of a new galaxy at the Hubble distance may trigger a + gravitational wave, similar to the way it triggers a gamma ray burst. + +Regardless of what is happening, it would be productive to try to +simulate the merging of black holes using the physics of [1]. + +With respect to d., this raises the question of why we do not seem to +be seeing simultaneous gamma ray bursts and gravitational waves. + +This may be because: + +1. we have incomplete coverage + +2. in general the gravitational wave and gamma ray bursts can happen + some considerable time apart. + +3. It is more like an eclipse: some receivers see the total eclipse, + some just get the penumbra. + +4. We cannot hope to understand this without modelling universal + harmonics observed in the cosmic microwave background. + +5. Actually, the pattern we see in the CMRB comes almost entirely from + lensing by our local galaxies, once that is removed there's not + much left. + +Or some collection of the above. + + +Arriving and departing +====================== + + +Notes +===== + +Observations would seem to show that our visible universe is saturated +with galaxies. + +Each galaxy centred on a giant, super massive centre. + +Our observations of this universe show this curious red shift, the +further away a light source is the greater the red shift. + +Surely, this is just what we should expect, due to the inertial drag +caused by the intervening galaxies? + +Each black hole, twisting and slowing time, giving the illusion of an +expanding universe. + +Curious behaviour at the Hubble distance. + +New arrivals and old friends. + +Harmonics +========= + +The harmonics of the universe seem to be on a scale commensurate with +the typical galactic peculiar velocity. + +How far can the gravitational wave from a galaxy go before the galaxy +has done a full rotation? + +Magnetism and the speed of a stream of electrons? + + +Plan +==== + +Mass times angular velocity over distance. + +We know the mass and the distance, but what is the actual angular +velocity of the galaxy? + +Assume on average, there is a shift in space time, amounting to +~70km/s over a distance of 3.2 million light years (= 1 mega parsec). + +A change in velocity of about c/4000 where c is the speed of light. + +Now if we approximate things and assume the nearest galaxies account +for the major part of this change, then we can look at the path that +the light takes from each galaxy and calculate the aggregate effect of +all the galaxies on that light as it makes its journey to us. + +For this to give a useful estimate we would need good estimates for a +number of parameters for each galaxy in the neighbourhood:: + + mass + + distance + + velocity of the galaxy + + redshift + +There is likely enough information to estimate each of these, although +in many cases the various parameters are inter-twined. + +We can also take a statistical approach, including computer +simulation, to model either the local galaxies or a larger universe. + +Constrain the simulation to obey Hubble expansion. + + k omega mass / r + +galaxies. + +Hubble constant. Allows calibration of inertial drag. + +Observations in nearby galaxies alone should be plenty to get a +reasonable value. + +This may help in understanding why galaxies travel and rotate at the +speeds they do. + +I suspect fully resolving this would involve some understanding of +galactic tidal effects and harmonics. + +I also suspect that magnetism, protons and electrons may play a role. + +Software +-------- + +Understand the software used in gravitational wave processing. + +Specifically, the `bayefits` used in creating sky maps for the source +of gravitational waves. + +More generally, work more with `astropy`. + +In particular, `astropy.coordinates`. + +Karmapi and Blume +----------------- + + +[1] Another paradigm for the universe. Colin Rourke. aka "The Book +of magic." + diff --git a/docs/nodice/stop.rst b/docs/nodice/stop.rst new file mode 100644 index 0000000..9b5d428 --- /dev/null +++ b/docs/nodice/stop.rst @@ -0,0 +1,7 @@ +==================== + Does it ever stop? +==================== + +If you get here, pause at least. + +Sleep of the cure io to pure. diff --git a/docs/nodice/this.rst b/docs/nodice/this.rst new file mode 100644 index 0000000..19c23b6 --- /dev/null +++ b/docs/nodice/this.rst @@ -0,0 +1,25 @@ +======================== + Turning self into this +======================== + +Or pickles without a jar + +In an oz db + +From the wizard tp + +Whatever the list + +you always need tp, just add m and mm and mmm + +so:: + + import this + +and read the zen of tp + +thanks for the zodb + +the zeberdee db that springs every night + +As the clock of the cron chimes out diff --git a/docs/nodice/typo.png b/docs/nodice/typo.png new file mode 100644 index 0000000..72e2da4 Binary files /dev/null and b/docs/nodice/typo.png differ diff --git a/docs/nodice/undertone.png b/docs/nodice/undertone.png new file mode 100644 index 0000000..e0d550c Binary files /dev/null and b/docs/nodice/undertone.png differ diff --git a/docs/nodice/weather.rst b/docs/nodice/weather.rst new file mode 100644 index 0000000..304e2be --- /dev/null +++ b/docs/nodice/weather.rst @@ -0,0 +1,3 @@ +btw nice updates to the weather service. + +des per i do xxx diff --git a/docs/nodice/weirdo.rst b/docs/nodice/weirdo.rst new file mode 100644 index 0000000..16e7774 --- /dev/null +++ b/docs/nodice/weirdo.rst @@ -0,0 +1,256 @@ +==================== + Strange Attractors +==================== + +Nature love spirals and spheres. + +When two waves pass, they may attract each other and circle each other +in a dance, suspended in space. + +They aim to be in harmony with their peers. + +But they are dragged along by what surrounds them. + +Which in turn is trying to be in harmony with its surroundings. + +To break the harmony, energy is needed. + +Raising the amplitude until it emits its own flash of light. + +Waves everywhere. + +We can't see them, sometimes we get glimpses. + +Patterns and waves in the water of time. + +Driving our thoughts as we sense harmony. + +Beginnings +========== + +Folklore and unix, unicos and sunos. + +Magic with math. + +Puzzles to puzzle. + +Bash and emacs + +version control too. + +strange beginnings sccs rcs cvs svn - hg darcs bazaar - git + +All the same but strangely different. + +Next there was linus with redhat and irix and always rms for gcc + +Except on irix where egcs wrestled with the rhymes of stroustrop + +Bot mostly the stl. + +pick-up-a-pick-up-a-p +===================== + +perl and tcl, a wish and a prayer. + +a version six? and what about tix? + +then there was python of monthy ball fame. + +from guido with his magic time machine. + +1.5 to 2.2 and later 2.6 + +The 2.7, 3.0, 2.7,3.1, 2.*, 3.4, 2.7, 3.5, 3.6 + +Always the GIL but now with async to await + + +Meanwhile in parallel universes +=============================== + +I worked on with emacs, bash and now python. + +Always bridges to build to another strange land. + +Access xl sql db + +And the land of the graphic user test + +And just when you pass that gut score, a new gut brings promise and +less. + + + +XL cats Charlie Frances Ivan Jeanne +=================================== + +SnowyN +====== + +I am told he likes cats, as I do too. + +They show me how and what and when to care. + +So there have been a few snowies. + +Snowy the first, a republican cat. + +A cat from Clontarf, on the line to the city. + +Out to Kildare with the lilly white air. + +Scared of the dogs here, big as horses. + +A stroke or two, now I am scared. + +And Sooty the stealth cat, no flap training there. + +Who knelt to Snowy, only here for the food. + +Snowy2 +------ + +Snowy2, a quantum cat. White noise and calm. A steady background +beat. + +Takes his time all is good. + +Snowy lived with a giant dog in devonshire, so moved to southampton, +yby the lighthouse. + +Tinkerbell in his field, looking for the ghyll, waiting for the rain. + +And the storms, Fay, Gonzalo, Joaquim, Alex, Karl and Nicole. + +Both snowy's came with a name. + +Ando sooty was always going to be sooty. + +There must be snowie every where. + +So Snowy4 counts for all n > 3. + +Charged on his mid-summer birthday. 2013 june 21. + +30 for him just one for me and m. + + +NSA document stash +================== + +I knew some like snowden, a younger flash gordon. + +Fixed the code when something ran slow. + +Now snowy4, helping humans use software. + +As they scoop up the waves. + +The world changing fast. + +Take a beat and look around. + +Lots of good here to be found. + + +Remember, remember the 5th of november +====================================== + +Alan Rusbridger, a guardian leader. Sat in the kitchen, reading the +letters. Talking to Brenda, queen of the crossword. + +Said I would like Cheltenham, fun to be had there. + +Puzzles like puzzles you never to see. + +People to help. Ellis and Cocks. Turing and Toulmin. + +Now the numbers were small. We shared with each other and select +others. + +And always it was felt on the side of the good. + +If you can't keep a secret we can't do our job. + +So suddenly secrets are there in the paper. + +20 years later and look how it has changed. + +9/11 the rules forgotten. + +Collecting it all, but missing the pearls. + +Red white and blue +================== + +It has been a strange journey with a rainbow of colours. + +The beginnings they echo the python moves strong. + +And easier and easier to do what we dreamed of. + +But harder and harder to please. + +For fear of computers that we can't control. + +And only a form to update. + +Snowy4 +====== + +Ed Snowden, citizen 4. + +I never saw that one coming. + +I read all the articles, watched citizen 4. + +Favourite scene? The blanket mantle of power. + +Seeing both sides, from inside and out. + +Trying to figure how we got here. + +Karma Pi grew out of that. What belongs in the open and how can it be +shared? + +Networks of trust. + +Ubuntu and python, redhat and sunos. Suse, debian, arch now too. Pick your own +name. + +Each goes at its pace, but finding its rhythm. + +And sharing the work of sharing the trust. + +But then there is the data and its everywhere. + +Protected by password but in an sec report. + +The data? Safe as houses. + +Pick your design, but find one with bridges. + +Greenwald talking a block from a home. + +This should be interesting. It was. + +Whatever Ed did he got a fair press. At least from the ones that he +trusted the most. + + + +qotd:: + + Well, I really want to encourage a kind of fantasy, a kind of + magic. I love the term magic realism, whoever invented it – I do + actually like it because it says certain things. It's about + expanding how you see the world. I think we live in an age where + we're just hammered, hammered to think this is what the world + is. Television's saying, everything's saying 'That's the world.' + And it's not the world. The world is a million possible things + + Terry Gilliam talking to Salman Rushdie + + The Believer, March 2003 via viki pidia + diff --git a/docs/nodice/who.rst b/docs/nodice/who.rst new file mode 100644 index 0000000..7f506b3 --- /dev/null +++ b/docs/nodice/who.rst @@ -0,0 +1,25 @@ +======================== + Who found Pi to the e? +======================== + +On a who dunnit or rather who found it + +Or what or who, its he, pi ri. + +Four and eighty after bouncing around in some unit of plank. + +Of course it was snow + +who found pi ree. + +He found him and loved him + +So brought it to us + +And now we have found him + +We cannot un know + +The love in snowy + +That brought us pi by you and by pie to the e to the i. diff --git a/docs/nodice/wikipedia.rst b/docs/nodice/wikipedia.rst new file mode 100644 index 0000000..0dea16f --- /dev/null +++ b/docs/nodice/wikipedia.rst @@ -0,0 +1,20 @@ +============ + Quick Feet +============ + +Message to wikipedia is looking for donations. + +I am in debt there, to be sure. + +$20 and a greasy chip butty edit. + +And in return lifetimes of words and pictures. + +Thanks wikipedia, one of the best. + +wiki pedia, wiki wiki, quick feet, many legs. + +made with whales + +g5md4rj7ca +. diff --git a/docs/ottawa/revertreds.rst b/docs/ottawa/revertreds.rst new file mode 100644 index 0000000..550cfb1 --- /dev/null +++ b/docs/ottawa/revertreds.rst @@ -0,0 +1,175 @@ +============= + Revert Reds +============= + +After a call to 311 the one at the end of my street seems to be +behaving a bit more predictably, which is good for me and others in +the area, but misses the heart of the problem. + +Current traffic policy leans towards keeping the cars flowing. Biking +about the city at present, it is startling how much space is given +over to cars and how much it impedes other means of travel. + +The current city traffic management is inconsistent with the city's +declaration of a climate emergency and statement in the official plan +that it desires to raise use of active transport and transit. + +Cycling across town the other day, down Somerset St. It was a very +enjoyable ride, the streets were very quiet. + +There are many lights along the route, hardly two share the same +protocols. + +Pedestrians get head start, but not bikes. + +Pedestrains and bikes both have their own symbols and get a head +start. + +Plain old traffic light, pedestrian light just flashes, no counter. + +Traffic like with pedestrian countdown. + +Each junction is a little different, as we see how ideas have evolved +through projects over time. + +Adding revert reds to this mix of light protocols is inviting +problems. + +But overall, with current low traffic everything felt safe and +enjoyable. + +The downtown is quiet, too quiet, the city is at a crossroads. How +to restore some vibrancy? + + + + +The city and the government might want to consider turning some +offices into public work spaces. A place you can go to do your remote +work, meet others doing similar work. + +Business such as Shopify, now fully remote working, have excellent +office spaces which would be excellent co-working spaces. + +Indeed Shopify is an interesting example, with its association with +open source software and communities. + +These communities have been collaborating on critical software bases +for over 30 years. Our entire IT infrastructure is built on open +source. And it was built through global collaboration facilitated by +the internet and tools the community built to support collaboration. + +One tool, in particular, is worth special mention, if only for the +name, *git*, but that is likely another story. + +The arrival of the pandemic and the work from home era has brought +this remote collaboration to large sectors of the population, albeit +with *zoom* and shared drives, cameras and mics. + +Maybe even *git* for version control, more likely Dropbox, Drives or +whatever shared filespace is called these days. + +The disruption has now been long enough that people have adapted to +the new normal and many rather like it. + +Organisations too have adapted too. I suspect the most successful +companies will be hybrid, with a decline in the demand for office +space. But many will need a large space for occasional gatherings. + +I would also expect that the move to remote has very much changed how +many organisations run, as people adapt to varying degrees and this +changes dynamics within an organisation. + +Many were no doubt much more comfortable with the old world and are +hoping to a return. In general, those exercising power and control +in organisations pre-pandemic may well have experienced significant +loss of control during all the change. + +It is natural there will be many strong advocates for a return to +office commute. + +How to resolve all this and re-vitalise the down town? + +Well let's return to open source communities. Whilst most +collaboration was done entirely on line, regular conferences were a +key part of the successful projects. + +They gave opportunities for large numbers of individuals, typically +using some common tool to help them solve some other bigger problem, +to meet others wrestling with the same computation problems. + +People from a wide variety of fields, gathering to share ideas was an +incredible incubator of ideas and stimulator of collaboration. + +Working remotely can be very isolating, it was hard to find people +locally doing the same things. Online communities turned into meetups +and mini conferences. + +Back to the city, how to get people to want to go and visit there? + +The key is surely to create spaces where people want to go because of +the others they will find there. Whilst few want to spend 40 hours a +week plus 10 hours commuting, many would be happy with a couple of +afternoons, mornings or evenings a week. + +In such work spaces it would be natural to have an extended working +day, so the facility will be in use for more hours of the day and +commuting will be more evenly spread through the day. + +As far as information technology is concerned, separation of civic +prigects into public, open projects versus internal private, projects +would be hugely beneficial. + +The open parts of government could be co-located with the co-working +spaces. Creating a unique opporunity to share ideas and increase +collaboration across the region, and share knowledge with each other. + +For example, a space where those interested in the city's open data +portals can gather, and have those in the city working on the same +spend some time each week in the same space. + +The city could allocate some of its spare office space to groups +interested in problems, such as the software controlling our traffic +lights. + +Imagine there is a whole variety of spaces you can choosed to go to +work remotely for a while. Not Jamaica, but rather the old city +offices where nobody wants to go. + +We have just gone through the publishing of an official plan and it is +notably lacking of any evidence that any alternative futures have been +given proper consideration and evaluation. This in light of +everything we have learnt through the pandemic. + +Surely the city should be looking at some radically different visions +for transport and land use across the city? + +There are no ends of projects where increased public contribution +would be invaluable. + +Open up the planning department, organise regular lunch-and-learns +in the new shared space. Truly, move to and being an open +organisation, designed as a place where the default is open to all. + +Stop out-sourcing everything to consultants, rather build internal +expertise and collaboration across different local communities. + +Create spaces where people can share there experiences during the +pandemic, how their outlook on the world may have changed and new +visions for the future. + +Places where people can ask, what could we do if we reclaim some space +from cars? + +Create the bike lanes where you don't stop rolling until you get where +you are going, pathways just merge and flow. + +Instead of wondering if the capacitance of your statusesque existence +is stable enough to turn a light red as you wait for the inevitable +revert. + + + + + + diff --git a/docs/philosophy.rst b/docs/philosophy.rst new file mode 100644 index 0000000..a38757f --- /dev/null +++ b/docs/philosophy.rst @@ -0,0 +1,51 @@ +============ + Philosophy +============ + +There are a lot of questions in karma pi land. + +Not so many answers, but some hints at experiments that could help give +better insights. + +It is a land of doubt and much mystery. + + +On the software side there is exploration of ideas to help share data, +resources and ideas. + +How to do this balancing privacy against benefits of open sharing? + +How to better understand how much we are sharing and with who? + +Karma Pi makes no attempt to be secure. Rather, it is assumed +processes anywhere on the local network are acting in good faith, and +in so doing make better use of the available resources. + +So for instance, a classroom working with raspberry pi's. Maybe +trying to make a weather forecast, but the pieces of the puzzle are +spread across the space. Forage for clues and other's with answers to +questions you had not even thought to ask? Someone who has been +watching the snow, rain and ice each day, the height of the tide or +the phase of the moon? + +The *karmapi.kiss* module is a simple start to sharing data across +pi's. + +And there is *yosser* if you want to share in the work. + +But there is also this, I learned today, thanks to Peter Wang, and no +doubt many others:: + + https://docs.oceanprotocol.com/ + +**Blockchain** too, in this case addressing data integrity and +security too. + +Trying not to re-invent wheels, finding others that are solving the +same problems and working together was always a goal. + +So *karmapi.kiss* or time to explore the **ocean**? + +*Ocean Protocol* logo appears to be a dolphin, so I guess ocean it is. + +Maybe with karma pi for the kissing dolphins? diff --git a/docs/pots.rst b/docs/pots.rst new file mode 100644 index 0000000..df6b1a1 --- /dev/null +++ b/docs/pots.rst @@ -0,0 +1,78 @@ +=========== + Soft Pots +=========== + +Pots +==== + +Software is malleable, just like clay. + +Start out with an idea, a magic pot, something to make from clay. + +Start doing what you think might get you there. + +Learn clay doesn't work that way. + +Or it does until it gets hot in the kiln. + +Along the way you notice a bunch of other cool things about clay. + +And your magic pot vision changes + +Since you now have new tricks in the tool kit. + +An artist with tools of many colours. + +Software +======== + +Someone else is has a very specific design for a pot they want you to build. + +They do not care that you can build something a 100 times better than their +design in lots of dimensions much more easily than you can build the +object of their desire. + +They also say what tools you can use to build the pot. + +And the pot must be fired in their kiln + +which is heated by a fire breathing dragon + +which randomly kicks the kiln around like a football or tosses it in +the air, breathes fire on it then heads it to the ground. + +Free Software Pots +================== + +Artisan software. + +Someone follows their own ideas. + +Finds something interesting. + +Offers it to others, who can each take their own path. + +Or like a band of artists weave rhythms and themes. + +Each with their own dance but creating ripples + +And waves to the future + +With a commit log story + +Of how we got here. + +With hints at the paths that might have been taken + +An infinite tree of exploration. + +Sharing the general. + +Generalising until all that differs is data + +And any good Turing complete will do. + + +Open data pots +============== + diff --git a/docs/quantum_theory_of_gravity.rst b/docs/quantum_theory_of_gravity.rst new file mode 100644 index 0000000..2d8460a --- /dev/null +++ b/docs/quantum_theory_of_gravity.rst @@ -0,0 +1,247 @@ +=========================== + A Theory of Waves in Time +=========================== + +It's all waves, gravitational waves. + +A field that propogates through itself. + +Local resonance and structure. + +Celestial harmony. + +Setting +======= + +Imagine a void. A cube of None marching through time. + +The cube cut into 8 smaller cubes, in turn each 8 smaller. + +And so on all the way down. + +Make the edges of the cubes vibrate, with the frequency inversely +proportional to the length of the cube side. + +Have the energy for each frequency be some magic constant multiple of +the frequency. + +The strings are perfectly elastic, so the vibrations pass through the +void at the speed of light. + +When a wave passes, a cube offers resistance, inertia, that has to be +overcome to move it. + +Below a certain threshold, the cube is pulled back by the fabric of +time. + + +Water +===== + +Add a drop of water to the void. + +Two protons dancing round 8 friends. + +H20, 47b, its everywhere here. + + +Schrodinger's Cat +================= + +What is an observation? + +An observation is when energy is turned into momentum or vice-versa. + +So when is the observation made in this experiment? + +A photon enters the box, passes through the half mirror... + +What's momentum +=============== + +mass * velocity + +Oh and there is a law of conservation of momentum. + + +What is energy? +=============== + +A gravitational wave. + +A change in energy, changes the waves. + +momentum times ache gives the energy. + +and frequency is proportional to momentum too. + + +Gravitational field +=================== + +Matter, which is itself just gravitational waves. + +Waves running in circles and eights and more, gyroscopes in the sky. + +Gyroscopes +========== + +Bouncing along the waves, creating waves as they pass. + +What is mass? +============= + +Mass is a standing wave of energy in the fabric of space time. + +A gyroscope that pulls as you pull. + +Einstein +======== + +Einstein guessed gravitational waves may be a thing. Two years ago, +they were detected, they are a thing. + + +Planck +====== + +Planck had a constant named after him. They call it *h*. + +When energy, in the form of photons, is created the frequency of the +photon is linearly proportional to the momentum. + +It is also linearly proportional to the ?? + + +Neutrons +======== + +There are lot of these about round here. Or things that can be +rearranged into neutrons, and yield energy. + + + +Resonance and Harmony +===================== + +Imagine being inside a recently formed black hole. A chaotic +implosion of matter. + +Matter which is moving and hence generating gravitational waves. + +A random distribution of white noise. + +Locally, there may be vibrations at the same frequency. + +Harmonics will emerge. + +Perhaps the resulting distribution of energy will follow a harmonic +distribution. + +The total amount of energy in a given frequency being proportional to +that frequency itself. + +This distribution of energy in the universe's gravitational field +would give rise naturally to the quantum phenomena and in particular +give rise to the Planck-Einstein relation, *E = hf*. + + +Background +========== + +Mean gravitational field, varies in time. + +Time +==== + +?? + +Dark Matter +=========== + +Local areas of structure within the field, below the noise. + +But you will get in sync if you pass by. + + +Quantum crypto +============== + +Agreeing a local field structure below the noise. + +Quantum computer +================ + +Look for structure in hidden field. + + +Karma +===== + +Waves that a body creates bounce back as they harmonise with the +universe around. + + +Godel, Escher, Bach +=================== + +Self reference. + + +Incompleteness of mathematics +============================= + +Mathematics of self referential fields. + + +Predictions +=========== + +Dark matter +----------- + +Black holes which have evaporated. + +Areas of wonderful hidden structure we can only see if we pass +through? + +Lenses that focus gravitational waves. + +Water +----- + +under the electron microscope. + +Homeopathy? DIY homeopathy? + +Diagnose the planet with sea samples under electron microscope? + +Moon and planets +---------------- + + +Does God play dice? +------------------- + +If so how does the game go? + + +Gravitational decay rate +------------------------ + +When two black holes spiral into each other how near can you be to +watch? + +Number of wavelengths away before you barely notice? + + +Probably OK so long as you don't get sucked in, you are already along +for the ride and have been for some time... + + +Therefore, field would seem to be extremely homogeneous, as noted, +time seems to be similar for lots of places in our universe. + +There can be big local explosions and nobody notices. + +It will follow a harmonic distribution. diff --git a/docs/roikpi.rst b/docs/roikpi.rst new file mode 100644 index 0000000..460f918 --- /dev/null +++ b/docs/roikpi.rst @@ -0,0 +1,172 @@ +=========================== + Round Objects in Karma Pi +=========================== + +A tour of round objects of all kinds in karma pi land. + +Modelling nested spheres. + +Balls of all kinds, the World Cup of soccer too. + +Using git to show how I develop code. + +How ideas change and evolve over time. + +Open data too and some ideas about decentralised systems. + + +Worried Man Blues +================= + +Influences... everywhere + +Close to home, and far away. + +Oceans, atmosphere, wind and rain. + +Music and harmony. + +Made in Sheffield +================= + + +1980 County Clare +================= + +Mathematics and underground topology at Warwick + +Ireland and Greece + +Ottawa +====== + +1990's + +Loved Ottawa + +And now for something completely different +========================================== + + +Inertia + +Citizen science + +Reproducible research + +Data sharing + +Distributed data science + +Local expertise driving global collaboration. + +Inertia in belief systems + +Bayesian information + +Kerr metric + +World Cup +========= + +DIY visualisation + +Breaking the rules. + +the rules +--------- + +events: a time and a value + +Everything else is meta data. + +Code uses meta data to decide what to do with events. + +breaking +-------- + +mix events with meta data + +data in the data structures + +helps understanding +------------------- + +Get something tangible working. + +Let it help you explore + +Drinking from the hosepipe +-------------------------- + +Just time to record the events, with a few garbles? + +fixing the code +--------------- + +taking away and re-moulding + +time for tankrain... + +Tankrain +======== + +show help + +Getting warmer +============== + +Slow it down + +ncdf needs love + +deltas + + + +Professor Ian Stewart +===================== + +Dark matter, no-one can find any. + +Alternative cosmology by Colin Rourke. + +*anpotu* + +Binky, Pyree and Fred Hoyle +=========================== + +The Nature of the Universe + +The onion +========= + +Nested layers of spheres. + +Open data science + + +Sunshine at Myrtle Park +======================= + +Demo time + questions + +World Cup:: + + python3.6 -m karmapi.wc.wc --events events.csv + +World warms:: + + python3.6 -m karmapi.ncdf + +Another Pardigm:: + + python3.6 -m karmapi.cpr + +Black hole on a pi?:: + + maybe.. + + +Question time +============= diff --git a/docs/rongorongo.rst b/docs/rongorongo.rst new file mode 100644 index 0000000..f517c61 --- /dev/null +++ b/docs/rongorongo.rst @@ -0,0 +1,443 @@ +========== + Rapa Nui +========== + +Once upon a time there was a team of stone masons who carved out a +giant block of rock from the volcanic tuff on the side of an extinct +volcano. + +A second team carved a similar block. + +Once the blocks were complete, with carved heads and a rounded front +edge, the rock underneath the horizontal moai was carved away in such +a way that the Moai was able to tile and rise under its own weight. + +Balance is critical here. First make it so the giant block is nearly +tipping, then make it oscillate like a tiny pendulum. + +A second Moai placed close and made to oscillate at the same frequency +will then resonate in harmony with the first. + +Once upright, they will walk down the hill together. + +The key is that the two Moai are in resonance, the gravitational waves +one sends out being in harmony with the other. As one sways, so does +the other in an equal and opposite motion. + +They may start to circle each other. + +To keep the motion going, a source of energy is required. The Moai +start at the top of the hill and slowly walk down it, earth's +gravitational field supplying the energy. + +Easter Island is where it is because it is at the centre of a giant +rotating magnetic storm on planet earth. + +The rock of the Moai likely contain significant quantities of iron, +rocks that can hold a magnetic field. + +This may be a key to how the Moai can rock and resonate without that +resonance building to the point that they topple. + +Now, since the Moai are in effect giant magnets, the earth's magnetic +field will tend to push them back upright. If you move a magnet +through a magnetic field, that field resists the movement and an +electric current is generated. If the electric current is exactly the +right size to create an equal and opposite force to the movement, then +the Moai will simply rock like a pendulum. + +Around each Moai, a standing wave will form. This standing wave turns +the Moai into a giant rocking pendulum trapped in the fabric of space +time. + +As more Moai are created and set on their journey of walking down to +their resting place on the ahu platforms, the Moai will resonate in +harmony. + +At a certain density of Moai, this resonance will be so strong, the +wave produced will make it impossible to add another Moai to the +system. + +The Moai might start to rock gently, but the oscillations will +increase over time and eventually it will topple. + +To the people of Rapa Nui, this all must have seemed like magic, a +special power, or Mana. + +The people will have learnt that certain times of the year there is a +greater probability of a new Moai staying stable. + +Archaeologist are fond of creating narratives that fit with the +artifacts they discover. + +The best narratives, the ones that are in fact the true story, lead to +other discoveries. + +This account is one such narrative. + +It is hard to imagine that the people would not have had great +ceremonies when a Moai was ready to be launched. Maybe they were +always launched at full moon, at certain times of the year? + + +And this leads to the mysterious *rongorongo* writings that have been +discovered. + +Messages etched onto special wood used for writing. This is not just +old envelopes onto which you scribble a shopping list, rather +expensive, hard to obtain writing paper. + +What was most important to the people of Rapa Nui? The records of +the Moai's walks down to the coast. The ones that walked, the ones +that fell. + +The ahu are just platforms build to help bring a Moai to rest at a +place where it can strengthen the Mana of the island. + +Perhaps the *ahu* are at places where Moai came to rest. Later, +perhaps after a storm they may have started to walk again. + +A well constructed *ahu* should have a gentle upward slope, so the +Moai can slowly lose its forward momentum. + +Moai will spin as they walk. This turns them into giant, slowly +revolving gyroscopes. + +The spin itself leads to stability, because of the law of conservation +of angular momentum, which is just a corollary to the law of +conservation of momentum, which itself is just a fundamental property +of gravitational fields. + +The slight asymetry in the Moai, due to the carving of heads has the +wonderful property that Moai are statistically much more likely to +come to rest facing inland than facing out to sea. + +My father studied geography, he always used to say, "geography is why +are things where they are?. History is why did things happen when +they did.". + +The answer to both is physics, the laws of nature. + +There is one law. Nature strives to achieve local and global harmony. + +It is all in the mathematics, all in the pie. + +The Moai are where they are because Rapa Nui is bang slap in the +middle of the pacific. It is one of the hubs around which the world +revolves. + +As such, it does not feel the shocks that hit other parts of the +world. + +Bermuda is a similar point, around which storms revolve. It is all +in the physics. + +So it may well be that outside of Rapa Nui the world is rarely stable +enough to get a Moai launched. + +Once launched, like a quantum of energy they go on their way until +some force or momentum or (ahu) stops them. + +Or until they achieve a place where they are in perfect harmony with +the universe itself. + +The first Moai? +=============== + +Giant's Cauesway in Northern Ireland has beautiful hexagonal pillars +of basalt. + +As the volcano was eroded by rain and wind, maybe Rapa Nui had pillars +that just walked down to the sea. + +Maybe the giant's causeway in Ireland is actually marching into the +sea? + +The magnetic field in Rapa Nui will be very stable, it may be the only +place on earth where this could happen. + +So the Moai were there when the humans arrived and the humans just +decorated them? And then learnt how to build new ones. + +Or maybe when humans got there they found columns of basalt, lying on +the ground all over the place. + +Like *eratic* boulders in glaciated areas. + +They stood a couple of the columns up, and they walked down the hill +together. + +Which came first? The Moai or the humans? + +Too many Moai? +============== + +As the Moai go off on their walks and find their place of resting on +the island, the magnetic field around the island will strive to be in +harmony with the magnetic fields of the Moai. + +The whole island will resonate with magnetic and gravitational fields +marching to the beat of the Moai. + +As more and more Moai are created the strength of this field will +increase. + +Launching a new Moai will become increasingly difficult. + +Since each Moai is a giant magnet it will naturally want to oscillate +in time with the field created by the other Moai. + +At some point this resonance will have sufficient energy to topple any +new Moai. + +To launch a Moai the amplitude of its oscillations need to be large +enough to cause it to wobble and waddle like a penguin, but not so +large that it topples over. + +As it wobbles, the island's magnetic and gravitational fields act like +the forcer of a pendulum, giving just enough new energy for each +oscillation to replace energy dissipated as heat, due to things such +as friction. + +If these are out of balance, the Moai will either stop rocking or +topple. + +There is a tiny sweet spot at which they will just march down the +hill. + +This sweet spot gets smaller as more Moai are added, since the +resonance in the magnetic and gravitational fields also get stronger. + +The location of Rapa Nui itself helps increase the size of the sweet +spot, being a Lagrangian point about which the earth's fields revolve. + +In fact, this is why there was a volcano at this spot in the first +place. And the presence of the volcano was what provided rocks with a +strong magnetic field. + +Now the Rapa Nui people no doubt developed a lot of myth and +superstition around the Moai, developing complex rituals for the +launching of a new Moai. + +If something was done differently and the Moai toppled that practice +might stop, if the Moai walked then the new change would likely be +added to the ritual. + +Since the walking of the Moai was associated with a mystical power or +*mana*, it is not difficult to imagine how the Moai would become of +such fundamental importance to the people. + +A giant electric motor +====================== + +It seems most of the Moai were carved out of the rock in a horizontal +position. + +Hence when turned through 90 degrees and stood upright, any magnetic +field that the rock had will now be 90 degrees out of phase with the +surrounding field. + +This may be the ideal orientation. + +Hence the standing Moai can be thought of as the coils of a giant +electric motor, driven by the island's magnetic field. + +As the Moai pass other Moai standing on ahu's this will cause electric +current to flow in those Moai, since a moving Moai creates a varying +magnetic field. + +Depending on the strength of this field, and noting that the Moai +should act like Tesla's Wardenclyffe towers and create standing waves +around the island, it is possible enough current would be generated to +create arcing between parts of the Moai. + +It has been stated by the Rapa Nui that Mana, or energy flowed when +eyes were added to the Moai eye sockets. + +If these are made of materials with the right properties they could +well act as giant capacitors that create just such a light show. + +Sea level changes +================= + +At times in the past much of Rapa Nui has been underwater. +Certainly, sea level has been much higher than it currently is. + +Undersea columns of harder rock may have been eroded by the sea. + +It is much, much easier to *launch* a Moai undersea, due to the +greater density of water to air. + +Perhaps this is how the first Moai were launched. + +The *Yonaguni* structure off the island of Taiwan in fract has two +natural columns that rise to just 2.5m below the sea surface. + +Note that *Yonaguni* is 100 miles off the coast of Taiwan. It appears +to be in a location that, like Rapa Nui, is one of the Lagrangian +points around which the earth's fields rotate. + +This shows that such natural structures can indeed be formed. + +Hence, one intriguing theory is that the Moai first walked under the +sea. + +Once an upright Moai is in a stable oscillation it could easily stay +upright as the sea level lowered, especially if there are multiple +such columns in resonance with each other. + +Standing waves in the ocean +=========================== + +If you place two columns under the ocean, a standing wave will emerge. + +The waves will be in harmony around the columns and help keep them +stable. + +If the columns are large enough and the forces applied to them are +small enough, they will be stable and in fact can withstand quite +strong forces, so long as the energy per oscillation of the column is +less than half the energy required for one oscillation. + +Deforestation +============= + +By the time Europeans arrived in 1772 there were no trees more than 3m +tall. + +It has been suggested that the deforestation was caused by excessive +harvesting of trees to use as rollers to move the Moai. + +However, if they *walked* on their own this cannot be the explanation +of the deforestation + +If the Maoi *walked* by themselves, then the spacings will be +such that a standing magnetic wave forms around them. + +The Moai are large enough to affect winds as they pass across the +island. + +It is likely that the Moai, given their positioning, will cause +standing waves to be created within any wind storm. + +The Moai would act like a lens focussing winds passing across the +island. + +This may have made it difficult for trees to grow larger than a +certain height, since the standing waves would simply blow them down. + + +Hence, rather than the deforestation being due to trees being +harvested to help move Moai, it may be the Moai themselves that caused +the deforestation. + +The Dance of the RongoRongo +=========================== + +There is an undeciphered text from Rapa Nui called *rongorongo*. + +Only a few samples survive. The writings were on pieces of wood. +One was on an old oar blade. + +Both sides of the oar are used. + +52 characters account for over 99% of the characters. + +That is a pack of cards, four sets of 13, ace through 10, jack, queen, +king. + +Four suits. Spades, hearts, diamonds, clubs. + +The Rapa Nui have a 13 month calendar. Most years have 12 full +moons, some have a bonus month. + +With four suits, each year pick one based on which quarter the moon is +in at the winter solstice. + +Now we have a symbol for the months. + +Now guess how *rongo rongo* is read? Round and round, like +everything in Rapa Nui. + +You start at the bottom, read right to left. At the end of the row, +mark with the thumb of your right hand, and twirl through 180 degrees. + +At the end of that row, twirl again, 180 degrees, but maybe reverse +the direction for fun. + +Now what could the tablets mean? What could be worthy of these +precious writing tools? And the scribes that could write. + +And what of the readers? What happened to them? They were the wise +ones the leaders of lands. + +When warriors arrived, they killed all the wise. + +Later they found the mysterious signs. + +They asked of the people can you help us to read. + +The ones that could read are watching from heaven. + +Well the Moai of course as they dance to the coast. + +Powered by *mana* from heaven above. + +And powered by earth as it drags to its centre. + +So the Moai did dance, in pairs, two by two. + +As the swayed and they rocked, + +As they hopped and they skipped, + +As they danced down the mountain to rest by the sea. + +As they came to their station + +Ahu by the sea. + +They turned to the mountain. + +To chants of delight. + +Each day the fine scribe, would draw the two dancers. + +The queen at the top the king down below + +Then dos-y-dos and off they do go. + +To meet at the centre, embrace and uncurl. + +A rongo rongo dance + +Of mystical beauty. + +Chant of the Moai +----------------- + +Eight lines on a tablet + +Each row twenty eight + +Four months of a dance a Moai did take. + +The king and the queen, in quantum delight + +Forever entangled to rock by the night. + + +Pismo s otoka Te Pito O Te Henua +-------------------------------- + +.. image:: rongo.jpg + +(Public Domain, screenshot from wikipedia.org) + + +Reference +========= + +https://www.youtube.com/watch?v=J5YR0uqPAI8 + +http://www.robertschoch.com/articles/schochbaddeleyeasterislandproposal.pdf diff --git a/docs/social.rst b/docs/social.rst new file mode 100644 index 0000000..cdff873 --- /dev/null +++ b/docs/social.rst @@ -0,0 +1,66 @@ +========= + Bobby's +========= + +Space and time are different aspects of the same thing. + +We can use time to put distance between us. + +Food stores are already doing this with semi-formal 8-9am seniors only +rules. + +Today I went out for a ride on the bike across Ottawa. + +Barely any traffic, but small business after small business closed. + +Small cafes, bars, restaurants, a bike shop, maps of the world. All +closed. + +I'm missing Bobby's after a winter of breakfasts on the way to the +hills. + +It's now March 23rd, a day later. + +Thoughts about how to distance in time. + +How much is two metres in time? + +Distracted by the bingo in Dublin. Distance, time and distributed consensus. + +Distance and time, different aspects of the same thing. + +We can social distance with time too. + +Imagine a community, 10 blocks in a city? Along the same bus route? + +What happens if only one tenth are outside each day? And they stay +inside the other nine? + +Today is day zero. If your zip code ends in a 0, you get to go to +your place of choice within 10 minutes walking distance. + +Tomorrow, will be day 1. And so on, unless some event resets the +clock. + +Such a strategy would need to be done alongside random testing to +allow tuning of the parameters and testing various hypotheses over +time. + +I suspect it might be wise to rotate staff in sync with customers, so +a place might need ten shifts, based on the same codes. So prepare to +be a trainee in case they are short when you visit. + +For a school, often friends and siblings are at the same school. So +do the day zero thing based on zip codes with families at schools and +teachers too. + +Oh and don't let anyone near the chefs. + +Combine it all with random testing so you can tune it a little. + +And add in noise of all sorts due to people misunderstanding the instructions. + +If new infections are zero for long enough, allow two digits out each day. + +But that's all a way down the road for now I'm afraid. + diff --git a/docs/transport.rst b/docs/transport.rst new file mode 100644 index 0000000..e13e794 --- /dev/null +++ b/docs/transport.rst @@ -0,0 +1,206 @@ +================ + Beyond the car +================ + +The car has shaped cities for many decades. + +Giant highways linking cities of congestion. + +Suburbs commuting to cities for work. + +How about a re-think? + + +Cities +====== + +Great cities are easy to get around. + +London and Paris, use the underground. + +Netherlands, ride a bike. + + +Everything but the last mile +============================ + +For many journeys it is only the last mile or so where the roads have +a reasonable volume of traffic, say 10 vehicles per minute. + +Let's build a network for the 10 per minute roads. + +The idea is to have a hierarchy of connections. + +Enter a pod, enter a destination and away you go. + +Slowly downtown, as pods move around 15km, weaving with bikes, and +taking the podlift over junctions. + +Synching with a collector that lifts the pod into the maglev network. + +For a short journey just stay in the pod, you'll be sent down the +slippage towards your destination. + +If you're on a bike, but with further to go, try a bike pod. + +Or take one of the routes that has bike antigravity assist. + +And if you are on foot then you can walk through all of town without +having to wait for vehicles. + +The last mile +============= + +Downtown, 10 block areas. + +Bikes, pedestrians and low speed (15-20km/h) lightweight vehicles. + +Magic shuttles 20km/h no stops. + +No door problems. + +Experiment with winter routes which take advantage of snow and ice. + +Dual: bike/ski routes? At least one should be good, whatever the +weather. + +Some days, you should just stay home and shovel. + + + +How to get from here to there? +============================== + +I wrote the above in December 2019. + +It's now mid-May and still snowing. + +How to make transit less risky with covid-19. + +Distancing is hard on a bus. + +Some things that may help: + +* open windows + +* fewer passengers + +* give the driver space and open windows. + +* less time on the bus. + +How can we have less time on the bus? + +With less traffic we can create bus priority routes. + +With more buses we can have more serving each route, so they don't all +stop at every stop. + +So how can we get more buses? + +One option is to divide the area into a number of segments. + +Now suppose you rotate the buses round the segments. They all work +one segment. So if there were ten segments, you would get ten times +the number of buses, with long gaps in between. + +Typical buses, you wait 30 minutes then 8 come along at once. + +Most buses will miss most stops, so you get down town faster, less +time to share air. + +If distancing is in force, keep all the buses running to reduce spread. + + +Contact tracing and the transit pass +------------------------------------ + +Many transit systems have some sort of payment card such as *Presto* +or *Oyster*. + +In many cases there is a high percentage of riders that are using the +cards. + +Each time a user taps, the system knows where they are. If they take +the bus, the system presumably knows the bus number and route. + +For rail, things are more ambiguous, since tapping is often enough to +get to a platform, but there is no information on which train is +taken. + +2021 vision +=========== + +So what happened to transit in 2020? + +Where I live. People stayed home. + +Transit use was way down. Town was quiet. Too quiet. + +This allowed those relying on transport to get to essential work in +un-crowded buses, with open windows. + +In my city a combination ... + +Bus service cut and buses kept to timetable, it is still common to see +buses waiting to avoid being early. + +When you factor in apps that work with open data feeds giving bus +location information, sticking to the timetable makes less and less +sense, the more regular a service becomes. + +Decisions to reduce spending on transport at this time, have missed an +opportunity to experiment with a contrarian approach to see just how +good the transport can be. + +Over the summer efforts focussed on active transport. Many cities +have seen a boom in cycling, in particular, there has been spectacular +change in many European cities, Paris being a very notable example. + +In Ottawa there have been significant efforts by the National Capital +Commission to make safe outdoor space available. + +There have been glimpses of what the city might be with a little +imagination. + +*Menard Laning* is a thing. This is the practice of building +temporary pop-up bike lanes courtesy of a local counciller buying a +few hundred traffic cones. + +It is disappointing that the city did not do more to encourage +more experiments during this period when traffic was dramatically +reduced. + +There are challenges in Ottawa, with severe winters and hot humid +summer days. The range of temperatures under which equipment has to +operate is some 80 degrees centigrade. A range which is likely to +increase as the planet warms. + +To compensate for this variation, the good news is that the short +range weather forecasts are generally very good. By short range, I +mean 1-3 days. Beyond that there is also a good general indication +of what the next 10 days will be like. + +Through the recent crisis we have learnt that much of society can +adjust to work in a new environment. + +As the climate changes the impacts on events such as Winterlude could +be significant. + +Rather than focus on a fixed time each year, it would make sense to +introduce events as certain milestones are reached each season. + +* the opening of the first stretch of the canal. +* the first un-interrupted 3km stretch +* Dow's lake open + +Arrange events for the opening. + +Use the forecast to predict likely schedule for the next week, adjust +as necessary. + +After heavy snow, close certain roads to traffic, build ski trails. + + + + diff --git a/docs/waves_in_time.rst b/docs/waves_in_time.rst new file mode 100644 index 0000000..4e94fc9 --- /dev/null +++ b/docs/waves_in_time.rst @@ -0,0 +1,155 @@ +=========================== + A theory of waves in time +=========================== + + +Forget everything you ever thought you knew about physics. + +Well, not quite everything. + +Bring with you everything you are sure you know. + +How do you know you know? + +Does this tell you something about the nature of information? + +BOTLOCOM +======== + + +Electron +======== + + +Proton +====== + + +Neutron +======= + +hydrogen + +oxygen + +Water +===== + +Dancing and harmony + +Pools, oceans and rivers +======================== + + +Gravity +======= + +Intertia +======== + +Constant G +========== + +Relativity +========== + +Black Hole +========== + +And the tale of the singularity that isn't. + +Gravitational Wave +================== + +Planck h +======== + +Kathryn Wheel +============= + +Schwartschild r +=============== + +Quanta +====== + +Quantum Uncertainty +=================== + +Snowy and the moon +================== + +Dark matter. + +Below the noise +=============== + +how quantum cryptography works. + +Math +==== + +Poincare, Einstein, Fourier, Tesla, Klein + +Godel, Escher, Bach + +Does God play Dice? +=================== + +If so, how? + + +Wnere to begin? +=============== + +Our universe is likely littered with black holes colliding with each +other. + +And this is now late in the day, just a billion years ago. + +So, let's begin and guess that our universe may have been born when +two masses, each roughly half the mass of our universe, merged into a +giant black hole. + +The two, ying and yang perhaps, merged throwing a ripple through the +time of space as the energy swirled inside, a new infinite harmony. + +Waves of almost equal amplitude, in every integer frequency of a +driving beat of time. + +The waves of energy would swirl like swirls of raspberry juice in a +bowl of custard. + +Vortices will form, as waves pass by and swirl in harmony. + +A tiny gyroscop of mass, resonating with anything sharing the +channel. + +Energy is conserved, so harmony is rewarded. + + +Skip to the neutron +=================== + +In our part of the universe, neutrons are pretty much the thing. +There are a lot of them about. + +From the outside of a neutron, you can view it as a standing wave in +the fabric of space time, running in circles, emitting a steady wave. + +Inside, there is all sorts going on, it is turtles all the way down. + +So the waves go by at the speed of light and rebound when they meet +with a similar beat. + +And they go with the flow, as that is all that they know. + +And harmony would emerge, but that energy rules. + + +self reference +============== + +When a system is self-referential, everything and nothing is circular. + + diff --git a/karmapi/backends/pipig.py b/karmapi/backends/pipig.py new file mode 100644 index 0000000..162e59a --- /dev/null +++ b/karmapi/backends/pipig.py @@ -0,0 +1,40 @@ +""" +A default backend. + +Or a new beginning? + +After many adventures, let's go with simple Tk, with a twist. + +Just display the latest image from the deque. + +pigfarm: Space Yard PillBox and MagicCarpet + + Space the base + + Yard with at Canvas as an artist + + PillBox: goal is a PIL.Image as artist + + MagicCarpet: + matplotlib and pandas world??? + +All come with different artists. + +pipig will focus on PIL, images, grids of data, often spherical. + +With the Canvas conversion to an image can be problematic. + +The PIL.Draw api is rich enough for karma pi needs and on a par with the canvas +api, so I don't need both here, let's stick to images. + +matplotlib will return images that can be similarly displayed, so I think we +may be good. + +Whereas adding an image to tk for display purposes is (relatively) seamless (?) + +So on the python side then PIL, or rather pillow + +Grids or projections from spheres + + +""" diff --git a/karmapi/backends/tkpig.py b/karmapi/backends/tkpig.py index 95afe00..4f58669 100644 --- a/karmapi/backends/tkpig.py +++ b/karmapi/backends/tkpig.py @@ -14,29 +14,20 @@ import curio -# import this early, I like pandas. -import pandas -random = pandas.np.random - import tkinter from tkinter import Tk, ttk, Text, messagebox -from matplotlib.backends.backend_tkagg import FigureCanvas, FigureManager - -from matplotlib.backends.backend_tkagg import ( - NavigationToolbar2TkAgg) - -from matplotlib.backends import tkagg - -from matplotlib.figure import Figure -from matplotlib import pyplot as plt import numpy as np +random = np.random from PIL import Image, ImageDraw, ImageTk -from pandas.formats.format import EngFormatter +try: + from pandas.formats.format import EngFormatter +except: + from pandas.io.formats.format import EngFormatter -from ripl import imagefind +from karmapi.finder import ImageFind from karmapi import base, yosser @@ -69,6 +60,10 @@ def setWindowTitle(self, title): def show(self): pass + def __str__(self): + + return str(self.__class__) + class Help: @@ -192,7 +187,7 @@ def recalc(self, width, height): def find_image(self, name): - return imagefind.interpret(dict(galleries=self.gallery, image=name)) + return ImageFind().interpret(dict(galleries=self.gallery, image=name)) class PillBox(Pig): @@ -282,13 +277,15 @@ class PlotImage(Pig): """ def __init__(self, parent, axes=[111], dpi=100, **kwargs): + from matplotlib.figure import Figure + from matplotlib.backends.backend_tkagg import FigureCanvas + super().__init__(parent) fig = Figure(dpi=dpi, **kwargs) self.image = FigureCanvas(fig, master=self) self.image._tkcanvas.pack(expand=1, fill=tkinter.BOTH) - #self.toolbar = NavigationToolbar2TkAgg(self.image, self) #self.toolbar.update() #self.toolbar.pack(expand=0) if axes is None: @@ -339,10 +336,9 @@ class XKCD(PlotImage): def plot(self): """ Display plot xkcd style """ + from matplotlib import pyplot as plt with plt.xkcd(): - np = pandas.np - data = np.ones(100) data[70:] -= np.arange(30) @@ -536,7 +532,7 @@ async def naptime(self, naptime=None): """ if naptime is None: - nap = 0.05 + naptime = 0.05 return naptime diff --git a/karmapi/base.py b/karmapi/base.py index 12234de..bc735b4 100644 --- a/karmapi/base.py +++ b/karmapi/base.py @@ -17,8 +17,14 @@ from collections import defaultdict from operator import itemgetter -import pandas -fft = pandas.np.fft +import numpy as np +fft = np.fft + +try: + import pandas +except Exception as e: + print(e) + print('NO PANDAS') from karmapi import flash @@ -104,7 +110,6 @@ def meta_data_match(path, key='gets'): """ Work our way along path looking for a match """ folders = list(path.parts) - print(folders) bases = [] relatives = folders[1:] @@ -203,7 +208,6 @@ def get_all_meta_data(path): path = [] for field in fields: path.append(field) - meta_data = meta.update( load_meta_path(Path(*path))) @@ -266,7 +270,6 @@ def build_from_meta(path): def load_meta_path(path): """ Load meta data a path if it exists """ filename = path / 'meta.json' - if filename.exists(): with filename.open() as infile: return json.loads(infile.read()) @@ -360,7 +363,8 @@ def load(path): """ path = Path(path) meta = get_all_meta_data(path) - + print(meta) + if (not path.exists()): # see if a peer has it got = try_pear(path) @@ -512,6 +516,26 @@ def show(self): get_value = itemgetter(1) for tag, ttime in sorted(self.tt.items(), key=get_value): - print(f'{ttime:8.3f} {tag}') + print("%8.3f %s" % (ttime, tag)) + + +def parse_date(date): + """ Parse a date """ + if date is None: + return date + fields = [int(x.strip()) for x in date.split('/')] + + + while len(fields) < 3: + fields.append(1) + + while len(fields) < 6: + fields.append(0) + + year, month, day, hour, minute, second = fields + + return datetime.datetime(year, month, day, hour, minute, second) + + diff --git a/karmapi/beanstalk.py b/karmapi/beanstalk.py index 1641bdd..03aa66d 100644 --- a/karmapi/beanstalk.py +++ b/karmapi/beanstalk.py @@ -154,7 +154,7 @@ def is_magic(self): def draw(self, canvas, width, height, colour): xx = self.xx * width - yy = self.yy * width + yy = self.yy * height canvas.create_text( diff --git a/karmapi/carpet.py b/karmapi/carpet.py index dc5895e..560f81e 100644 --- a/karmapi/carpet.py +++ b/karmapi/carpet.py @@ -8,7 +8,7 @@ class MagicMosaic(pigfarm.Space): - def __init__(self, parent, carpets=[]) + def __init__(self, parent, carpets=[]): super().__init__(parent) diff --git a/karmapi/cds.py b/karmapi/cds.py new file mode 100644 index 0000000..0766a2d --- /dev/null +++ b/karmapi/cds.py @@ -0,0 +1,64 @@ +""" +Coppernicus data service interface +""" + +import cdsapi + +c = cdsapi.Client() + +years = [ + '1979','1980','1981', + '1982','1983','1984', + '1985','1986','1987', + '1988','1989','1990', + '1991','1992','1993', + '1994','1995','1996', + '1997','1998','1999', + '2000','2001','2002', + '2003','2004','2005', + '2006','2007','2008', + '2009','2010','2011', + '2012','2013','2014', + '2015','2016','2017', + '2018' + ] + + +months = ['%02d' % x for x in range(1, 13)] + +days = ['%02d' % x for x in range(1, 32)] + +times = ['%02d:00' % x for x in range(0, 24)] + +years = ['1979'] +months = ['01'] +days = ['01'] + +print(years) +print(months) +print(days) +print(times) + +c.retrieve( + 'reanalysis-era5-single-levels', + { + 'product_type':'reanalysis', + 'format':'grib', + 'variable':[ + '2m_temperature','total_precipitation' + ], + 'year': years, + 'month': months, + 'day': days, + 'time':[ + '00:00','01:00','02:00', + '03:00','04:00','05:00', + '06:00','07:00','08:00', + '09:00','10:00','11:00', + '12:00','13:00','14:00', + '15:00','16:00','17:00', + '18:00','19:00','20:00', + '21:00','22:00','23:00' + ] + }, + 'download.grib') diff --git a/karmapi/checksum.py b/karmapi/checksum.py index 68594ea..795a115 100644 --- a/karmapi/checksum.py +++ b/karmapi/checksum.py @@ -208,3 +208,7 @@ def main(args=None): meta = dict(path=apath, timestamp=timestamp.isoformat()) base.save_meta(cpath.parent, meta) + +if __name__ == '__main__': + + main() diff --git a/karmapi/cpr.py b/karmapi/cpr.py new file mode 100644 index 0000000..9a93e2a --- /dev/null +++ b/karmapi/cpr.py @@ -0,0 +1,1231 @@ +""" +Not, CPR, but Colin P Rourke. + +Or CPU central processsor unit? + +CP R s t U + +CPR: show time universe + +Simulate nested spherical waves. + +Things have moved on a little. + +So each ball of nested waves will have a driver at the inside and at the +outside too. + +Different clocks at each layer. + +And then outer layers made up of other randomly placed nested spheres. + +But using a universal queue, so let each sphere run in its own co-routine. + +Update: 2018/8/4 +================ + +The Sphere and NestedWaves classes are moving along. + +For now, a sphere is represented by a square grid. + +We can decide later where the grid points lie. + +I have been experimenting with grids multiples of primes and made a few code +changes moving it closer to *anpotu*. + +Some interesting patterns emerging:: + + python3.6 cpr --base 0 --inc 23 -n 7 + +Update: 2018/8/9 + +The motivation for using grids with prime dimensions was that it makes it makes +it challenging for the spheres to stay in sync with each other. + +Their periods are co-prime. + +As a result, spirals emerge. + +In the initial runs there was a strong diagonal property developing. + +A smooth, square, space in the top left corner. + +A more random square bottom right, with the corners of these two squares meeting. + +Much symmetry for the bands to the top and left of the view. + +My interpretation is these bands show the layers largely being in sync. + +Regardless, another view of these grids is to view them from the north or south +pole. When you do that there are spirals everywhere. + +Feedback from the user base +=========================== + +:: + + The problem with all these new settings is that my computer can't manage + with a high enough base setting to get reasonably smooth output. + Eventually it all seizes up! You either need to run on a much faster + machine or simplify the code. The previous code before all these later + releases was much better in this respect. I could set base to 137 and get + a fairly responsive output. + + But it's all very interesting. + + You still haven' t told me what it has to do with the new paradigm! (Apart + from the 1/r decay). C + + +The performance has been bugging me too. + +I made some changes in how the spheres update and now they are busy hogging the +cpu. I'm working towards spreading the work across processors. + +Ironically, there's a python thing called the GIL in the way -- but that is +another story. [YOSSER] + +Re: the paradigm. Up to now I have pretty much been debugging the code. + +Puzzling over why the images were like they were, fixing up the code along the +way. + +Once I have the code stable again (?) the next phase is to embed these spheres +in a *celestial sphere*, summing the fields per de Sciama. + +Again, to begin with I will ignore all the physics and code something up that +we can then add some reality (?) to it once I have it working. + +I expect the paradigm to be more evident in this part of the code. + +Another thing to keep in mind it is easy to add new types of spheres: a quasar +with an accretion belt for example. + +I am also hoping there will be some *emergent* behaviour in the code, maybe +even galaxies spawning new ones. + +Johnny GILl 2018/8/28 + +YOSSER +====== + +So for now I am running each tick of a sphere by having curio spawn a thread. + +Let's change that to run in process. + +So what does it have to do with the Colin Rourke's new paradigm? +================================================================ + +*A new paradigm on the universe.* + +https://msp.warwick.ac.uk/~cpr/paradigm + +ISBN: 9781973129868 + +I am currently reworking my way through the first five chapters of the book. + +It is the third or fourth time through, each time with new understanding. + +It is a wonderful work, with compelling arguments. + +Chapter 2, Sciama's principle finishes with: + + Sciama's initiative, to base a dynamical theory on Mach's principle as + formulated i Sciama's principle, has never been followed up and this + approach to dynamics remains dormant. One of the aims of this book is to + reawaken this approach. + +One of the aims of karma pi is to help understanding of such theories. + +In particular, help my own understanding with computer simulations. + + +""" +import math + +import argparse + +from collections import deque, defaultdict, Counter, namedtuple + +import asyncio +curio = asyncio + +import numpy as np + +from PIL import Image, ImageTk + +from karmapi import tpot, prime + +from blume import magic, farm + +from random import random, randint, gauss, shuffle + +class Sphere: + """ If it hass mass (m) then pass through waves + + Regardless, show the view at radius r from centre of mass. + + omega: angular velocity, three orthogonal directions + + velocity: relative to what??? + """ + + def __init__(self, size=None, + t=0, m=None, r=None, omega=None, velocity=None, mu=None, + twist=True, boundary=None): + + # resolution + size = size or (4, 4) + + ww, hh = size + + self.rgb = np.zeros(shape=(ww, hh, 3)) + + self.size = size + self.history = {} + self.delta = False + + self.last_ball = None + self.next_ball = None + + self.boundary = boundary or 'zero' + + self.twist = True + + #self.fade = 1 / math.e + self.fade = 1 + + self.t = t + + self.paused = False + + # Default for mass?? + if mu and m: + m = gauss(m, mu) + + self.M = m + + self.omega = omega or [random() for x in range(3)] + self.velocity = velocity or [random() for x in range(3)] + + # radius corresponding to grid view??? + self.r = r + + # time moves slower in the inner spheres? + # FIXME? + #self.sleep = self.size[0] / 1000 + self.sleep = self.size[0] / 100 + self.sleep=.5 + + self.reset(init=True) + + def __repr__(self): + """ Show mass size and radius """ + return f'Ball: r = {self.r} M = {self.M} size = {self.size}' + + def reset(self, init=False): + """ Reset the sphere """ + + self.random_grid() + + return + + async def pause(self): + + self.paused = not self.paused + + async def more_sleepy(self): + """ Make the ball sleep more """ + self.sleep *= 2 + + + async def more_wakey(self): + """ Make the ball sleep less """ + self.sleep /= 2 + + + def random_grid(self): + + width, height = self.size + nn = width * height + + self.rgb = (np.random.random(size=(width, height, 3)) - 0.5) * 2 + + + def get_views(self): + + views = dict( + grid=self.rgb2grid, + northpole=self.northpole, + southpole=self.southpole, + uphemi=self.uphemi, + lowhemi=self.lowhemi) + + return views + + def project(self, view, quantise=True): + """ Quantise and project the data """ + + #image = Image.new('RGB', (self.size[0], self.size[1])) + + # FIXME do the 256 magic int stuff here + if self.rgb.dtype != np.uint8: + print('quantising') + pixels = self.quantise(self.rgb).astype(np.uint8) + else: + pixels = self.rgb + + pixels = self.get_views().get(view, self.rgb2grid)(pixels) + print('PPPP', view, pixels.shape) + + return pixels + + def rgb2grid(self, pixels=None): + """ Change lists of red green blue to a pixel grid""" + if pixels is None: + pixels = self.quantise(self.rgb) + return pixels + + + def poleview(self, pixels, scale=1, wind=1): + """ View from a pole """ + + # make black everywhere + width, height = self.size + + grid = np.zeros(shape=(width, height, 3), dtype=np.uint8) + grid += 127 + + xorig = int(width / 2) + yorig = int(height/ 2) + + ww, hh, bands = pixels.shape + print('ww hh', pixels.shape) + + for xx in range(hh): + for yy in range(ww): + + # so radius yy from centre and xx how far round the circle + angle = wind * xx * 2 * math.pi / width + + xoff = yy * math.cos(angle) / scale + yoff = yy * math.sin(angle) / scale + + xpos = int(xorig + xoff) + ypos = int(yorig + yoff) + + xpos = xpos % height + ypos = ypos % width + + grid[ypos][xpos] = pixels[yy][xx] + + return grid + + def northpole(self, pixels): + """ Give a circular view from the north pole """ + return self.poleview(pixels, scale=2) + + def southpole(self, pixels): + """ Give a circular view from the south pole """ + pixels = pixels[::-1] + + return self.poleview(pixels, scale=2, wind=-1) + + def uphemi(self, pixels): + """ show upper hemisphere """ + nn = int(pixels.shape[0] / 2) + pixels = pixels[:nn] + + return self.poleview(pixels) + + def lowhemi(self, pixels): + """ show lower hemisphere """ + nn = int(len(pixels) / 2) + pixels = pixels[::-1][:nn] + + return self.poleview(pixels, wind=-1) + + async def run(self, elsewhere=True): + """Run the sphere + + Really want to just add to queue and let something else + do the running. + + We already have yosser so maybe should ask to help? + + Want yosser to pop off the queue, run it, push back on at other + end of queue? + + what to do about last and next ball. + + don't really want them to update + + how about ball locks? + + will there be dead locks? + + should something else supervise when balls run? + + Latest arun() run here, prun() try another process. + + elsewhere decides which, default here. + """ + + if elsewhere: + return await self.prun() + + return await self.arun() + + async def arun(self): + """ Run in current process """ + while True: + self.tick() + self.post_tick() + await curio.sleep(self.sleep) + + + async def prun(self): + + if not self.paused: + #XSball = await curio.run_in_process(self.tick) + print('TICKING', self) + ball = self.tick() + print('TICKING', ball) + #print(f'{self} sleep:{self.sleep}') + + # hack, just move stuff around + self.post_run_update(ball) + self.post_tick() + + def post_run_update(self, ball): + """ Hack running in process """ + self.rgb = ball.rgb + + self.t = ball.t + + + def post_tick(self): + """ Do any post tick stuff that is not cpu blocking """ + pass + + def tick(self): + """ Do one tick for the sphere + + so self.t is also a count of how often we've been here ?? + + at least in this thread. + + """ + + self.t += 1 + + # Here if we are between two spheres + # so have last_ball and next_ball + + # for each point in grid select corresponding + # points in inner/outer spheres + + lb = self.last_ball + nb = self.next_ball + + n1, n2 = self.size + + ix = 0 + deltax = (1 / (2 * n1)) * 2 * math.pi + deltay = (1 / (2 * n2)) * 2 * math.pi + + cbweight = self.weight(self) + lbweight = (lb or self).weight(self) + nbweight = (nb or self).weight(self) + + #cbweight = lbweight = nbweight = 1 + + #print(cbweight, lbweight, nbweight) + + xgrid = list(range(n2)) + ygrid = list(range(n1)) + + #cbweight = lbweight = nbweight = 1 + #print(self, 'weights', lbweight, cbweight, nbweight) + + nbc = lbc = (0., 0., 0.) + + shuffle(ygrid) + for y in ygrid: + #curio.sleep(0) + y1 = (y / n2) * 2 * math.pi + y2 = y1 + deltay + + shuffle(xgrid) + for x in xgrid: + #curio.sleep(0) + + x1 = (x / n1) * 2 * math.pi + x2 = x1 + deltax + + if lb: + lbc = lb.sample(x1, y1, x2, y2) + else: + if self.boundary == 'random': + lbc = tuple(randunit() for c in 'rgb') + + if nb: + nbc = nb.sample(x1, y1, x2, y2) + else: + if self.boundary == 'random': + nbc = tuple(randunit() for c in 'rgb') + + tix = cix = y, x + + if n1 == n2 and self.twist: + tix = tuple(reversed(tix)) + + cbc = self.rgb[cix[0]][cix[1]] + + #print(lbc, cbc, nbc) + + value = [((aa * lbweight) + + (bb * cbweight) + + (cc * nbweight)) * (1 / math.e) + for aa, bb, cc in zip(lbc, cbc, nbc)] + + + self.rgb[tix[0]][tix[1]] = value + + return self + + + def weight(self, ball): + + delta_r = abs(ball.r - self.r) + + + if delta_r == 0: + return self.M or 1 + + weight = (self.M or 1) / (delta_r ** self.fade) + #print(delta_r, self.M or 1, self.fade, weight) + + return weight + + + def quantise(self, value): + + value = value - np.trunc(value) + + value = 127 + (value * 128) + value = np.clip(value, 0, 255) + + return value + + + def setup_wave(self): + """ Do some set up work for a sphere with mass """ + + self.waves = {} + self.inc = math.pi/20 + + for c in 'rgb': + phase = random() + scale = 1 # was random() wondering if should just use 1? + + self.waves[c] = [c, phase, scale] + + + def sample(self, x1, y1, x2, y2): + """ Return a pixel given a rectangle + + x1, y1, x2, y2 are real + + Want to select a point from a rectangle around this + point. + + allowing the rectangle to wrap around, identifying the left right + edges as well as the top and bottom. + + (perhaps make this optional?) + """ + + # radians per x-step + deltax = 1 / self.size[0] + deltax *= 2 * math.pi + + # radians per y-step + deltay = 1 / self.size[1] + deltay *= 2 * math.pi + + # width height of rectangle. + xdelta = x2 - x1 + ydelta = y2 - y1 + + # expansion or contraction modulus + xk = int(xdelta / deltax) + + xk = xk or 1 + + xx = int(x1 / deltax) + + xk2 = xk // 2 + xx = randint(xx-xk2, xx + xk - (1 + xk2)) + + yk = int(ydelta / deltay) + yk = yk or 1 + + yy = int(y1 / deltay) + + yk2 = yk // 2 + yy = randint(yy - yk2, yy + yk - (1 + yk2)) + + return self.rgb[xx][yy] + + + +class NeutronStar(Sphere): + """ + + An sphere with a mass + + Just supply the mass. + + or... maybe a bit more complex. + + So, nest some waves and figure out project and sample. + + So what radii are interesting? + + Each star, or galaxy can have its own process, and a pi can run a + good few stars. + + + """ + def reset(self, init=False): + """ Reset the sphere """ + + super().reset(init) + self.setup_wave() + + + def tick(self): + """ wave + + red, green, blue + + let's do: + red up down + blue left right + green in and out all over + + How to fill in self.grid? + """ + n1, n2 = self.size + width = 2 * math.pi + height = math.pi + + rc, rphase, rscale = self.waves['r'] + gc, gphase, gscale = self.waves['g'] + bc, bphase, bscale = self.waves['b'] + + for x in range(n1): + xx = ((x / n1) + (1 / (2 * n1))) * 2 * math.pi + + xx += self.inc * self.t + + for y in range(n2): + + yy = (y / n2) + (1 / (2 * n2)) * 2 * math.pi + yy += self.inc * self.t + + self.rgb[x][y][0] = sample_wave(rphase, xx) * rscale + self.rgb[x][y][1] = sample_wave(bphase, yy) * bscale + + # not sure xx is the right thing here + self.rgb[x][y][2] = sample_wave(gphase, xx) * gscale + + + if self.boundary != 'none': + super().tick() + else: + self.t += 1 + + return self + + +def randunit(): + + x = random() + if random() > 0.5: + x *= -1 + + return x + +def sample_wave(phase, x): + + xx = x + (2 * math.pi * phase) + + return math.sin(xx) + + + + +class NestedWaves(magic.Ball): + """ Inner and outer spheres + + simulated annealing inspired in between? + + but put it in the tea pot too. + + + Lots of tea pots of all kinds. + + and draw slices on the canvas from the yard. + """ + + def __init__(self, balls=None, fade=1, twist=True): + """ Initialise the thing """ + + super().__init__() + + # expect we'll find something to do with a queue + #self.uq = curio.UniversalQueue() + + self.views = ['grid', 'northpole', 'southpole', 'uphemi', 'lowhemi'] + self.view = 0 + self.fade = fade + self.twist = twist + self.spheres = [] + + # interesting -- already magic roundabout could help. + self.build(balls) + + # event handling + self.add_event_map(' ', self.pause) + self.paused = False + self.add_event_map('o', self.reset) + + self.dball = 0 + self.add_event_map('j', self.backward) + self.add_event_map('k', self.forward) + self.add_event_map('v', self.next_view) + self.add_event_map('b', self.previous_view) + self.add_event_map('d', self.lessfade) + self.add_event_map('f', self.morefade) + self.add_event_map('s', self.more_sleepy) + self.add_event_map('w', self.more_wakey) + self.add_event_map('t', self.toggle_twist) + + self.sleep = 0.05 + + + def add_event_map(self, key, coro): + + self.add_filter(key, coro) + + + async def lessfade(self): + """ Decrease r exponent """ + self.fade -= 1 + print(f"metric: 1 / (r ** {self.fade})") + + async def morefade(self): + """ Increase r exponent """ + self.fade += 1 + print(f"metric: 1 / (r ** {self.fade})") + + async def more_sleepy(self): + """ Sleep more + + Tell each ball and self to sleep more + """ + await self.sleepy() + + for ball in self.balls: + await ball.more_sleepy() + + + async def more_wakey(self): + """ Sleep less + + Tell each ball and self to sleep less + """ + await self.wakey() + + for ball in self.balls: + await ball.more_wakey() + + async def toggle_twist(self): + """ Toggle 90 degree twist + + Tell each ball to toggle twist + """ + self.twist = not self.twist + + for ball in self.balls: + ball.twist = self.twist + + + async def pause(self): + """ Pause """ + self.paused = not self.paused + for ball in self.balls: + await ball.pause() + + async def reset(self): + """ Reset waves """ + await self.cancel() + + for ball in self.balls: + ball.reset() + + await self.start() + + async def forward(self): + """ Move to next sphere """ + self.dball += 1 + self.dball %= len(self.balls) + + async def backward(self): + """ Move to previous sphere """ + self.dball -= 1 + if self.dball < 0: + self.dball = len(self.balls) - 1 + + async def next_view(self): + """ next view """ + self.view += 1 + self.view %= len(self.views) + + async def previous_view(self): + """ previous view """ + if self.view: + self.view -= 1 + else: + self.view = len(self.views) - 1 + + def build(self, balls): + """ Create the balls """ + # add a bunch of spheres to the queue + self.balls = [] + last_ball = None + + for sphere in balls: + + if last_ball: + sphere.last_ball = last_ball + last_ball.next_ball = sphere + + # may need to revisit this, spread some work + # self.uq.put(sphere) + print('adding ball', sphere.size) + sphere.fade = self.fade + self.balls.append(sphere) + + last_ball = sphere + + + + async def random_step_some(self): + """ Step all balls once """ + balls = self.balls[:] + while balls: + ix = randint(0, len(balls)-1) + print('stepping ball', ix) + await balls[ix].run() + + del balls[ix] + + async def backward_step_all(self): + """ Step all balls once """ + balls = self.balls[::-1] + while balls: + #ix = randint(0, len(balls)-1) + ix = -1 + + print('Stepping:', balls[ix]) + #await balls[ix].magic_tick() + balls[ix].tick() + + del balls[ix] + + async def step_balls(self): + """ step all the balls once + + or maybe a random ball? + """ + n = randint(0, len(self.balls) - 1) + + for ball in range(n): + ball = self.pick() + + await ball.run() + + def pick(self): + """ Choose a ball """ + return self.balls[randint(0, self.n-1)] + + def draw(self): + + # xx = randint(0, self.n - 1) + xx = self.dball + + ball = self.balls[xx] + print(xx, 'lucky for some', ball.size, ball.M) + + self.draw_ball(ball) + + + async def publish(self, ball): + + width, height = self.size, self.size + + image = ball.project(self.views[self.view]) + + #image = image[::, ::, 1] + image = Image.fromarray(image) + image = image.resize((int(width), int(height))) + + await self.outgoing.put(image) + + def draw_ball(self, ball): + """ wc has everything???? + + feels like I have written this bit 20 times + """ + + print('DRAW_BALL', type(self)) + + #width, height = self.size, self.size + + width, height = ball.size + + image = ball.project(self.views[self.view]) + + + #image = image[::, ::, 1] + image = Image.fromarray(image) + image = image.resize((int(width), int(height))) + self.ax.imshow(image) + + + async def start(self): + + return + + spheres = [] + for ball in self.balls: + sphere = await curio.spawn(ball.run) + spheres.append(sphere) + await curio.sleep(ball.sleep) + + self.spheres = spheres + return spheres + + async def cancel(self): + + for ball in self.spheres: + await ball.cancel() + + + async def run(self): + """ Run the waves """ + + + #self.set_background() + + print('RANDOM STEP TIME') + await self.random_step_some() + + spheres = self.spheres + + print('NESTED WAVES Running') + try: + self.ax = await self.get() + + self.draw() + self.ax.show() + print('ball drawn') + #await self.step_balls() + + except curio.CancelledError: + print('cancelling balls from nested waves') + for ball in spheres: + print('cancelling', ball) + await ball.cancel() + + raise + + +def generate_spheres(sizes, clazz=None, mass=None, radii=None, + iboundary='zero', oboundary='zero'): + + clazz = clazz or NeutronStar + xclazz = clazz + + first = True + sizes = list(sizes) + n = len(sizes) + + mass = mass or [1] + while len(mass) < n: + mass.append(mass[-1]) + + radii = radii or range(n) + + + dr = radii[-1] - radii[-2] + while len(radii) < n: + radii.append(radii[-1] + dr) + + K = 2 + + boundary = iboundary + for r, nn, M in zip(radii, sizes[:-1], mass): + + size = nn + + size = (size, size) + + #M = 1.0 * K + + #mu = M / 10 + + R = 1 * r + + #M = M / (R+1) + #mu = M / 10 + + mu = None + sphere = clazz(size, r=R, m=M, mu=mu, boundary=boundary) + + clazz = Sphere + boundary = 'none' + + yield sphere + + # Add an outer sphere too + size = sizes[-1] + size = (size, size) + + #M = 10 * M + #mu = M / 10 + print(xclazz) + if oboundary != 'none': + yield xclazz(size=size, r=r+1, m=M, mu=mu, boundary=oboundary) + + +def prime_balls(base, n): + """ Generate next n primes starting at base""" + + for nn in range(base, 1000_0000): + + if not prime.isprime(nn): + continue + + print('prime', nn) + yield nn + + n -= 1 + if n == 0: + return + +def pi_balls(base, n): + """ Generate next n pi-based balls starting at base + + pi = 4 * sum((-1)^n * (1/(1 + (2*n)))) + """ + # for now, punt to prime balls + return prime_balls(base, n) + + + +class CelestialSphere(NestedWaves): + """ An outer sphere of nested waves + + Embed random neutron stars in a de Sitter Space + + Present a window onto this sphere to inner layers. + + N = a / M for number of stars + + Give them mass, velocity to get ball rolling + + Each star does its own thing, schedules itself to run. + + Stars collide -- for now do pass through. + + Just model gravitational wave + + reflect what passes its way + """ + def __init__(self, parent, a=1, n=None, m=None): + """Initialise. + + *a* is the size of the universe + + *m* the mean mass of galaxies. + + *n* is the number of galaxies. + + However, we assume: + + n = a / m + + By setting a = 1 as a default, you can control the + expected number of galaxies by setting m to 1/n. + + + So, for ~7 galaxies, set m to 1/7 or just supply n == 7 + + + Where to put the galaxies? + + Should really put them in de Sitter Space + + A 4-dimensional subspace of a 5 dimensional Minkowski space + + metric + + ds**2 = sum ((x[i] - y[i]) ** 2) - (t - u) ** 2) + + R = sum ((x[i] - y[i]) ** 2) - (t - u) ** 2)) ** 0.5 + + + For now just place randomly in unit sphere with random velocity? + + Relative to the centre of the unit sphere? + + But try to set it to be in sync with the existing balls *** + + So don't need velocity after all. + + Just record each run what it is, balanced by the grid. + + For now everything is on a p * p grid, with p grids to make a cube. + + Each grid can be viewed as the surface of a sphere, latitude and + longitude grids. + + Aim to be able to navigate the grid of galaxies. + + Some interesting possibilities arise as sizes of grids vary. + + Elliptic curves and modular forms??? + """ + + super().__init__(parent) + + n = n or a / m + a = a or n * m + m = a / n + + self.n = n + self.m = m + self.a = a + + + def build(self): + """ Create the balls + + Really should place them in the five dimensions, + + but have a constraint that gets us down to four dimensions. + + For now, place them randomly in a unit cube. + """ + self.balls = {} + for wave in range(self.n): + + self.ball[wave] = Sphere(m=1, mu=0.1) + + # where is it? what's the observer? + + + + async def run(self): + """ ??? """ + + +def argument_parser(parser=None): + + parser = parser or argparse.ArgumentParser() + + parser.add_argument('-a', type=int, default=1) + parser.add_argument('-n', type=int, default=10) + parser.add_argument('--twist', type=bool, default=True) + parser.add_argument('--fade', type=int, default=1) + parser.add_argument('--stride', type=int) + parser.add_argument('-m', type=int, default=1) + parser.add_argument('--base', type=int, default=20) + parser.add_argument('--mass', nargs='*', type=float) + parser.add_argument('--radii', nargs='*', type=float) + parser.add_argument('--iboundary', + choices=['random', 'zero', 'none'], + default='zero') + parser.add_argument('--oboundary', + choices=['random', 'zero', 'none'], + default='zero') + + parser.add_argument('--play', default='') + + return parser + +def random_prime_balls(nmin, nmax): + """ generate a random prime balls """ + while True: + base = random.randint(nmin, nmax) + ball = list(prime_balls(base, random.randint(3, 13))) + yield ball + + +def args_to_spheres(args): + + if args.stride: + stride = args.stride + start = args.base + end = start + (args.n * args.stride) + + balls = range(start, end, stride) + else: + balls = prime_balls(args.base, args.n) + + print('balls', balls) + spheres = list(generate_spheres( + balls, + mass=args.mass, + radii=args.radii, + iboundary=args.iboundary, oboundary=args.oboundary)) + + return spheres + +async def run(args): + + # pass list of balls into NestedWaves + spheres = args_to_spheres(args) + + land = farm.Farm() + + waves = NestedWaves( + balls=spheres, fade=args.fade, + twist=args.twist) + + land.add(waves) + land.shep.path.append(waves) + + await farm.start_and_run(land) + + + +def main(): + + parser = argument_parser() + + args = parser.parse_args() + + curio.run(run(args)) + +if __name__ == '__main__': + + main() + + + + + diff --git a/karmapi/epigume.py b/karmapi/epigume.py new file mode 100644 index 0000000..52febd6 --- /dev/null +++ b/karmapi/epigume.py @@ -0,0 +1,21 @@ +""" Recipe for love and life in harmony """ + +from math import e, pi +from time import sleep +from random import randint + +h = me = 1 +n = 0 +while True: + n += 1 + print(n, h, me, abs(h-me) / n) + + h, me = me, h + + h *= pi + + me *= e + + sleep(randint(0, n)) + + diff --git a/karmapi/eric.py b/karmapi/eric.py index 4c0b51a..65cc3d7 100644 --- a/karmapi/eric.py +++ b/karmapi/eric.py @@ -85,7 +85,7 @@ async def run(self): async def start(self): if self.farm.current: - self.filename = instpect.getsourcefile(self.farm.current) + self.filename = inspect.getsourcefile(self.farm.current) diff --git a/karmapi/filly.py b/karmapi/filly.py new file mode 100644 index 0000000..5ceba61 --- /dev/null +++ b/karmapi/filly.py @@ -0,0 +1,457 @@ +""" Fantasy Insured Loss LotterY + +So lets play fantasy insured loss estimates. + +Here's how the games works. + +A natural catastrophe occurs. + +Modelling agencies and companies estimate how much they will lose. + +Here we try to guess how these loss estimates will change over time. + +This is really just a game of magic denoinators. + +When an estimate is given what is included is often unclear. + +So an estimate from RMS a couple of days prior to Harvey landfall said the wind +losses would be $1-6B. + +How did they arrive at this number? + +1. Estimate the category of storm at landfall. +2. Find events that "match". +3. Weight events according to how good a match. +4. Run best guess of industry exposure through the model. + +Problems? +========= + +Many. Not least the model is tuned to previous events. + +48 inches of rain did not used to be the norm. + +And most residential policies exclude flood, so who cares anyway? + +And what about cars: well they are roughly 5-10% of the wind exposure -- your +car is worth way less than your home. + +But wait: car insurance covers flood damage. + +But we don't have a flood model. Or if we do it has never seen 4 feet of rain. + +Harvey, Irma, Jose, Katia, Maria, Mexico Quake, California fires. + +Economic Loss. + +Insured loss. + +Reinsurance + +ILS. + + +Track reports over time. + +Predict who will still be here in n years time. + +Losses are in $1B unless otherwise mentioned. + +Multiple events and multi year contracts. + +x% of contracts are aggregate covers and deductibles drop down. + +x% are multi year. Premium is fixed and deductibles drop down when the +threshold is reached. + +Bonuses +======= + +Report early, report detail. + +An early loss report indicates: + +* strong analytics, able to make estimates fast. + +* confidence in your model of risk. + +Detail: + +* more detail to support the assertions. This reduces the uncertainty in the + magic denominator. + +* but bragging about a detailed model, that ignores many factors is a negative bonus. + +So what of next year, 2018? +=========================== + +Triggers have triggered, new deals have been written. + +Multi year deals, a multi year roller. + +What of events? + +So 2017 again? Or maybe 2016? + +Will the ocean still be warm? A definite yes. + +Will there be shear? It depends on the ENSO and other fine factors. + +The moon? No eclipse, but tides running higher. + +Will there be landfalls? Strong storms seem to favour keeping the eye off land. + +But sometimes so strong they cannot resist. + +Model adjustments: too soon to be sure, but a tweak here and there. + +Take Maria, a giant cat 5. How many cat 5's hit PR in 10K years of a model? + +1? 2? 3? 10, 20, 30? + +How many of those are 180 mph? + +So a one in 1000, you're having a laugh. + +So I don't have events for 2016, but just lets pretend its 2017 / pi. + +Now lets see what 2018 might be. + +Correlation, you see +==================== + +So modellers for years have debated series. A string of events but no common thread. + +They look at starts, arrivals are negative binomial. + +The sd = mean * 1.15 + +yBut not enough data to surely be sure. + +So lets just pretend they don't come in threes. + +Yet drivers are 100% correlated: hot sea, low shear, and landfall too. + +And two storms out at sea, maybe even 3, feed it each other and share the energy. + +So though far away, Maria feeds Irma and Lee feeds Maria. + +And the seas that are swelling help Ophelia to form. + +Driven by a moon in a total eclipse year. + +Curio +===== + +So this is all about events and events are what curio does. + +Probably all that will be needed here is curio.run() + +So one goal here is to make forecasts, for time periods ahead. + +The first guess is no change. + +The aim is to do better than that, for some definition of better. + +So lets say closer to what happens. + +Bonus marks if errors over time turn out to have been useful estimates. + +Start with skill = None and update if evidence warrants. +""" + +from math import pi +import random +import argparse + +from datetime import date +from collections import defaultdict, deque + +import copy + +# stinging bats and swooping manta rays +import curio + +INSURED = 0.8 + +INSURED_FLOOD = 0.1 + +INSURED_WIND = 0.9 + +AUTO_FLOOD = 1.0 + +# share of contracts that are multi year +MULTI_YEAR = 1.0 / pi + +# Drop down deductible +DDD = 1.0 / pi + +class Event: + + def __init__(self, name, loss, ifactor=None): + + self.name = name + + self.loss = loss + + + self.ifactor = ifactor or INSURED + + +class Report: + + def __init__(self, name, event, when, value): + + self.name = name + self.event = event + self.date = when or date.now() + + +class Org: + + def __init__( + self, + name, + premium=None, + noncat=0.0, + ceded=0.0, + share = None, + capital = None, + aggloss = None, + maxloss = None, + skill=None): + + self.name = name + + # market capitalisation: how the stock market values the organisation + self.capital = capital + + # annual written premium + self.premium = premium or self.capital / 5.0 + + # share of premium for noncat lines + self.noncat = noncat + + # share of premium that is ceded + self.ceded = ceded + + # skill this is the denominator. + # How much of what you think you know is true? + # For now None or a number 0 < n < 1? + # Divide by this to measure the error? + self.skill = skill + + # estimate of market share + self.share = share or self.premium / 100. + + # Track agg loss and maxloss and error too, but throw in some salt + igul = random.randint(1, 50) + rigul = random.random() * self.share * igul + self.aggloss = aggloss or rigul + self.maxloss = maxloss + + self.deductable = 1.0 + + self.events = deque() + + def add_event(self, event): + + self.events.put(event) + + def tick(self, now=None): + """ Crank the clock foward, see how it looks """ + + now = now or date.now() + event = self.event.pop() + + # calculate loss + loss = event.loss * self.share + self.aggloss += loss + + # update error + self.error += loss / (self.skill or random.random()) + + + + + def score(self): + loss = self.loss + skill = self.skill or random.random() + + return loss, loss / skill + + +Orgs = dict( + renre = Org('renre', + premium=1.4, + noncat=0.3, + ceded=0.3, + share=0.01 * INSURED, + capital=5.6), + + axis = Org('axis', + premium=1.5, + noncat=0.3, + ceded=0.1, + capital=4.8), + + tmr = Org('tmr', + premium=1.4, + noncat=0.2, + ceded=.25, + capital=1.4), + + partner = Org('partner', + premium=1.4, + noncat=0.4, + ceded=.25, + capital=6.56), + + arch = Org('arch', + premium=None, + capital=12.56, + ), + aspen = Org('aspen', + premium=0, + capital=2.5), + + xl = Org('xl', + premium=0, + capital=10.5), + + everest = Org('everest', + premium=0, + capital=10.5), + ) + + +Events = dict( + harvey = Event('harvey', 100, 0.2), + irma = Event('irma', 100, 0.2), + maria = Event('maria', 80, 0.5), + jose = Event('jose', 1, 0.3), + katia = Event('katia', 1, 0.3), + nate = Event('nate', 1, 0.5), + ophelia = Event('ophelia', 2, 0.8), + mexicoq = Event('mexico', 25, 0.5), + calfire = Event('calfire', 10, 0.8), + + # meta events 15B to Bermuda reinsurers. Say it + # really looks like 3 * 40B events. + # So numbers for orgs should be roughly in line + # compare to other losses... note no Maria? + bdaharirm = Event("Bermuda Harvey Irma", 120, 1.0), + minthegap = Event("igul - cgul", 20, 1.0), + ) + +MoreEvents = dict( + ophelia = Event('ophelia', 10, 0.8), +) + + +q3 = [x for x in Events.values()] + +# Reports so far on losses +Reports = [ + Report(Orgs['renre'], q3, date(2017, 10, 6), 0.625), + Report(Orgs['partner'], q3, date(2017, 10, 6), 0.475), + Report(Orgs['axis'], q3, date(2017, 10, 12), 0.585), + Report(Orgs['xl'], q3, date(2017, 10, 12), 1.48), + Report(Orgs['everest'], q3, date(2017, 10, 12), 1.2), + Report(Orgs['arch'], q3, date(2017, 10, 12), 0.345), + Report(Orgs['aspen'], q3, date(2017, 10, 17), 0.360), + ] + +# factor to apply to premium to get reinsurance loss +MAGIC = 0.001 + +def race(hash, codehash=None, seed=None): + """ filly on a chain race + + """ + + # do something useful + + # add the time, the seed and the code hash + + # save the results + + # checksum all of this and the incoming hash + + # are we done aka did I win aka small checksum? + + # declare game over + + # aggregate saved results + + # checksum all of this + + # pass it on + + # do deltas + + # when deltas have enough leading zeroes + + # declare winner + + # rinse and repeat + pass + + +if __name__ == '__main__': + + events16 = {} + for key, event in Events.items(): + + eee = copy.copy(event) + + eee.loss /= pi + + events16[key] = eee + + + years = { + 2016: events16, + 2017: Events, + 2018: [Events, events16]} + + # Estimate losses + elosses = {} + aggloss = defaultdict(float) + + for ename, event in Events.items(): + print(ename) + losses = {} + for oname, org in Orgs.items(): + loss = event.loss * org.premium * MAGIC + print(oname, loss) + aggloss[oname] += loss + + elosses[ename] = losses + print() + + # show agg losses + print() + print('Aggregate Loss') + for org, loss in aggloss.items(): + print(org, loss) + + # Compare to reports + for report in Reports: + pass + + + parser = argparse.ArgumentParser() + + parser.add_argument('--seed') + parser.add_argument('--hash') + parser.add_argument('--codehash') + + args = parser.parse_args() + + + seed = args.seed + hush = args.hash + codehush = args.codehash + + race(hush, seed=seed, codehash=codehush) diff --git a/karmapi/gilliam.py b/karmapi/gilliam.py new file mode 100644 index 0000000..320d6b3 --- /dev/null +++ b/karmapi/gilliam.py @@ -0,0 +1,92 @@ +""" The tale of Gilliam and the GILly + +So before anyone complains, this all came about because of this: + +@freakboy3742 aka Russell Keith-Magee:: + + I'm suddenly very disappointed that in all Python's history with the GIL, + nobody has name.. a GIL-related package GILLIAM. + +So here it is. + +There's more to the story of course. + +The bigger the conference the more likely someone will propose a GILectomy. + +It is like Godwin's law, but it ends in surgery. + +And the patient awakes, dazed and confused and only three times slower the before surgery. + +But low hanging water melons abound so more fun to come. + +I must have been using python nearly five years before I was aware of this GIL +thing there. + +In DC, 2003 perhaps. + +There were these things called threads, they talk to each other. + +Actually, mostly they did not do too much talking. + +Most times you used them to do n things at once. + +If they can share one processor, then all is good. + +Except when it isn't. Which is mostly when someone tries to talk. + +By this time computers came with many cpus. + +So if you had many threads that was just one python process and one cpu. + +Much of this code is where humans come in. Interfaces for humans. + +One cpu can keep up with a human. + +So that leaves n-1 to do the fun stuff. + +But if you have cool threads then at certain times they grab the GIL. + +The Global Interpretter Lock. + +The thread with the GIL is the one that can rock. + +If it just takes a beat then they all keep up. + +So if you are lucky terry will know where he is and what time it is. + +And if you ask with or without a flag terry may tell how you are running. + +And now for something completely the same? +""" + +import dis +import sys +import datetime + +def where(): + return "Sheffield Somewhere" + +def when(): + return datetime.datetime.now() + + +def terry(flag=None): + """ + Am I running in a co-routine? + + Credits: @dabeaz and @yarkot + """ + flag = flag or 128 + + co_flags = sys._getframe(2).f_code.co_flags + + return co_flags & flag + + +if __name__ == '__main__': + + # A sketch with Terry Gilliam the main character + print(where()) + print(when()) + print(terry()) + diff --git a/karmapi/grb.py b/karmapi/grb.py new file mode 100644 index 0000000..6b81e95 --- /dev/null +++ b/karmapi/grb.py @@ -0,0 +1,826 @@ +""" +Are gamma-ray bursts optical illusions? + +Robert S MacKay, Colin Rourke + +http://msp.warwick.ac.uk/~cpr/paradigm/GammaRayBursts.pdf + +What is it like when a galaxy emerges into view at the edge of our visible +universe? + +In what follows I am imagining a wider universe that has the similar uniform +structure. + +It appears spirals are a natural thing to arise and perhaps we just see a +window on an expanding arm of a giant spiral of galaxies. + +If we go with this, then from the perspective of the galaxy (the emitter of +light just coming into view from our world) nothing unusual is happening, it is +just cruising along, just like our galaxy. + +What paths have the light waves have taken to get to us and how +long that journey was? + +Note also the new addition to our inertial field, settling in. + +Update +====== + +The emitter itself does not need to enter our visible universe. All that is +required is a beam of light from that emitter that enters our visible universe, +and is heading in our direction. + +Colin:: + + Not quite right. All we ever see of anything is light. Sending light + to us is the same as being in our universe + +There was lots more from Colin. See docs/nodice/grb.rst for more on that +story. + +Now if a gamma-ray burst indicates a new galaxy arriving in our visible +universe, with the burst representing the, finite, but unbounded history of the +universe, including the history of its inertial drag field. + +This latter, is hypothesised to be driven by a super-massive object (~10^11 +solar masses) at the centre of the galaxy. + +Noting that this field decays linearly with distance, but extends well beyond +the visible part of the galaxy. + +When a galaxy comes into view, not just a big slice of time, but also a large +expanse of space becomes visible in a short space of time. + +I picture this as a wave, like a sunrise, sweeping across our solar system. + +We see gamma ray bursts lasting several minutes, with the frequency rising +rapidly to a sharp peak before slowly tailing off over the next several +minutes. + +It is hypothesised that the gravitational wave that is seen will broadly follow +the shape of the gamma-ray, but over a longer time span. + +It is hypothesised that large masses in our solar system will act to amplify +the signal. + +The result will be echo cancellation due to the different paths that the +gravitational wave can take. + +Echoes will bounce around the solar system as bodies follow the incoming wave +together. + +It also has to be noted that the earth too will act to echo the wave it sees. + +Consider the moon, earth and sun. It takes just 1.3 seconds for light to travel +from earth to moon or vice versa. + +From moon or earth to the sun is around 500 seconds, or 8 minutes 20 seconds. + +Place the earth at the origin and then picture the different path lenghts. + +So, + + P = location of GRB emitter + M = location of moon + S = location of sun + E = earth, location (origin) + +Lengths of interest:: + + deltaS = PSE - PE + + deltaM = PSME - PSE = SME - SE + +Now deltaM is independent of P. + +Given the location in the sky that the GRB actually comes from, we can also get +a better estimate on deltaS. + +We may also be able to work this backwards: given a signal that will place some +constraints on the geometry. + +Jupiter? other planets? + +For now the goal is given a time and a place in the sky P, draw a picture? +""" + +import math +import numpy as np +import argparse +import requests +import json +from pathlib import Path + +from datetime import datetime as dt +from datetime import timedelta + +from astropy import coordinates, constants +from astropy.time import Time + +import curio + +from matplotlib import pyplot as plt +from matplotlib import colors + +import blume +from blume import magic +from blume import farm as fm + +from karmapi import cpr + + +# Much thanks for all involved in this: +OBSERVATIONS = 'https://www.gw-openscience.org/catalog/GWTC-1-confident/json/' + +GRB_20170818_0224 = """ + +J1243.9-1135 07012051001 12 43 51.26 -11 35 06.28 Aug 18, 2017 02:22:00 Aug 28, 2017 120.341 119.873 128 Aug 29, 2017 +J1245.4-1154 07012052001 12 45 22.41 -11 54 01.4 Aug 18, 2017 02:25:00 Aug 28, 2017 123.173 122.995 130 Aug 29, 2017 +J1246.9-1213 07012053001 12 46 53.91 -12 12 34.99 Aug 18, 2017 02:27:00 Aug 28, 2017 122.849 120.104 128 +""" + +def angle(d, m, s): + + a = s + a = m + a / 60 + return d + (a / 60) + +LIGO_HLAT = angle( 46, 27, 18.52) +LIGO_HLON = angle(119, 24, 27.56) + +LIGO_LLAT = angle(30, 33, 46.42) +LIGO_LLON = angle(90, 46, 27.27) + + +class SkyMap(magic.Ball): + + def __init__(self, balls, planets, *args, **kwargs): + + super().__init__() + self.sleep = 1 + self.balls = balls + self.planets = planets + self.offset = 0 + + #self.add_event_map('r', self.reverse) + + async def reverse(self): + """ Rongo Rongo change direction """ + self.paused = False + for ball in self.balls: + ball.inc *= -1 + + async def run(self): + """ Draw the balls """ + #ball = self.balls[self.dball] + #print('current ball', ball.name, ball) + + fig = plt.figure() + + fig.clear() + + #ax = fig.add_axes((0,0,1,1), projection='mollweide') + ax = fig.add_subplot(1, 1, 1, + projection='mollweide') + + if self.planets: + ax.set_title(str(self.planets[0].t), color='white') + + locs = [self.decra2rad( + ball.body.dec.value, + ball.body.ra.value) + for ball in self.balls] + + sun = None + for planet in self.planets: + planet.tick() + if planet.name == 'sun': + sun = planet + + if sun: + self.offset = (sun.body.ra.rad - math.pi) * -1 + print("WITH SUN", self.offset / math.pi) + else: + self.offset += math.pi/10 + self.offset = 0 + + + ball_colours = [x.distance for x in self.balls] + + ax.scatter([self.spinra(xx[1]) for xx in locs], + [xx[0] for xx in locs], + c=ball_colours, + s=[x.data['major_axis'] or 1 for x in self.balls]) + + norm = colors.Normalize(min(ball_colours), max(ball_colours)) + cm = plt.get_cmap() + for ball, loc, colour in zip(self.balls, locs, ball_colours): + ma = ball.data['major_axis'] or 1 + ngn = ball.data.get('neighbor_galaxy_name', '') + #constellation = coordinates.get_constellation(ball.body) + constellation = '' + #if (ma or 1) > 20: + if 'ilky' in ngn or 'ilky' in constellation: + #if 'ilky' in ball.name: + + print() + print(constellation) + print(ball) + + ax.text( + self.spinra(loc[1]), loc[0], + '\n'.join((ball.name, constellation)), + color='red', + #color=cm(1.0-norm(colour)), + fontsize=15 * math.log(max(ma, 10)) / 10) + + + #self.planets = [] + planet_xx = [x.body.ra.radian - math.pi for x in self.planets] + planet_yy = [x.body.dec.radian for x in self.planets] + #planet_xx = [self.spinra(x) for x in planet_xx] + + planet_colors = dict( + earth='gold', + sun='brown', + mercury='silver', + venus='orange', + moon='lightblue', + mars='crimson', + jupiter='grey', + saturn='skyblue', + neptune='green', + uranus='indigo', + pluto='violet') + + pcs = [math.log(x.body.distance.au + 1) for x in self.planets] + planet_sizes = [math.log(min(p.data['m'], 1000.0) + 1) + for p in self.planets] + print(planet_sizes) + + pcs = [planet_colors[p.name] for p in self.planets] + #pcs = [planet_colors['saturn'] for p in self.planets] + #pcs = ['brick'] * len(pcs) + + + cc = ax.scatter(planet_xx, + planet_yy, + c=pcs, + s=planet_sizes, + cmap='rainbow') + + for ball, loc, colour in zip(self.planets, + zip(planet_xx, planet_yy), + pcs): + + try: + constellation = coordinates.get_constellation(ball.body) + except: + print('no constellation for', ball) + + print() + print(constellation) + print(ball) + ax.text(loc[0], loc[1], constellation + '\n' + ball.name, + color=colour, fontsize=8) + + + #plt.colorbar(cc) + ax.axis('off') + + await self.put(magic.fig2data(plt)) + + fig.clear() + + ax = fig.add_subplot(111) + rv = [xx.data.get('radial_velocity', 0.0) or 0. for xx in self.balls] + distance = [xx.data.get('distance', 0.0) or 0. for xx in self.balls] + + rrv = [] + dd = [] + for vel, dist in zip(rv, distance): + if dist > 11: + continue + + if vel == 0.0: + # use Hubble relationship + vel = dist * 70. + rrv.append(vel) + dd.append(dist) + + ax.scatter(dd, rrv) + + #await curio.sleep(self.sleep) + #await self.outgoing.put(magic.fig2data(fig)) + #await curio.sleep(self.sleep) + + #await self.outgoing.put(magic.fig2data(fig)) + fig.clear() + ax = fig.add_subplot(111) + ax.plot(distance) + #await self.outgoing.put(magic.fig2data(fig)) + + fig.clear() + ax = fig.add_subplot(111) + ax.plot([xx[1] for xx in locs]) + #await self.outgoing.put(magic.fig2data(fig)) + + + def spinra(self, ra): + + ra += self.offset + while ra > math.pi: + ra -= 2 * math.pi + + while ra < math.pi * -1: + ra += 2 * math.pi + + return ra + + def decra2rad(self, dec, ra): + + ra = (ra - 12) * math.pi / 12. + + while ra > math.pi: + ra -= 2 * math.pi + + return dec * math.pi / 180., ra + + + def latlon2xy(self, lat, lon): + """ Convert lat lon to yard coordinates """ + if lon < 0: + lon += 360. + lon += 180 + lon %= 360 + + xscale = 360.0 / self.width + yscale = 180.0 / self.height + + xx = int(lon / xscale) + yy = int((90 + lat) / yscale) + + return xx, yy + + +def gamma_hack(): + + from matplotlib import pyplot as pp + + T = 1000 + k = 10000 + + xx = [x * math.pi / k for x in range(T)] + shint = np.array([math.sinh(x) for x in xx]) + cosht = np.array([math.cosh(x) for x in xx]) + print(shint.size) + #print(xx[-100:]) + #print(yy[-100:]) + + pp.plot(list(shint), list(cosht)) + + + # emitter + shinu = shint.copy() + coshu = cosht.copy() + + alpha = 2 + beta = 1 + gamma = -1 + delta = 1 + e0 = (alpha * shinu) + (beta * coshu) + e1 = (gamma * shinu) + (delta * coshu) + + # 2.2 + + geo_test = - (e0 * shint) + (e1 * cosht) + + pp.plot(geo_test) + + pp.show() + + + # TODO plot t against u: receiver and emitter times respectively + + +def argument_parser(parser=None): + + parser = parser or argparse.ArgumentParser() + + parser.add_argument('--lat', type=float, default=LIGO_HLAT) + + parser.add_argument('--lon', type=float, default=LIGO_HLON) + + #parser.add_argument('--date', default='2015/09/14/09/50/45') + #parser.add_argument('--date', default='2017/08/14') + parser.add_argument('--date') + + #parser.add_argument('--grb', default='170817A') + parser.add_argument('--grb', + help="fixme get gamma ray burst data") + parser.add_argument('--gw', help="file for latest ligo data") + parser.add_argument('--galaxy', help="file of local galaxy data") + + return parser + + +def get_body(body, t=None): + + t = t or dt.now() + + return coordinates.get_body(body, Time(t)) + + +def get_mass(body): + + # masses (10^24 Kg) + em = 5.97 + + to_earth = 1.0 / em + + masses = dict( + moon = 0.073 * to_earth, + mercury = 0.330 * to_earth, + venus = 4.87 * to_earth, + mars = 0.64 * to_earth, + earth = 1.0, + jupiter = 1898 * to_earth, + saturn = 568.0 * to_earth, + uranus = 86.8 * to_earth, + neptune = 102.0 * to_earth, + pluto = 0.0146 * to_earth) + + sun = masses['jupiter'] * (constants.GM_sun / constants.GM_jup) + masses['sun'] = sun + + return masses.get(body, 1.) + + +BODIES = [ + 'sun', 'moon', + 'mercury', 'venus', + 'earth', + 'mars', 'jupiter', 'saturn', + 'neptune', 'uranus'] +#BODIES = coordinates.solar_system_ephemeris.bodies + +RADIUS_OF_EARTH = 6378. +RADIUS_OF_SUN = 1.391e6 + +def au2earth(value=1): + """ Convert astronomical units to earth radii """ + + # earth to sun + e2s = float(constants.c.to('km/s').value) * 499.0 + #print(e2s) + return value * e2s / 6378 + + +def display_body(name, t): + + print("Time of event:", t) + print("Viewing from:", name) + target = get_body(name, t) + results = {} + for body in BODIES: + print(body) + + bd = body_data(body, t) + + mass = bd['m'] + bod = bd['body'] + + if body == name: + if name in ['earth', 'sun']: + r = bd['r'] + else: + r = target.separation_3d(bod) + + print(bod) + print('mass:', mass) + print(f'distance to {name}: {r}') + print('m over r:', mass / r) + print() + print() + + return results + +def get_distance(): + pass + +def body_data(name, t): + + bod = get_body(name, t) + mass = get_mass(name) + + radius = None + if name == 'earth': + radius = 6378 / 1.5e8 + elif name == 'sun': + radius = 1.391e6 / au2earth(1) + + return dict( + r=radius, + m=mass, + name=name, + body=bod) + + +class Body(magic.Ball): + + + def __init__(self, name, t, size=None): + """ Initialise the body """ + + super().__init__() + + self.name = name + self.t = t + + self.inc = 3600 * 6 # 6 hours + self.inc = 3600 * 24 * 28 # 1 month + self.inc = 3600 * 24 * 7 # 1 week + + self.set_body() + + def set_body(self): + + bd = body_data(self.name, self.t) + self.body = bd['body'] + self.data = bd + + def tick(self): + + self.t += timedelta(seconds=self.inc) + return self.set_body() + + async def run(self): + + self.tick() + + def separation(self, body): + """ Return distance to body """ + return self.body.separation_3d(body) + + +def args_to_spheres(args, t): + + spheres = [] + for body in BODIES: + bod = Body(body, t=t) + bod.distance = 0 + spheres.append(bod) + + grb = {} + grb['170817A'] = (176.8, -39.8) # RA DEC + + if args.grb in grb: + ra, dec = grb.get(args.grb) + + gbod = Body('sun', t=t) + gbod.body = coordinates.SkyCoord(ra, dec, unit='deg') + gbod.distance = 0.0 + gbod.name = args.grb + spheres.append(gbod) + + return spheres + +def dump(spheres): + + for a in spheres: + + for b in spheres: + if a is b: continue + xx = b.body + yy = xx.transform_to(a.body) + print(f'{a.name} {b.name} {xx.ra.value - yy.ra.value} {xx.dec.value - yy.dec.value}') + print(f'zzzzzzz {a.name} {b.name} {yy.ra.value} {yy.dec.value}') + print + +def sun(t=None): + + return get_body('sun', t) + +def moon(t=None): + + return get_body('moon', t) + +def earth(t=None): + + return get_body('earth', t) + +def jupiter(t=None): + + return get_body('jupiter', t) + + +def get_waves(path=None): + + if path.exists(): + with path.open() as infile: + return json.load(infile) + + resp = requests.get(OBSERVATIONS) + + data = json.loads(resp.content.decode('utf-8')) + print(type(data)) + + if path is not None: + with path.open('w') as outfile: + json.dump(data, outfile, indent=True) + + return data + + +def parse_date(date): + """ Parse a date """ + if date is None: + return dt.now() + + fields = [int(x.strip()) for x in date.split('/')] + + + while len(fields) < 3: + fields.append(1) + + while len(fields) < 6: + fields.append(0) + + year, month, day, hour, minute, second = fields + + return dt(year, month, day, hour, minute, second) + + +class Bod(object): + + def __init__(self, ra, dec): + self.body = coordinates.SkyCoord(ra, dec, unit='deg') + +async def run(args): + + + print(args.date) + args.date = parse_date(args.date) + + t = args.date + + earth = display_body('earth', t) + sun = display_body('sun', t) + + + for k,v in earth.items(): + print(f'{k}: {v["moverr"]}') + + + + # pass list of balls into NestedWaves + planets = args_to_spheres(args, t) + + print("GOT solar system", len(planets)) + + spheres = [] + if args.galaxy: + gals = list(near_galaxies(open(args.galaxy))) + + gals = [cleanse(gal) for gal in gals] + + print('clean galaxy data') + print(gals[0]) + + + + for gal in gals: + #gbod = Body('sun', t=t) + ra = gal['ra'] + dec = gal['dec'] + gbod = Bod(ra, dec) + gbod.distance = gal['distance'] + gbod.data = gal + #gbod.body = coordinates.SkyCoord(ra, dec, unit='deg') + #if 'neighbor_galaxy_name' in gal: + # gbod. + + gbod.name = gal['name'] + + + spheres.append(gbod) + + print("GOT spheres", len(spheres)) + + farm = fm.Farm() + + ss = SkyMap(balls=spheres, planets=planets, fade=args.fade, + twist=args.twist) + farm.add_node(ss, background=True) + farm.add_edge(ss, farm.carpet) + farm.add_edge(fm.GuidoClock(), farm.carpet) + #spheres = cpr.args_to_spheres(args) + #farm.add(cpr.NestedWaves, dict( + # balls=spheres, fade=args.fade, + # twist=args.twist)) + + #farm.setup() + starter = await curio.spawn(farm.start()) + + print('farm runnnnnnnnnning') + runner = await farm.run() + + +def gravity_waves(path): + """ Read or download gravity wave observations """ + waves = get_waves(path) + + data = waves['data'] + + print(json.dumps(waves['parameters'], indent=True)) + + rows = [] + for name, fields in data.items(): + print() + print(name) + row = dict(name=name) + + #fields['name'] = name + + for k, v in fields.items(): + print(k, v['best']) + + + for k, v in fields.items(): + row[k] = v.setdefault('best') + print(f"{v['best']}", end=', ') + print() + + rows.append(row) + + return rows + +def tokens(line, sep=','): + """ Split line into tokens """ + return [x.strip() for x in line.split(sep)] + +def near_galaxies(infile): + """ parse galaxy.txt from + + https://heasarc.gsfc.nasa.gov/w3browse/all/neargalcat.html + + """ + header = tokens(infile.readline()) + print(header) + for row in infile: + fields = tokens(row) + yield dict(zip(header, fields)) + + +def parse_radec(value): + + d, m, s = [float(s) for s in value.split()] + + scale = 1 + if d < 0: + d *= -1 + scale = -1 + + d += m / 60. + d += s / 3600. + + return d * scale + +def cleanse(data): + + clean = {} + + for key, value in data.items(): + + try: + value = float(value) + except: + pass + + if key in ('ra', 'dec'): + value = parse_radec(value) + + clean[key] = value + + return clean + +if __name__ == '__main__': + + + parser = argument_parser(cpr.argument_parser()) + + args = parser.parse_args() + + + + if args.gw: + rows = gravity_waves(Path(args.gw)) + + import pandas + + df = pandas.DataFrame(rows) + print(df.describe()) + else: + + curio.run(run(args)) + diff --git a/karmapi/hat.py b/karmapi/hat.py new file mode 100644 index 0000000..3a89c63 --- /dev/null +++ b/karmapi/hat.py @@ -0,0 +1,67 @@ + +import random +import datetime +import sense_hat +import time + +class HatInfo: + + def __init__(self): + + self.hat = sense_hat.SenseHat() + self.stick = sense_hat.SenseStick() + + self.hat.rotation = 90 + + self.colour = (170, 80, 80) + + self.stats = True + + def whattimeisit(self): + + return f'{datetime.datetime.now():%H:%M}' + + def run(self): + + h = self.hat + while True: + + if self.stats: + + messages = [ + f'T: {h.temp:0.1f}', + f'P: {h.pressure:0.1f}', + f'H: {h.humidity:0.1f}', + f'TT: {self.whattimeisit()}'] + + colours = [ + [255, 255, 0], + [255, 0, 255], + [0, 255, 255], + [255, 255, 255], + ] + + + for message, colour in zip(messages, colours): + + h.show_message(message, text_colour=colour, + scroll_speed=0.2) + + pixels = [random_colour()] * 32 + [random_colour()] * 32 + #pixels = pixels * 8 + h.set_pixels(pixels) + time.sleep(2) + continue + + +def random_colour(): + + ri = random.randint + + return [ri(0, 256), ri(0, 256), ri(0,256)] + +if __name__ == '__main__': + + h = HatInfo() + + h.run() diff --git a/karmapi/hju.py b/karmapi/hju.py new file mode 100644 index 0000000..9fca163 --- /dev/null +++ b/karmapi/hju.py @@ -0,0 +1,298 @@ +""" I + git + +tank rain for git browsing + +""" + +import itertools +import argparse + +import datetime +utcnow = datetime.datetime.utcnow + +import requests +from pathlib import Path + +from collections import defaultdict + +import curio + +from karmapi import show, base + +from karmapi import pigfarm, checksum + +# Paths to data +url = '.' + +target = None + + +class TankRain(pigfarm.MagicCarpet): + """ Widget to show tankrain images """ + + def __init__(self, parent, path=None, version='local', date=None, *args): + + self.version = version + self.path = path or '~/karmapi/tankrain' + self.timewarp = 0 + self.date = date + if self.date is None: + self.date = utcnow() + + self.load_images() + + super().__init__(parent, axes=[111]) + + self.add_event_map('r', self.reverse) + self.add_event_map(' ', self.next_view) + + self.add_event_map('b', self.previous_day) + self.add_event_map('v', self.next_day) + + def load_images(self): + + self.paths = [x for x in self.get_images()] + self.ix = 0 + self.inc = 1 + + def compute_data(self): + + from PIL import Image + + ix = self.ix + + if ix < len(self.paths): + im = Image.open(self.paths[ix]) + else: + # FIXME -- create an image that shows there is no data + # for now, lets just show a rainbow + rainbow = [x for x in range(100)] + im = [rainbow] * 100 + + ix = ix + self.inc + if ix == len(self.paths): + ix = 0 + if ix < 0: + ix = len(self.paths) - 1 + + self.ix = ix + + self.data = im + + def get_images(self): + + # FIXME -- create key bindings to select time + date = self.date + datetime.timedelta(seconds=self.timewarp) + path = Path(f'{self.path}/{date.year}/{date.month}/{date.day}/').expanduser() + + print(f'loading images for path: {path} v{self.version}v') + + jpegs = path.glob('{}*.[jp][np]g'.format(self.version)) + gifs = path.glob('{}*.gif'.format(self.version)) + + for image in sorted(itertools.chain(jpegs, gifs)): + + if image.stat().st_size == 0: + continue + print(image) + yield image + + + async def next_view(self): + + switch = dict( + wide='local', + local='parish', + parish='wide') + + # no versions, don't switch + switch[''] = '' + + self.version = switch[self.version] + + self.load_images() + + async def previous_day(self): + + self.timewarp -= 24 * 3600 + + self.load_images() + + async def next_day(self): + + self.timewarp += 24 * 3600 + self.load_images() + + async def reverse(self): + + self.inc *= -1 + + async def start(self): + """ FIXME: get yoser to run fetch """ + #farm.yosser.run(fetch, minutes=20, sleep=300) + pass + + async def run(self): + + # use yosser? + await pigfarm.aside(runfetch) + + self.dark() + while True: + + #title = self.paths[self.ix] + if self.paths: + title = self.paths[self.ix] + else: + title = f'{self.ix} : {len(self.paths)} {self.path}' + + self.compute_data() + self.axes.clear() + print('TITLE:', title) + try: + self.axes.set_title(title) + self.axes.imshow(self.data) + except OSError: + print('dodgy image:', self.paths[self.ix]) + + + self.draw() + + await curio.sleep(self.sleep) + + + +async def fetch_part(name, data, minutes=30, timewarp=None, bad=None): + + timewarp = datetime.timedelta() + + #FIXME adjust for timewarp + bad = bad or set() + + timestamp = utcnow() + + timestamp += timewarp + + aminute = datetime.timedelta(minutes=1) + + # make timestamp an even minute + # if timestamp.minute % 2: + # timestamp -= aminute + + end = timestamp - (minutes * aminute) + checks = set() + + while timestamp > end: + timestamp -= aminute + + path = Path(target.format( + date=timestamp, + suffix='.png', + name=name)) + + path = Path('~/karmapi').expanduser() / path + + if path.exists(): + print('already got', timestamp, name) + continue + + if str(path) in bad: + print('skipping bad', timestamp, name) + continue + + # FIXME get a timewarp from the target. Parish is on GMT + #if parish: + # timewarp += parish_timewarp + + print('looking for', timestamp, name) + # need to fetch it + iurl = data['url'].format( + date=timestamp, + size=data['size']) + + + # fixme -- await an async http call + image = requests.get(iurl) + + if image.status_code == requests.codes.ALL_OK: + # Save the imabe + # checksum the data + check = hash(image.content) + if check in checks: + print('dupe', timestamp, name) + else: + print('GOT', timestamp, name) + path.parent.mkdir(exist_ok=True, parents=True) + path.open('wb').write(image.content) + else: + bad.add(str(path)) + print('bad', path, len(bad)) + + + print() + +async def runfetch(): + + await fetch() + + +async def fetch(minutes=30, sleep=300): + """ Download images """ + iurls = dict( + local = dict(url=url + radar_template, + size=100), + wide = dict(url=url + radar_template, + size=250), + parish = dict(url=url + parish_template, + size=0), + ) + + + while True: + bad = set() + for name, data in iurls.items(): + + await fetch_part(name, data, minutes, bad) + + # FIXME -- shrink bad from time to time + + await curio.sleep(300) + + +def main(args=None): + """ Retrieve images currently available + + There are usually six images available from the last half hour. + """ + + parser = argparse.ArgumentParser() + + parser.add_argument('--pig', action='store_false', default=True) + parser.add_argument('--minutes', type=int, default=30) + parser.add_argument('path', nargs='?', default='~/karmapi/tankrain') + parser.add_argument('--version', default='') + parser.add_argument('--date') + + args = parser.parse_args() + + args.date = base.parse_date(args.date) + + if args.pig: + farm = pigfarm.PigFarm() + farm.add( + TankRain, + dict(path=args.path, version=args.version, date=args.date)) + + from karmapi.mclock2 import GuidoClock + farm.add(GuidoClock) + + pigfarm.run(farm) + sys.exit() + else: + curio.run(fetch(args.minutes)) + +if __name__ == '__main__': + # Radar + + main() + diff --git a/karmapi/hush.py b/karmapi/hush.py index 91f4725..00e7c26 100644 --- a/karmapi/hush.py +++ b/karmapi/hush.py @@ -21,6 +21,58 @@ https://github.com/tyiannak/pyAudioAnalysis + + +Update: back after a long absense. + + +OK. So I have some .wav files I want to process and use with the rest of the +karma that is here. + +But there are a lot of pieces to juggle around here. + +I want to use the tpot. + +Here's the idea. + +Take a poor quality recording of me playing the guitar and turn it into +something Carlos Santana might do while he's tying shoe laces. + +So I'm more Carlisle Sultana than Carlos, so this might take a while. + +Less ambitious goal? Beware if it sounds easy ... remember the black hole of +code. Did I mention the black hole is actually made of spaghetti code? + +All the failed *next generation* projects for the last generation, this is just +one of the holes out there. + +The cool thing is that due to modern version control a code base can easily +belong to multiple black holes simultaneously. + +Of course a lot of this stuff is actually out there in the wild, but that is a +whole other problem. + +Did I mention I digress? + +So the other goal is to be able to control tankrain with a guitar. + +And the teapot might just help with that. Guess the state, bind the state to +actions for tankrain. + +Oh and update. Laptop has a mic, so can do the recording with hush. + +And now I am having dega code + +its deja vu for you know you have an idea you want to pursue and remember +solving the problem before (the problem in this case being reading and writing +files). + +But the problem here is files with a special sound format. And then of course +you realise this is the place where you did it last time. + +Time to see if any of it still works. + +karma currie time to be exact. """ from datetime import datetime import math @@ -35,8 +87,12 @@ from matplotlib import pyplot +try: + import pyaudio + FORMAT = pyaudio.paInt16 +except: + FORMAT = None -import pyaudio import wave import numpy as np @@ -44,7 +100,6 @@ CHUNK = 1024 * 4 #CHUNK = 256 * 1 -FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORD_SECONDS = 5 diff --git a/karmapi/kiss.py b/karmapi/kiss.py new file mode 100644 index 0000000..6178299 --- /dev/null +++ b/karmapi/kiss.py @@ -0,0 +1,98 @@ +""" +Kiss goodbye to data + +hello, just the same + +exceptions and all sorts of complications + +keep it simple + +share +""" +import argparse + +from karmapi import checksum + +from pathlib import Path + +from curio import run, tcp_server, open_connection + +PORT = 8008 + +async def goodbye(data, **meta): + """ kiss good-bye to data """ + + ck = checksum.checksum(data) + + # check meta data etc -- see checksum module + + path = meta.getdefault('path', Path('.')) + + # any matches? Somebody else's problem? + # run delta for each match? + + # save a copy? + if not path.exists(): + save(data, path) + + # vision test? Looks the same? How to? + + # 2018 aeh eye + + # catch exceptions? + + +hello = goodbye + +async def echo_client(client, addr): + print('Connection from', addr) + s = client.as_stream() + async for line in s: + print(line) + await s.write(line) + print('Connection closed') + await s.close() + + +async def client(host, port): + sock = await open_connection( + host, port) + async with sock: + await sock.sendall(b'kiss\r\nWOW HERE I AM\r\n\r\n') + chunks = [] + while True: + chunk = await sock.recv(10000) + if not chunk: + break + chunks.append(chunk) + + response = b''.join(chunks) + print(response.decode('latin-1')) + + + +def get_parser(): + + parser = argparse.ArgumentParser() + parser.add_argument('--host', default='localhost') + parser.add_argument('--port', type=int, default=PORT) + parser.add_argument('--serve', action='store_true') + + return parser + + +if __name__ == '__main__': + + parser = get_parser() + + args = parser.parse_args() + + if args.serve: + try: + run(tcp_server, args.host, args.port, echo_client) + except KeyboardInterrupt: + pass + + else: + # client mode + run(client, args.host, args.port) diff --git a/karmapi/maps.py b/karmapi/maps.py index 91336bf..d38b1df 100644 --- a/karmapi/maps.py +++ b/karmapi/maps.py @@ -125,7 +125,7 @@ def plot_points_on_map(lats, lons, xlons.append(lon) x, y = m(xlons, lats) - #m.drawcoastlines() + m.drawcoastlines() m.drawmapboundary() m.drawlsmask(alpha=1.) diff --git a/karmapi/mayqueen.py b/karmapi/mayqueen.py new file mode 100644 index 0000000..c5ce8f5 --- /dev/null +++ b/karmapi/mayqueen.py @@ -0,0 +1,20 @@ +""" +Shine some zodiacal light on spherical data + + +""" + +from karmapi import cpr, tpot + +class MayQueen(cpr.Sphere): + + + async def run(self): + """ Run surrounding spheres through tea pots + + """ + pass + + + + diff --git a/karmapi/mj.py b/karmapi/mj.py new file mode 100644 index 0000000..297b7da --- /dev/null +++ b/karmapi/mj.py @@ -0,0 +1,103 @@ +""" +Simple substitution + +The Babington Plot according to wiki pedya:: + + https://en.wikipedia.org/wiki/Babington_Plot + +Simon Singh has a book on the history of crytography. + +Will see if I can find one. + +My Queen Mary went with as simple substitution + some magic codes. + +But I'm not sure the magic works, even in python. It's a human thing. + +So, here's a simple sub with a twist for now. + +""" + +def key_to_alpha(key): + """ Generate alphabet for key + + Idea is run through the key, dropping any + letters already seen. + + Then go back to the beginning of the alphabet and + write letters out that are not in the key. + """ + alphabet = '' + used = set() + + for c in key: + if c.lower() not in used: + alphabet += c + used.add(c) + + a = ord('a') + + for xx in range(26): + c = chr(a + xx) + if c not in used: + alphabet += c + + return alphabet + +def gen_cipher_lookup(alpha, didigs=None): + + didigs = didigs or [1, 2] + + available = [x for x in range(10) if x not in didigs] + print(available) + + calpha = [str(x) for x in available] + for digit in didigs: + for x in available: + calpha.append(str((10 * digit) + x)) + + lookup = {} + for p, c in zip(alpha, calpha): + lookup[p] = c + + return lookup + + +def encode(message, cipher): + + result = '' + for c in message: + code = cipher.get(c, c) + result += code + + return result + + +import argparse +import sys + + +parser = argparse.ArgumentParser() + +parser.add_argument('--key', default='iloveyou') +parser.add_argument('--mj', action='store_true') +parser.add_argument('--cheat', action='store_true') + +args = parser.parse_args() + + +message = sys.stdin.read() + +alpha = key_to_alpha(args.key) + +cipher = gen_cipher_lookup(alpha) + +if args.mj: + print("Not yet implemented :(") + sys.exit(26) + +if args.cheat: + for p, c in cipher.items(): + print(p, c) + +print(encode(message, cipher)) + diff --git a/karmapi/moon.py b/karmapi/moon.py new file mode 100644 index 0000000..a5750c1 --- /dev/null +++ b/karmapi/moon.py @@ -0,0 +1,258 @@ +""" +Moon or moai + +Electromagnetic balls of wonder dancing together. + +Ahu bus stops + +and the number 7 bus. + +May Day Parade + +Winter Solstice + +Spring Tide Mays + +And October blaze. + + +So far now, simulate moai. + +And orongo. + + +""" +from pathlib import Path +from matplotlib import pyplot as plt + +from blume import magic, farm + +import datetime + +import netCDF4 + +def puzzle(): + """ No idea what this is about + + New moons? + """ + NEW = datetime.datetime(1900, 1, 1, 5, 50) + + NEXTNEW = datetime.datetime(1900, 1, 30, 5, 22) + + + delta = (NEXTNEW - NEW) + + deltas = delta.days * 24 * 3600 + + print(delta.days) + + deltas += delta.seconds + + print(deltas) + + + latest = datetime.datetime(2017, 11, 18, 3, 43) + + ldelta = latest - NEW + + + seconds = ldelta.days * 24 * 3600 + seconds += ldelta.seconds + + print(seconds, seconds / deltas) + + current = NEW + for x in range(100): + print(current) + + current += delta + +from collections import deque +from math import pi + +class queue(deque): + + def __init__(self): + + super().__init__(self) + + self.value = 0.0 + + def value(self): + + return self.value + + def tick(self): + + self.value /= pi + +class stop: + """ Or Ahu, a bus depot """ + + def __init__(self, x=None, y=None): + + self.queue = queue() + + self.x = x + self.y = y + + async def echo(self, depot=None): + + value = 0.0 + for item in depot: + value += depot.value() + + self.value += value / 2 + return self.value + + def add(self, moai): + + # fixme push according to direction of travel + self.queue.push(moai) + +def data_to_rows(data): + + # figure out what we have + import csv + for row in csv.reader(data): + keys = [x.strip() for x in row] + break + + for row in csv.DictReader(data[1:], keys): + yield row + + + +class RongoRongo(magic.Ball): + + async def start(self): + + print('Rapa Nui') + self.dem = netCDF4.Dataset(self.dem) + + # this should just be: self.moai = magic.Spell(open(self.moai)) + # just need an init method for spell + records = list(data_to_rows(open(self.moai).readlines())) + spell = magic.Spell() + spell.find_casts(records) + self.moai = list(spell.spell(records)) + + self.extent = ( + self.dem.geospatial_lon_min, self.dem.geospatial_lon_max, + self.dem.geospatial_lat_min, self.dem.geospatial_lat_max) + + print(self.dem) + print(self.extent) + + + def zoomit(self, data): + + if self.zoom <= 1.: + return data, self.extent + + width, height = data.shape + ww = int(width // self.zoom) + hh = int(height // self.zoom) + + xoff, yoff = self.xoff, self.yoff + + wstart = int((xoff + width - ww) // 2) + hstart = int((yoff + height - hh) // 2) + lats, lons = self.dem['lat'], self.dem['lon'] + + extent = (lons[hstart], lons[hstart + hh-1], + lats[wstart], lats[wstart + ww-1]) + extent = [float(x) for x in extent] + + return data[wstart:wstart+ww, hstart:hstart+hh], extent + + async def run(self): + + data = self.dem['Band1'] + + zdata, extent = self.zoomit(data) + zdata = zdata[::-1] + + plt.imshow( + zdata, extent=extent, vmin=self.vmin, vmax=self.vmax, + interpolation=self.interpolation[0], + cmap=magic.random_colour()) + + #plt.imshow(data, extent=extent) + plt.colorbar() + + moai = select_moai(self.moai, extent) + lats = [x['lat'] for x in moai] + lons = [x['lon'] for x in moai] + plt.scatter(lons, lats, s=.1, c='r') + + #plt.scatter([ahu.x for ahu in self.ahu.values()], + # [ahu.y for ahu in self.ahu.values()], + # s=1, c='r') + + await self.put() + +def select_moai(moai, extent): + + minlon, maxlon, minlat, maxlat = extent + + result = [] + for mo in moai: + lat, lon = mo['lat'], mo['lon'] + + if minlon <= lon and lon <= maxlon and minlat <= lat and lat <= maxlat: + result.append(mo) + return result + + +if __name__ == '__main__': + + import argparse + from pathlib import Path + + parser = argparse.ArgumentParser() + + AHU = dict( + orongo = stop(y=-27.1874, x=-109.4431), + ranoraraku = stop(y=-27.1220, x=-109.2889), + rrq = stop(y=-27.1263, x=-109.2885), + tongariki = stop(y=-27.1258, x=-109.2769), + akivii = stop(y=-27.1150, x=-109.3950), + hanavarevare = stop(y=-27.1167, x=-109.4167), + tepeu = stop(y=-27.1024, x=-109.4163), + + xx1 = stop(y=-27.0950, x=-109.4108), + xx2 = stop(y=-27.1236, x=-109.4215), + xx3 = stop(y=-27.0933, x=-109.4098), + xx4 = stop(y=-27.0887, x=-109.4074), + xx5 = stop(y=-27.0703, x=-109.3987), + ) + + ORIGIN=AHU['orongo'] + + parser.add_argument('-moai', default='moai.csv') + parser.add_argument('-vmin', type=float, default=-4000) + parser.add_argument('-vmax', type=float, default=500) + parser.add_argument('-xoff', type=float, default=0.0) + parser.add_argument('-yoff', type=float, default=0.0) + parser.add_argument('-zoom', type=float, default=2.0) + parser.add_argument('-dem', default='easter_island_3_isl_2016.nc') + + args = parser.parse_args() + + magic.modes.rotate() + animal = farm.Farm() + + rongo = RongoRongo() + rongo.update(args) + rongo.ahu = AHU + rongo.interpolation = deque([ + None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16', + 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', + 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']) + + animal.add(rongo) + animal.shep.path.append(rongo) + + farm.run(animal) diff --git a/karmapi/ncdf.py b/karmapi/ncdf.py index 0dac2bd..965def2 100644 --- a/karmapi/ncdf.py +++ b/karmapi/ncdf.py @@ -1,9 +1,408 @@ """ -Interface to netcdf files +View netcdf files of global data + +Fit models + +Simulate future + +n c d f + +natural circular data field? + +OK time for an update. + +I discovered *pyshtools* in my explorations. + +Spherical harmonic analysis. Fourier transforms for spheres. + +Explore global harmonics. + +But first I need to unravel what is here. """ +import datetime +import math +import argparse +from pathlib import Path + +from random import randint + +from karmapi import base, tpot, cpr, pigfarm import netCDF4 +import numpy as np + +import curio + +import pyshtools + +from matplotlib import pyplot +from matplotlib.pyplot import show, imshow, title, colorbar + def load(path): - return netCDF4.DataSet(path) + return netCDF4.Dataset(path) + + +def current_epoch(): + + return datetime.datetime(1900, 1, 1) + +def stamp_filter(stamps, start, epoch=None): + + for date in stamps_to_datetime(stamps, epoch): + + if date >= datetime.datetime(start.year, start.month, start.day): + yield stamp + +def stamps_to_datetime(stamps, epoch=None): + + epoch = epoch or current_epoch() + + for stamp in stamps: + yield epoch + datetime.timedelta(hours=int(stamp)) + + +def stamp_sort(stamps): + """ FIXME: use this to go through images in order """ + ss = sorted(zip(stamps, + stamps_to_datetime(stamps), + range(len(stamps)))) + + return ss + +class WorldView(cpr.Sphere): + + def __init__(self, stamps, values, **kwargs): + + self.stamps = stamps + self.values = values + self.save = False + self.size = self.values[0].shape + #self.size = self.size[1], self.size[0] + print('SIZE', self.size) + self.min = self.values[0].min() + self.max = self.values[0].max() + self.ix = 0 + self.n = len(self.stamps) + self.spin = 5 + + self.sample_points() + + super().__init__(self.size, **kwargs) + + # data is some sort of ncdf thing + # set it up so run can just cycle through the + # frames in order. + + # take 3 at a time for r g b + + def sample_points(self): + + h, w = self.size + + self.points = [] + for pt in range(100): + x, y = randint(0, h-1), randint(0, w-1) + + self.points.append((x, y)) + + + def __getstate__(self): + """ Don't try and save stamps or values """ + state = self.__dict__.copy() + state.update(dict(stamps=None, values=None)) + return state + + def show_date(self): + + print(self.current_date()) + + def tick(self): + + self.t += 1 + + if self.save: + im = self.project() + im.save(f'{self.save}/{now}.png') + + return self + + + def post_tick(self): + """ stuff that has to happen on this processor """ + self.next_frame() + + + def current(self): + + s, d, ix = self.stamps[self.ix] + + data = self.values[ix] + + return data + + def current_date(self): + """ Get date for current stamp """ + s, d, ix = self.stamps[self.ix] + + return d + + def next_frame(self): + + red = self.current() + print(f'RED SHAPE {red.shape}') + red = to_sha(red[1:]) + print(f'RED SHAPE {red.shape}') + red = red.flatten() + print(f'RED SHAPE {red.shape}') + + red = np.concatenate((red[self.spin:], red[0:self.spin])) + + self.forward() + green = self.current() + green = to_sha(green[1:]) + green = green.flatten() + green = np.concatenate((green[self.spin:], green[0:self.spin])) + + self.forward() + blue = self.current() + blue = to_sha(blue[1:]) + blue = blue.flatten() + blue = np.concatenate((blue[self.spin:], blue[0:self.spin])) + + self.rgb = np.array(list(zip(red, + green, + blue))) + + self.spin += 5 + self.spin %= self.size[0] + + #print(red[0][50]) + #print(red[1][50]) + + height, width = self.size + self.rgb.resize((height-1, width, 3)) + + #self.sample_current() + + self.forward() + + # fix me + #for skip in range((9 * 11) + 18): + # self.forward() + + + def sample_current(self): + """ Take a sample of current data + + Add it to history. + """ + if self.ix in self.history: + print('size of history', len(history)) + 1/0 + return + + rgb = [] + for xx, yy in self.points: + value = self.rgb[xx, yy] + rgb.append(value) + + self.history[self.ix] = rgb + + + def forward(self): + """ Step to next frame """ + self.ix += 1 + + self.ix = self.ix % self.n + + def backward(self): + + self.ix -= 1 + + if self.ix == -1: + self.ix += self.n + + def scale(self, data): + + #return [randunit() for x in data] + + delta = self.max - self.min + data = [(x - self.min) / delta for x in data.flatten()] + + # map to [-1, 1] interval + data = [max(min((2 * x) - 1.0, 1.0), 0.0) for x in data] + + return data + + +def to_sha(data): + + from pyshtools.expand import SHExpandDH + + #print(data.shape) + return SHExpandDH(data, sampling=2) + + +class World(cpr.NestedWaves): + + def __init__(self, parent, stamps=None, values=None, + balls=None, + save=None, **kwargs): + + self.stamps = list(stamps) + self.values = values + self.save = save + self.spin = 1 + + + sphere = WorldView(self.stamps, self.values) + sphere.M = 1 + sphere.r = 0 + balls[0] = sphere + + sphere = WorldView(self.stamps, self.values) + sphere.M = balls[-1].M + sphere.r = balls[-1].r + balls[-1] = sphere + + #self.add_event_map('w', self.more_spin) + #self.add_event_map('w', self.less_spin) + + super().__init__(parent, balls=balls, **kwargs) + + +class CircularField: + + def __init__(self, path='.', raw='temperature.nc', value='t2m', **kwargs): + """ Load the file """ + + print(path) + print(raw) + print(value) + path = Path.home() / Path(path) + + self.df = load(path / raw) + + stamps = self.df.variables['time'] + self.values = self.df.variables[value] + + print(self.df.variables.keys()) + + self.stamps = stamp_sort(stamps) + + print("number of observations:", len(stamps)) + + # totals across years + self.totals = {} + + + def filter_stamps(self, hour=None, day=None): + + good = [] + for stamp in self.stamps: + s, d, ix = stamp + if hour is not None: + if d.hour != hour: + continue + if day is not None: + if d.day != day: + continue + good.append(stamp) + + self.stamps = good + + def generate_data(self, epoch=None): + """ spin through frames in stamp order """ + epoch = epoch or current_epoch() + + for ix, stamp in enumerate(self.stamps): + ss, date, nix = stamp + yield date, self.values[nix] + + + def sum_years(self): + """ Build totals across years """ + counts = {} + for date, value in self.generate_data(): + key = (date.month, date.day, date.hour) + + if key in self.totals: + self.totals[key] += value + counts[key] += 1 + else: + self.totals[key] = value + counts[key] = 1 + + for key in self.totals.keys(): + self.totals[key] /= counts[key] + + def deviation(self, date, value): + """ Return defiation from monthly mean """ + key = (date.month, date.day, date.hour) + return value - self.totals[key] + + +def argument_parser(parser=None): + + parser = cpr.argument_parser(parser) + parser.add_argument('--path', default='karmapi/ecmwf') + parser.add_argument('--value', default='t2m') + parser.add_argument('--raw', default='temperature.nc') + parser.add_argument( + '--pc', action='store_true', + help='do principal components') + + parser.add_argument('--delta', action='store_true') + parser.add_argument('--model', action='store_true') + parser.add_argument('--offset', type=int, default=0) + parser.add_argument('--save') + + return parser + +if __name__ == '__main__': + + + parser = argument_parser() + + args = parser.parse_args() + + + if args.pc: + pca = pcs(stamps, values, 48*35) + + pca.show_fracs(0.1) + + for x in dir(pca): + print(x) + + elif args.delta: + delta(stamps, values) + + elif args.model: + + model(stamps, values) + + else: + #path = path / args.value + #images(path, stamps, values) + pass + + cf = CircularField(args) + + print('min max:') + print(cf.values[0].min(), cf.values[0].max()) + + spheres = cpr.args_to_spheres(args) + + print(f'Number of spheres {len(spheres)}') + parms = dict(stamps=cf.stamps, values=cf.values, save=args.save, + balls=spheres) + + farm = pigfarm.sty(World, parms) + + curio.run(farm.run(), with_monitor=True) + + + diff --git a/karmapi/nhc.py b/karmapi/nhc.py index 5b429fd..8ad964e 100644 --- a/karmapi/nhc.py +++ b/karmapi/nhc.py @@ -1,11 +1,15 @@ """ -ENSO +ENSO and HURDAT http://www.esrl.noaa.gov/psd/enso/mei/#content """ HURDAT = 'http://www.nhc.noaa.gov/data/hurdat/hurdat2-1851-2015-070616.txt' +HURDAT = 'https://www.nhc.noaa.gov/data/hurdat/hurdat2-1851-2017-050118.txt' + + + import csv import datetime diff --git a/karmapi/oo2ueh.py b/karmapi/oo2ueh.py new file mode 100644 index 0000000..11a028d --- /dev/null +++ b/karmapi/oo2ueh.py @@ -0,0 +1,65 @@ +""" +Explorations in Ottawa weather data + +Data thanks to environment Canada + +http://climate.weather.gc.ca/radar/index_e.html + +""" +import requests + +URL = "http://climate.weather.gc.ca/radar/index_e.html" + +URL = "http://climate.weather.gc.ca/radar/image_e.html?time=07-OCT-18+01.06.42.405345+PM\&site=XFT" + +PARMS = dict( + site='XFT', + year=2018, + month=10, + day=7, + hour=12, + minute=50, + duration=2, + image_type='PRECIPET_RAIN_WEATHEROFFICE', + image=1) + +TURL = "http://climate.weather.gc.ca/radar/image_e.html?time=07-OCT-17+01.00.33.755554+PM&site=XFT" + +ITIMES = [ + '/radar/image_e.html?time=07-OCT-17+01.00.33.755554+PM&site=XFT' + '/radar/image_e.html?time=07-OCT-17+01.10.31.151260+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+01.20.28.146381+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+01.30.41.084535+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+01.40.36.764073+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+01.50.31.739783+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.00.28.468690+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.10.42.567798+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.20.55.146242+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.30.42.623817+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.51.12.647761+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+02.50.57.567531+PM&site=XFT', + '/radar/image_e.html?time=07-OCT-17+03.00.42.884564+PM&site=XFT', + ] + +def find_images(data): + + dump = False + for row in data.split('\n'): + if dump: + print(row) + if row.startswith('blobArray'): + dump = True + +if __name__ == '__main__': + + #print(help(requests.get)) + print(URL) + result = requests.get(URL, PARMS) + + print(result) + print(type(result.content)) + print(len(result.content)) + find_images(result.content.decode()) + + 1/0 + print(result.content.decode()) diff --git a/karmapi/orongo.py b/karmapi/orongo.py new file mode 100644 index 0000000..319a679 --- /dev/null +++ b/karmapi/orongo.py @@ -0,0 +1,122 @@ +""" Convert to rongo rongo + +Sort of. + +Four suits. + +Still Rock Wobble Dance s r w d SH DC ? + +0-9 a b +""" + +from collections import Counter + +from pathlib import Path + +import argparse + +from math import pi, e + +import random + +from PIL import Image + +PIE = pi * e + +YEAR = 1 + +MONTH = 4 + +WEEK = 52 + +DAY = 7 + +EMONTH = (DAY * MONTH) / PIE + +EYEAR = 0.25 / (DAY * WEEK) + + +def orongo(data, alpha=None): + """ Spin it around """ + + if alpha is None: + alpha = list(range(52)) + + print(data.__hash__()) + + print(len(key)) + + return reversed(data) + +def alpha( + key=None, + xgap=None, + ygap=None, + gap=None): + """ Pick symbols from an image + + Mind the gaps. + """ + key = Path(key) + + image = Image.open(str(key)) + print(image.size) + + width, height = image.size + xgap = xgap or (width / PIE) + + for season in range(MONTH): + for week in range(MONTH): + for day in range(DAY): + # pick up a pick up a pixel or many from image + yield + + + +def main(): + + parser = argparse.ArgumentParser() + + parser.add_argument('path', nargs='+') + + parser.add_argument('--key') + + parser.add_argument('--glob', default='**/*.rst') + + args = parser.parse_args() + + key = list(alpha(args.key or 'rongo.png')) + + totals = Counter() + ototals = Counter() + + for path in args.path: + print(path) + for name in Path(path).glob(args.glob): + + print(name) + + counts = Counter() + + data = name.open().read() + counts.update(data.split()) + totals.update(counts) + + rongo = orongo(data, alpha=key) + counts = Counter(rongo) + + print('rongo') + print(counts.most_common(5)) + print(sum(counts.values())) + print() + + + print('Totals:') + + print(totals.most_common(20)) + + print(sum(totals.values())) + +if __name__ == '__main__': + + main() diff --git a/karmapi/pig.py b/karmapi/pig.py index 0efb44b..14c1ad3 100644 --- a/karmapi/pig.py +++ b/karmapi/pig.py @@ -10,10 +10,6 @@ import sys import inspect -from multiprocessing import cpu_count - -from concurrent.futures import ProcessPoolExecutor - import curio # import this early, I like pandas. diff --git a/karmapi/pigfarm.py b/karmapi/pigfarm.py index b2df63c..9d4f11e 100644 --- a/karmapi/pigfarm.py +++ b/karmapi/pigfarm.py @@ -6,7 +6,13 @@ """ import pandas # piglets and pandas together -np = pandas.np +import numpy as np + +try: + + from pandas.core.indexes.datetimes import DatetimeIndex +except: + from pandas.tseries.index import DatetimeIndex from collections import deque import curio @@ -23,7 +29,6 @@ from karmapi import piglet from karmapi import toy -from tkinter import Toplevel BIGLY_FONT = 'helvetica 20 bold' @@ -33,6 +38,7 @@ class PigFarm: def __init__(self, meta=None, events=None): self.event = curio.UniversalQueue() + self.play = '' self.piglet_event = curio.UniversalQueue() @@ -107,7 +113,7 @@ async def build(self): while True: meta, kwargs = await self.builds.get() - print('building piglet:', meta) + print('building piglet:', meta, kwargs.keys()) piglet = meta(self.toplevel(), **kwargs) @@ -141,12 +147,21 @@ async def help(self): keys.update(self.event_map) msg = '' for key, value in sorted(keys.items()): - msg += '{} {}\n'.format(key, value.__doc__) + msg += '{} {}\n'.format(key, + self.doc_firstline(value.__doc__)) from karmapi import piglet piglet.Help(msg) + def doc_firstline(self, doc): + """ Return first line of doc """ + if doc: + return doc.split('\n')[0] + else: + return "????" + + async def quit(self): """ quit the farm """ @@ -222,6 +237,15 @@ async def tend(self): async def run(self): self.quit_event = curio.Event() + + print(f'PLAYYYYY TIME *{self.play}*') + for x in self.play: + await self.event.put(x) + + #print(f'playing {x] qsize {self.event.qsize}') + print(f'{x} xxxx') + + self.play = '' runner = await spawn(self.tend()) @@ -279,10 +303,22 @@ async def show_eric(self): await spawn(farm.run()) - farm.toplevel().withdraw() + #farm.toplevel().withdraw() +def sty(clazz=None, parms={}, play=''): + + farm = PigFarm() + farm.play = play + + from karmapi.mclock2 import GuidoClock + + farm.add(GuidoClock) + + if clazz: + farm.add(clazz, parms) + return farm class Pig: """ Display piglets, part of a farm @@ -404,7 +440,7 @@ def load_image(self, name): height /= wscale width /= wscale - print(f'load {width} {height}') + print(width, height) image = image.resize((int(width), int(height))).convert('RGBA') @@ -507,7 +543,7 @@ def frame_to_stats(self, frame): stats = frame.describe() - ef = pandas.formats.format.EngFormatter(1, True) + ef = pandas.io.formats.format.EngFormatter(1, True) cells = [] @@ -550,7 +586,7 @@ def process_data(self): if self.begin or self.end: frame = filter_frame(frame, self.begin, self.end) - if isinstance(frame.index, pandas.tseries.index.DatetimeIndex): + if isinstance(frame.index, DatetimeIndex): sortflag = False frames[group] = dict(frame=frame, sort=sortflag) @@ -633,6 +669,7 @@ def draw_table( """ Draw a table on the axes """ from matplotlib import colors, cm, table + from blume.table import table norm = colors.Normalize() stats, cells, rows, cols = self.frame_to_stats(data) @@ -652,7 +689,7 @@ def draw_table( bbox = (0.0, 0.0, 1.0, 1.0) - tab = self.axes.table( + tab = table(self.axes, rowLabels=rows, rowColours=row_colours, colLabels=cols, @@ -660,13 +697,15 @@ def draw_table( cellText=cells, cellColours=colours, cellEdgeColours=colours, + edges=['TL'], + #max_col_label_width=0.1, bbox=bbox, loc=loc) acell = tab._cells[0, 0] print('fontsize', acell.get_fontsize()) - title = title or f'table location {loc}' + title = title or 'table location ' + str(loc) self.axes.set_title(title) self.axes.set_axis_off() @@ -692,12 +731,13 @@ def draw_plot(self): # sort columns on mean mean = frame.mean() mean.sort_values(inplace=True) - frame = frame.ix[:, mean.index] + frame = frame[mean.index] # subtract the mean if self.subtract_means: plot_frame = frame - mean plot_frame /= frame.std() + plot_frame = plot_frame.clip(-3, 3) else: plot_frame = frame @@ -802,11 +842,11 @@ def make_timestamp_index(frame): return frame def filter_frame(frame, start, end): - + """ FIXME - looks weird and used f-strings """ d = start - start = f'{d.year}-{d.month:02}-{d.day:02} {d.hour:02}:{d.minute:02}:{d.second:02}' + #start = f'{d.year}-{d.month:02}-{d.day:02} {d.hour:02}:{d.minute:02}:{d.second:02}' d = end - end = f'{d.year}-{d.month:02}-{d.day:02} {d.hour:02}:{d.minute:02}:{d.second:02}' + #end = f'{d.year}-{d.month:02}-{d.day:02} {d.hour:02}:{d.minute:02}:{d.second:02}' return frame[start:end] diff --git a/karmapi/piglet.py b/karmapi/piglet.py index 6c95308..70c0922 100644 --- a/karmapi/piglet.py +++ b/karmapi/piglet.py @@ -17,10 +17,12 @@ from .backends.hatpig import * -else: - +elif joy.BACKEND == 'tk': from .backends.tkpig import * +else: + from .backends.pipig import * + global YQ YQ = curio.Queue() @@ -149,12 +151,13 @@ async def doit(self): async def run(self): """ Make the pig run """ # spawn task for each runner - coros = [] - for item in self.runners: - if inspect.iscoroutine(item): - coros.append(await(curio.spawn(item))) - await curio.gather(coros) + async with curio.TaskGroup() as coros: + + for item in self.runners: + if inspect.iscoroutine(item): + await coros.spawn(item) + class Grid(Pig): """ A grid of widgets """ @@ -416,18 +419,15 @@ async def magic(self, event, *args, **kwargs): async def run(self): - poll_task = await curio.spawn(self.poll()) + async with curio.TaskGroup() as tasks: + poll_task = await tasks.spawn(self.poll()) - flush_task = await curio.spawn(self.flush()) + flush_task = await tasks.spawn(self.flush()) - yosser_tasks = [] - for yosser in range(cpu_count()): + yosser_tasks = [] + for yosser in range(cpu_count()): - yosser_tasks.append(await curio.spawn(self.yosser(YQ))) - - tasks = [flush_task, poll_task] + yosser_tasks - - await curio.gather(tasks) + yosser_tasks.append(await tasks.spawn(self.yosser(YQ))) class Piglet(Pig): @@ -453,7 +453,7 @@ def draw_table(self): cellEdgeColours=colours, loc=loc) #loc='upper_center') - self.axes.set_title(f'table location {loc}') + self.axes.set_title('table location ' + str(loc)) self.axes.set_axis_off() @@ -506,7 +506,8 @@ class Image(PlotImage): def __init__(self, parent, image=None, title=None, galleries=None): - from ripl import imagefind + from .finder import ImageFind + imagefind = ImageFind() self.path = '/home/jng/devel/karmapi/docs/pycaribbean/princess_cricket.jpg' diff --git a/karmapi/pixin.py b/karmapi/pixin.py new file mode 100644 index 0000000..07abc2f --- /dev/null +++ b/karmapi/pixin.py @@ -0,0 +1,80 @@ +""" +Quick and dirty move some pictures around. + +Usual stuff guess year/month/day from file name, move accordingly + +Cross fingers +""" +import datetime +import argparse +import shutil + +from pathlib import Path + +def warp(dest, when): + + folder = dest / str(when.year) / str(when.month) / str(when.day) + + return folder / f'{when.hour:02}{when.minute:02}{when.second:02}' + +def parse(item): + """ Oh no.. date parsing time """ + print(item) + pitem = Path(item) + #for x in dir(pitem): + # print(x) + when = pparse(pitem) + + return when, pitem + +def pparse(pitem): + """ Convert path into date time """ + fields = pitem.stem.replace('~', '_').split('_') + print(fields) + + name, day, second = fields[:3] + + year = int(day[:4]) + month = int(day[4:6]) + day = int(day[6:]) + print(year, month, day) + + hour = int(second[:2]) + minute = int(second[2:4]) + second = int(second[4:]) + + when = datetime.datetime(year, month, day, hour, minute, second) + + return when + +if __name__ == '__main__': + + parser = argparse.ArgumentParser() + + parser.add_argument('dest') + + parser.add_argument('-folder', default='.') + + args = parser.parse_args() + + items = Path(args.folder) + + dest = Path(args.dest) + + for item in items.glob('*'): + + # skip sub-folders for now. Pixel pics come with .inflight + if item.is_dir(): + continue + + when, what = parse(item) + + if when and what: + + where = warp(dest, when).with_suffix(what.suffix) + + if where: + where.parent.mkdir(exist_ok=True, parents=True) + print(what, where) + if not where.exists(): + shutil.copyfile(what, where) diff --git a/karmapi/prime.py b/karmapi/prime.py index 6a97e5b..498bfe3 100644 --- a/karmapi/prime.py +++ b/karmapi/prime.py @@ -3,7 +3,7 @@ import random import math -from karmapi.piglet import Video +from blume import magic xx = """ 10 0.500000 0.4343 A @@ -26,7 +26,7 @@ 1,000,000,000,000,000,000 1.000000 0.0241 C """ -class Prime(Video): +class Prime(magic.Ball): def compute_data(self): @@ -34,7 +34,7 @@ def compute_data(self): pass - def plot(self): + async def run(self): print('plotting primes') @@ -58,6 +58,8 @@ def plot(self): self.axes.plot(y) + self.put(magic.fig2data(plt)) + PRIMES = [2, 3] diff --git a/karmapi/rainbow.py b/karmapi/rainbow.py new file mode 100644 index 0000000..c5908b2 --- /dev/null +++ b/karmapi/rainbow.py @@ -0,0 +1,58 @@ +""" +Somewhere + +under a rainbow + +way up high + +Credits: GOES East Rainbow data from NOAA +""" +import argparse +import datetime +from pathlib import Path +import curio + +import requests + +from karmapi import base, tpot + +URL = "http://www.ssd.noaa.gov/goes/east/tatl/rb-animated.gif" + + +def get(path, url=URL): + """ Get latest rainbow """ + + with Path(path).open('wb') as out: + out.write(requests.get(url).content) + + +async def capture(args): + + + while True: + + now = datetime.datetime.now() + path = Path(f'{args.path}/{now.year}/{now.month}/{now.day}') + path.mkdir(exist_ok=True, parents=True) + path = path / f'{now.hour:02}{now.minute:02}{now.second:02}.gif' + + print(path) + get(str(path)) + await curio.sleep(args.sleep) + + + +def main(): + + parser = argparse.ArgumentParser() + parser.add_argument('--sleep', type=float, default=60*60) + parser.add_argument('path', nargs='?', default='.') + + args = parser.parse_args() + + curio.run(capture(args)) + + +if __name__ == '__main__': + + main() diff --git a/karmapi/roikpi.py b/karmapi/roikpi.py new file mode 100644 index 0000000..a7c5102 --- /dev/null +++ b/karmapi/roikpi.py @@ -0,0 +1,85 @@ +""" +Round objects in karma pi +""" + +import math + +import argparse + +from collections import deque, defaultdict, Counter, namedtuple + +import curio + +import numpy + +from PIL import Image, ImageTk + +from karmapi import base, tpot, prime, pigfarm + +from karmapi.wc import wc +from karmapi import cpr +from karmapi import ncdf +from karmapi import tankrain + +from random import random, randint, gauss + +def main(): + + parser = ncdf.argument_parser() + + parser.add_argument('--pig', action='store_false', default=True) + parser.add_argument('--minutes', type=int, default=30) + parser.add_argument('slides', nargs='?', default='.') + parser.add_argument('--background') + parser.add_argument('--version', default='') + parser.add_argument('--date') + parser.add_argument('--events') + + args = parser.parse_args() + print(args) + + args.date = base.parse_date(args.date) + + if args.events: + args.events = open(args.events) + + farm = pigfarm.sty() + + + farm.add( + tankrain.TankRain, + dict(path=args.slides, version=args.version, date=args.date)) + + # JeusSansFrontieres + jsf = wc.jsf + + farm.add( + wc.MexicanWaves, + dict(jsf=jsf, + venues=wc.places, + back_image=args.background, + events=args.events)) + + spheres = cpr.args_to_spheres(args) + + farm.add( + cpr.NestedWaves, + dict(balls=spheres)) + + cf = ncdf.CircularField(args) + print('min max:') + print(cf.values[0].min(), cf.values[0].max()) + + spheres = cpr.args_to_spheres(args) + + parms = dict(stamps=cf.stamps, values=cf.values, save=args.save, + balls=spheres) + + farm.add(ncdf.World, parms) + + curio.run(farm.run(), with_monitor=True) + + +if __name__ == '__main__': + + main() diff --git a/karmapi/sense.py b/karmapi/sense.py index e4af246..e859cb4 100644 --- a/karmapi/sense.py +++ b/karmapi/sense.py @@ -35,10 +35,9 @@ from karmapi import pigfarm, base try: - import sense_hat + import pisense except: - # see if sense hat emulator is around - import sense_emu as sense_hat + print('No sense hat libraries') def stats(hat): @@ -66,8 +65,8 @@ def get_weather(hat): while True: data = dict( - humidity = hat.humidity, - pressure = hat.pressure, + humidity = hat.environ.humidity, + pressure = hat.environ.pressure, temperature = ( hat.get_temperature_from_pressure() + @@ -233,7 +232,7 @@ async def record(path='.', sleep=1, tasks=None, names=None, hat=None): """ Record everything from the hat """ if hat is None: - hat = sense_hat.SenseHat() + hat = pisense.SenseHAT() weather = get_weather compass = get_compass @@ -281,13 +280,10 @@ def drop_bad_rows(infile): print(fields) nn = len(fields) - + + lasttime = 0.0 for ix, row in enumerate(infile): - # sometimes get nulls in data eg when pi not shutdown cleanly - if null in row: - continue - values = row.split(',') values = [x.strip() for x in values] @@ -295,12 +291,25 @@ def drop_bad_rows(infile): print(ix, len(fields), len(values)) continue - result.append(dict(zip(fields, values))) + # turn values into a dictionary + data = dict(zip(fields, values)) - return result + timestamp = float(data.get('timestamp', 0)) + + # sometimes get nulls in data eg when pi not shutdown cleanly + if null in row or timestamp < lasttime: + yield result + result = [] + lasttime = 0 + continue + + lasttime = timestamp + result.append(data) -def xtimewarp_timestamps(data): - """ Don't let data go backwards in time """ + yield result + +def check_timestamps(data): + """ See if data go backwards in time """ lasttime = None timewarp = 0.0 @@ -309,14 +318,12 @@ def xtimewarp_timestamps(data): timestamp = float(row['timestamp']) if lasttime and timestamp < lasttime: - timewarp = lasttime - timestamp - print(ix, timewarp) + print('timewarp', ix, timestamp-lasttime, timestamp, lasttime) - row['timestamp'] = str(timestamp + timewarp) + #row['timestamp'] = str(timestamp + timewarp) lasttime = timestamp - return data def timewarp_timestamps(data): """ Don't let data go backwards in time """ @@ -340,7 +347,7 @@ def timewarp_timestamps(data): if lasttime and timestamp < lasttime: timewarp = lasttime - timestamp - print(ix, timewarp) + print('timewarp', ix, timewarp) elif timewarp: mc = deltas.most_common(1)[0][0] @@ -360,31 +367,40 @@ def clean(path): put clean files in clean subfolder. """ (path / 'clean').mkdir(exist_ok=True, parents=True) - + for name in path.glob('*'): if name.is_dir(): continue with name.open() as dirty: - data = drop_bad_rows(dirty) - data = timewarp_timestamps(data) - - fields = data[0].keys() - clean_name = path / 'clean' / name.name - with clean_name.open('w') as cleaner: - writer = csv.DictWriter(cleaner, fieldnames=fields) - writer.writeheader() - writer.writerows(data) - - df = base.load(clean_name) - - # change pressure to altitude if it exists - if hasattr(df, 'pressure'): - df['altitude'] = df.pressure.map(pressure_to_altitude) - - df = df.drop('pressure', axis=1) - - base.save(clean_name, df) + for part, data in enumerate(drop_bad_rows(dirty)): + print(part, name) + if not(data): + continue + + fields = data[0].keys() + + if 'timestamp' in fields: + check_timestamps(data) + + clean_name = path / 'clean' / name.name + if part: + clean_name = path / 'clean' / (name.name + f'{part}') + + with clean_name.open('w') as cleaner: + writer = csv.DictWriter(cleaner, fieldnames=fields) + writer.writeheader() + writer.writerows(data) + + df = base.load(clean_name) + + # change pressure to altitude if it exists + if hasattr(df, 'pressure'): + df['altitude'] = df.pressure.map(pressure_to_altitude) + + df = df.drop('pressure', axis=1) + + base.save(clean_name, df) class HatShow: """ Show things on a Sense Hat """ @@ -420,7 +436,7 @@ def main(): farm = pigfarm.PigFarm() - hat = sense_hat.SenseHat() + hat = pisense.SenseHAT() farm.add(WeatherHat) farm.add(OrientHat) diff --git a/karmapi/sha.py b/karmapi/sha.py new file mode 100644 index 0000000..2ad2b72 --- /dev/null +++ b/karmapi/sha.py @@ -0,0 +1,478 @@ +""" +Spherical Harmonic Analysis and markov models. + +And also, plotting as you go. + +Navigating data. +""" + + +from karmapi import ncdf, tpot + +import pyshtools +import curio +import matplotlib +from matplotlib import pyplot as plt +from blume.table import table +from blume import magic +from blume import farm as magic_farm + +import numpy as np + +import datetime +from collections import Counter +import math +import time + +def spectrum(value): + + + clm = ncdf.to_sha(value[1:]) + + return clm, pyshtools.spectralanalysis.spectrum(clm) + + +async def generate_spectra(df, queue=None, + lmax=10, mmax=10, power=False, delta=False, + month=None, topn=0, **kwargs): + + print('Calculating means across years') + df.sum_years() + print('Done means across years') + + spectra = [] + last = None + lastdate = None + vmax = vmin = None + vmax = None + vmin = None + fig = plt.figure() + fig.set_facecolor('black') + + for ix, (date, value) in enumerate(df.generate_data()): + + value = df.deviation(date, value) + + if last is None: + last = value + continue + + if delta: + value = last - value + + clm, spect = spectrum(value) + if power: + print('SPECT:', spect) + value = spect + else: + value = np.append(clm[0][:lmax, :lmax], + clm[1][:lmax, :lmax]) + junk, ww, hh = clm.shape + + start = lmax + clm[:, start:ww, start:hh] = 0.0 + + xxxx = pyshtools.expand.MakeGridDH(clm) + plot = xxxx + #print(type(xxxx), xxxx.shape) + + #if True: + perc = np.percentile + if not month or date.month == month: + print('lmax:', lmax) + + if vmax is None: + vmax = perc(plot, 95.) + vmin = perc(plot, 5.) + print('vmax/vmin', vmax, vmin) + + print(date, perc(plot, 5), + perc(plot, 95), plot.mean()) + + fig.clear() + + #ax = fig.add_axes((0,0,1,1), projection='mollweide') + ax = fig.add_subplot(1, 1, 1, + projection='mollweide') + lon = np.linspace(-np.pi, np.pi, plot.shape[1]) + lat = np.linspace(-np.pi/2, np.pi/2, plot.shape[0]) + lon, lat = np.meshgrid(lon, lat) + ax.pcolormesh(lon, lat, plot[::-1], cmap=plt.cm.jet, + vmax=vmax, vmin=vmin) + ax.set_title(str(date), color='white') + ax.axis('off') + key = (date.month, date.day, date.hour) + + if False: + ax = fig.add_subplot(2, 1, 2, + projection='mollweide') + + xxxx = df.totals[key][1:] + lon = np.linspace(-np.pi, np.pi, xxxx.shape[1]) + lat = np.linspace(-np.pi/2, np.pi/2, xxxx.shape[0]) + lon, lat = np.meshgrid(lon, lat) + ax.axis('off') + + ax.pcolormesh(lon, lat, xxxx[::-1], cmap=plt.cm.jet) + #vmax=vmax, vmin=vmin) + + plt.grid(True) + + await queue.put(magic.fig2data(fig)) + await curio.sleep(0) + + spectra.append(value) + + if lastdate and lastdate > date: + break + lastdate = date + + if topn and ix > topn: + break + + + print(f'FULL SET OF SPECTRA {len(spectra)} {len(spectra[0])}') + return spectra + + +def stats(data): + """ Return some standard stats """ + print("DATA STATS (shape, mean, var, percentiles)") + print(data.shape) + print(data.mean()) + print(data.var()) + print(np.percentile(data.cumsum(), [0.25, 0.5, 0.75, 0.9, 0.99])) + print() + means = data.mean(axis=0) + print(f'means: {means.shape}') + stds = data.std(axis=0) + print(f'stds: {stds.shape}') + + for x in range(12): + print(means[10*x:10 + (10 * x)]) + print() + + +def random_sample(data, n): + + norm = np.random.normal + means = data.mean(axis=0) + stds = data.std(axis=0) + + shape = [n] + list(means.shape) + samp = norm(size=shape) + + # old code below scales to original distro + print(samp.shape) + + samp *= stds + samp += means + + return samp + +def normalise(data): + + means = data.mean(axis=0) + stds = data.std(axis=0) + #print(f'normalise {means}') + #print(f'normalise {stds}') + stds = np.where(stds==0.0, + np.ones(shape=stds.shape), + stds) + data -= means + data /= stds + + return data + + +def stamp_stats(stamps): + + dates = [x[1] for x in stamps] + hours = Counter(x.hour for x in dates) + hhours = Counter(x.hour for x in dates[:int(len(dates)/2)]) + months = Counter((x.year, x.month) for x in dates) + + print(hours) + print(hhours) + print(months) + +def make_bmatrix(spectra, states): + """ """ + nstates = len(states) + # calculate probs given observations + B = np.zeros(shape=(len(spectra), nstates), dtype=float) + + observations = [] + for obs, spect in enumerate(spectra): + observations.append(obs) + + for state, ss in enumerate(states): + dist = spect.dot(ss) + + #distance /= (ss + 1) ** 0.5 + + # FIXME? need to convert distance to prob + # but teapot will deal with any linear scaling + # so prob e ** x or log(x) here ... or all ok? + + #print(obs, state, dist) + #B[obs, state] = (abs(dist) ** 0.5) + #print('B', obs, state, dist, math.e ** (-1 * dist)) + B[obs, state] = math.e ** (-1 * dist) + + return observations, B + +class TeaPlot(magic.Ball): + + def __init__(self, nstates=10, **kwargs): + + super().__init__(**kwargs) + + self.tplot = tpot.TeaPlot(**kwargs) + + # Like to change this so input comes over queues + # with an end of queue + self.nstates = nstates + + self.event_map = dict( + t=self.tea) + + async def tea(self): + + print('time for tea') + + def beer(self): + + super().beer() + + rebrew(self) + + async def start(self): + + spectra = self.spectra + nstates = self.nstates + + sample = random_sample(spectra, nstates) + + observations, B = make_bmatrix(spectra, sample) + print('b matrix:', B[0]) + self.OBSERVATIONS = observations + + # generate random eh? + A = np.random.random(size=(nstates, nstates)) + for i in range(nstates): + A[i, :] /= A[i, :].sum() + + P0 = np.random.random(size=nstates) + P0 /= P0.sum() + self.A = A + self.B = B + self.P0 = P0 + + self.OBSERVATIONS = observations + + # do one tpot round + self.brew() + self.beer() + self.stir() + print("Initial score", self.SCORE) + + # show a plot? + plot = gamma_plot(self) + await self.put(plot, 'image') + + async def run(self): + + + print('TPOT filled, away we go') + print(self.A) + print(self.P0) + self.stew(iters=1, epsilon=2.0) + + plot = gamma_plot(self) + await self.put(plot, 'image') + + print(f'q size {self.queue.qsize()}') + + #for x in self.GAMMA[:10]: + # print(f'Gamma: {x}') + + await curio.sleep(1) + + + +def gamma_plot(tpot): + + T, nstates = tpot.GAMMA.shape + + bottom = np.zeros(T, dtype=float) + index = list(range(T)) + fig = plt.figure() + ax = fig.add_subplot(211) + data = tpot.GAMMA + + print(f'data shape {data.shape}') + ax.imshow(data.T, aspect='auto') + #for i in range(nstates): + # ax.bar(index, data[:, i], bottom=bottom) + # bottom += data[:, i] + + + from matplotlib import colors, cm + norm = colors.Normalize() + + colours = cm.get_cmap()(norm(tpot.A)) + alpha = 0.2 + colours[:, :, 3] = alpha + + ax = fig.add_subplot(212) + ax.axis('off') + tab = table(ax, + cellColours=colours, + cellEdgeColours=colours, + bbox=(0, 0, 1, 1)) + + return magic.fig2data(fig) + + + + +def lager(tplot): + """ Generate new set of states using tpot.GAMMA """ + + + spectra, nstates = tplot.spectra, tplot.nstates + nstates = tplot.nstates + + states = np.zeros(shape=(nstates, len(spectra[0])), dtype=float) + + for obs, gam in zip(spectra, tplot.GAMMA): + for state in range(nstates): + states[state] += gam[state] * obs + + for i in range(nstates): + states[i] /= sum(tplot.GAMMA[:, i]) + + return states + +def rebrew(tplot): + """ Do re-estimation """ + # re-estimate states based on gamma + states = lager(tplot) + for state in states: + print('State:', state) + + observations, B = make_bmatrix(tplot.spectra, states) + + tpot.B = B + tpot.OBSERVATIONS = observations + + +class Sphere(magic.Ball): + # FIXME: fix so teapot waits on a queue for spectra + # need a queue where None means end of data? + # + # And have it all just working as edges in the farm + + + def __init__(self, **args): + + super().__init__() + + # Now passed in as keywords + self.df = ncdf.CircularField(**args) + self.args = args + + async def run(self): + + args = self.args + self.filter_stamps(hour=args.hour, day=args.day) + + #stamp_stats(df.stamps) + spectra = await generate_spectra(df, self.image, **dargs) + spectra = np.array(spectra) + + print(f'spectra zero shape {spectra[0].shape}') + + # fixme - save spectra somewhere and do faster load. + # cf repeatability too. + # maybe just normalise spectra? + if args.norm: + nspectra = normalise(spectra) + stats(nspectra) + spectra = nspectra + + await self.put(spectra, 'spectra') + +def main(): + + parser = ncdf.argument_parser() + + parser.add_argument('--plot', action='store_true') + parser.add_argument('--topn', type=int, default=0) + parser.add_argument('--lmax', type=int, default=10) + parser.add_argument('--power', action='store_true') + parser.add_argument('--norm', action='store_true') + parser.add_argument('--nstates', type=int, default=10) + + parser.add_argument('--month', type=int) + parser.add_argument('--day', type=int) + parser.add_argument('--hour', type=int) + + args = parser.parse_args() + + + curio.run(run(args)) + +async def run(args): + + # might be interesting to try to turn args into + # coroutines that allow the values in args to be controlled + # not sure where all that belongs, but should pass args to Farm? + farm = magic_farm.Farm() + + carpet = farm.carpet + #await carpet.more() + #await carpet.more() + + farm.setup() + await farm.start() + + runner = await curio.spawn(farm.run()) + + # magic to go from argparse to a dict + dargs = args.__dict__ + + sphere = Sphere(**dargs) + + farm.add_node(sphere) + + print(f'spectra zero shape {spectra[0].shape}') + # TeaPlotter + tea_plotter = TeaPlot(spectra=spectra, + nstates=args.nstates) + + + tea_plotter.queue = carpet.incoming + + print('STARTING TEA PLOT') + await tea_plotter.start() + + tplot_task = await curio.spawn(tea_plotter.run()) + + print(tplot_task) + + await runner.join() + + await tplot_task.cancel() + + + +if __name__ == '__main__': + + main() + #parser = ncdf.argument_parser() + + #args = parser.parse_args() + + #df = ncdf.CircularField(args) diff --git a/karmapi/table.py b/karmapi/table.py new file mode 100644 index 0000000..2fcc8ce --- /dev/null +++ b/karmapi/table.py @@ -0,0 +1,975 @@ +# Original code by: +# John Gill +# Copyright 2004 John Gill and John Hunter +# +# Subsequent changes: +# The Matplotlib development team +# Copyright The Matplotlib development team + +""" +This module provides functionality to add a table to a plot. + +Use the factory function `~matplotlib.table.table` to create a ready-made +table from texts. If you need more control, use the `.Table` class and its +methods. + +The table consists of a grid of cells, which are indexed by (row, column). +The cell (0, 0) is positioned at the top left. + +Thanks to John Gill for providing the class and table. + +""" + +from matplotlib import artist, cbook, docstring +from matplotlib.artist import Artist, allow_rasterization +from matplotlib.patches import Rectangle +from matplotlib.text import Text +from matplotlib.transforms import Bbox +from matplotlib.path import Path + + +class Cell(Rectangle): + """ + A cell is a `.Rectangle` with some associated `.Text`. + + Edge visibility is also configurable. + + .. note: + As a user, you'll most likely not creates cells yourself. Instead, you + should use either the `~matplotlib.table.table` factory function or + `.Table.add_cell`. + + Parameters + ---------- + xy : 2-tuple + The position of the bottom left corner of the cell. + width : float + The cell width. + height : float + The cell height. + edgecolor : color + The color of the cell border. + facecolor : color + The cell facecolor. + fill : bool + Whether the cell background is filled. + text : str + The cell text. + loc : {'left', 'center', 'right'}, default: 'right' + The alignment of the text within the cell. + fontproperties : dict + A dict defining the font properties of the text. Supported keys and + values are the keyword arguments accepted by `.FontProperties`. + visible_edges : str + A substring of 'BRTL' (bottom, right, top, left) or one + of {'open', 'closed', 'horizontal', 'vertical'}. + """ + + VPAD = 0.1 + """Vertical padding between text and rectangle.""" + + HPAD = 0.6 + """Multiple of fontsize to use as Horizontal between text and rectangle.""" + + _edges = 'BRTL' + """default value for visible edges.""" + + _edge_aliases = {'open': '', + 'none': '', + 'closed': 'BRTL', + 'all': 'BRTL', + 'horizontal': 'BT', + 'vertical': 'RL', + 'bottom': 'B', + 'right': 'R', + 'top': 'T', + 'left': 'L' + } + + def __init__(self, xy, width, height, + edgecolor='k', facecolor='w', + fill=True, + text='', + loc=None, + fontproperties=None, + visible_edges=None, + ): + + # Call base + Rectangle.__init__(self, xy, width=width, height=height, fill=fill, + edgecolor=edgecolor, facecolor=facecolor) + self.set_clip_on(False) + + self.visible_edges = visible_edges + + # Create text object + if loc is None: + loc = 'right' + self._loc = loc + self._text = Text(x=xy[0], y=xy[1], text=text, + fontproperties=fontproperties) + self._text.set_clip_on(False) + + def set_transform(self, trans): + Rectangle.set_transform(self, trans) + # the text does not get the transform! + self.stale = True + + def set_figure(self, fig): + Rectangle.set_figure(self, fig) + self._text.set_figure(fig) + + def get_text(self): + """Return the cell `.Text` instance.""" + return self._text + + def set_fontsize(self, size): + """Set the text fontsize.""" + self._text.set_fontsize(size) + self.stale = True + + def get_fontsize(self): + """Return the cell fontsize.""" + return self._text.get_fontsize() + + def auto_set_font_size(self, renderer, grow=False): + """Adjust font size until the text fits. + + Parameters + ---------- + renderer : Renderer + grow : bool + Whether the font size should also be increased if there is space + available. + """ + + fontsize = self.get_fontsize() + width, height = self.get_required_dimensions(renderer) + + if width == 0: + return fontsize + + # make sure font is large enough + if grow: + while width < self.get_width() and height < self.get_height(): + fontsize += 1 + + self.set_fontsize(fontsize) + width, height = self.get_required_dimensions(renderer) + + # now shrink until it fits + while (fontsize > 1 and + (width > self.get_width() or height > self.get_height())): + fontsize -= 1 + + self.set_fontsize(fontsize) + width, height = self.get_required_dimensions(renderer) + + return fontsize + + @allow_rasterization + def draw(self, renderer): + if not self.get_visible(): + return + # draw the rectangle + Rectangle.draw(self, renderer) + + # position the text + self._set_text_position(renderer) + self._text.draw(renderer) + self.stale = False + + def _set_text_position(self, renderer): + """Set text up so it draws in the right place. + + Currently support 'left', 'center' and 'right' + """ + bbox = self.get_window_extent(renderer) + l, b, w, h = bbox.bounds + + # draw in center vertically + self._text.set_verticalalignment('center_baseline') + y = b + (h / 2.0) + + # now position horizontally + if self._loc == 'center': + self._text.set_horizontalalignment('center') + x = l + (w / 2.0) + elif self._loc == 'left': + self._text.set_horizontalalignment('left') + x = l + self._get_horizontal_pad() + else: + self._text.set_horizontalalignment('right') + x = l + w - self._get_horizontal_pad() + + self._text.set_position((x, y)) + + def get_text_bounds(self, renderer): + """ + Return the text bounds as *(x, y, width, height)*. + """ + bbox = self._text.get_window_extent(renderer) + return bbox + + def get_required_width(self, renderer): + """Return the minimal required width for the cell.""" + width, height = self.get_required_dimensions(renderer) + return width + + def get_required_height(self, renderer): + """Return the minimal required width for the cell.""" + width, height = self.get_required_dimensions(renderer) + return height + + def get_required_dimensions(self, renderer): + """Return the minimal width and height required for this cell.""" + bbox = self.get_text_bounds(renderer) + l, b, w, h = bbox.bounds + + # Calculate text padding + width = w + (2.0 * self._get_horizontal_pad()) + height = h * (1.0 + (2.0 * self.VPAD)) + + # Adjust bbox to include padding + bbox.x1 = bbox.x0 + width + bbox.y1 = bbox.y0 + height + + # apply transform to get width and height in table coordinates. + l, b, w, h = bbox.inverse_transformed(self.get_data_transform()).bounds + return w, h + + def _get_horizontal_pad(self): + """Amount of horizontal padding""" + + # if there is no text, then we don't need padding + if len(self._text._text) == 0: + return 0.0 + + # Simply use font size as padding, looks reasonable in most cases. + return self.get_fontsize() * self.HPAD + + @docstring.dedent_interpd + def set_text_props(self, **kwargs): + """ + Update the text properties. + + Valid kwargs are + + %(Text)s + """ + self._text.update(kwargs) + self.stale = True + + @property + def visible_edges(self): + """ + The cell edges to be drawn with a line. + + Reading this property returns a substring of 'BRTL' (bottom, right, + top, left). + + When setting this property, you can use a substring of 'BRTL' or one + of {'open', 'closed', 'horizontal', 'vertical', 'all', 'none'} + """ + return self._visible_edges + + @visible_edges.setter + def visible_edges(self, value): + if value is None: + self._visible_edges = self._edges + else: + lookup = dict(bottom='B', right='R', top='T', left='L') + value = ''.join((lookup.setdefault(x, x) for x in value)) + + if value in self._edge_aliases: + self._visible_edges = self._edge_aliases[value] + else: + if any(edge not in self._edges for edge in value): + raise ValueError( + 'Invalid edge param {}, must only be one of ' + '{} or string of {}'.format( + value, + ", ".join(self._edge_aliases), + ", ".join(self._edges))) + + self._visible_edges = value + + self.stale = True + + def get_path(self): + """Return a `.Path` for the `.visible_edges`.""" + codes = [Path.MOVETO] + + for edge in self._edges: + if edge in self._visible_edges: + codes.append(Path.LINETO) + else: + codes.append(Path.MOVETO) + + if Path.MOVETO not in codes[1:]: # All sides are visible + codes[-1] = Path.CLOSEPOLY + + return Path( + [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]], + codes, + readonly=True + ) + + +@cbook.deprecated('3.2', message='CustomCell functionality merged into Cell') +class CustomCell(Cell): + pass + + +class Table(Artist): + """ + A table of cells. + + The table consists of a grid of cells, which are indexed by (row, column). + + For a simple table, you'll have a full grid of cells with indices from + (0, 0) to (num_rows-1, num_cols-1), in which the cell (0, 0) is positioned + at the top left. However, you can also add cells with negative indices. + You don't have to add a cell to every grid position, so you can create + tables that have holes. + + *Note*: You'll usually not create an empty table from scratch. Instead use + `~matplotlib.table.table` to create a table from data. + """ + codes = {'best': 0, + 'upper right': 1, # default + 'upper left': 2, + 'lower left': 3, + 'lower right': 4, + 'center left': 5, + 'center right': 6, + 'lower center': 7, + 'upper center': 8, + 'center': 9, + 'top right': 10, + 'top left': 11, + 'bottom left': 12, + 'bottom right': 13, + 'right': 14, + 'left': 15, + 'top': 16, + 'bottom': 17, + } + """Possible values where to place the table relative to the Axes.""" + + FONTSIZE = 10 + + AXESPAD = 0.02 + """The border between the Axes and the table edge in Axes units.""" + + def __init__(self, ax, loc=None, bbox=None, **kwargs): + """ + Parameters + ---------- + ax : `matplotlib.axes.Axes` + The `~.axes.Axes` to plot the table into. + loc : str + The position of the cell with respect to *ax*. This must be one of + the `~.Table.codes`. + bbox : `.Bbox` or None + A bounding box to draw the table into. If this is not *None*, this + overrides *loc*. + + Other Parameters + ---------------- + **kwargs + `.Artist` properties. + """ + + Artist.__init__(self) + + if isinstance(loc, str): + if loc not in self.codes: + cbook.warn_deprecated( + "3.1", message="Unrecognized location {!r}. Falling back " + "on 'bottom'; valid locations are\n\t{}\n" + "This will raise an exception %(removal)s." + .format(loc, '\n\t'.join(self.codes))) + loc = 'bottom' + loc = self.codes[loc] + self.set_figure(ax.figure) + self._axes = ax + self._loc = loc + self._bbox = bbox + + # use axes coords + ax._unstale_viewLim() + self.set_transform(ax.transAxes) + + self._cells = {} + self._edges = None + self._autoColumns = [] + self._autoFontsize = True + self.update(kwargs) + + self.set_clip_on(False) + + def add_cell(self, row, col, *args, **kwargs): + """ + Create a cell and add it to the table. + + Parameters + ---------- + row : int + Row index. + col : int + Column index. + *args, **kwargs + All other parameters are passed on to `Cell`. + + Returns + ------- + cell : `.Cell` + The created cell. + + """ + xy = (0, 0) + cell = Cell(xy, visible_edges=self.edges, *args, **kwargs) + self[row, col] = cell + return cell + + def __setitem__(self, position, cell): + """ + Set a Cell in a given position. + """ + cbook._check_isinstance(Cell, cell=cell) + try: + row, col = position[0], position[1] + except Exception: + raise KeyError('Only tuples length 2 are accepted as coordinates') + cell.set_figure(self.figure) + cell.set_transform(self.get_transform()) + cell.set_clip_on(False) + self._cells[row, col] = cell + self.stale = True + + def __getitem__(self, position): + """Retrieve a cell from a given position.""" + return self._cells[position] + + @property + def edges(self): + """ + The default value of `~.Cell.visible_edges` for newly added + cells using `.add_cell`. + + Notes + ----- + This setting does currently only affect newly created cells using + `.add_cell`. + + To change existing cells, you have to set their edges explicitly:: + + for c in tab.get_celld().values(): + c.visible_edges = 'horizontal' + + """ + return self._edges + + @edges.setter + def edges(self, value): + self._edges = value + self.stale = True + + def _approx_text_height(self): + return (self.FONTSIZE / 72.0 * self.figure.dpi / + self._axes.bbox.height * 1.2) + + @allow_rasterization + def draw(self, renderer): + # docstring inherited + + # Need a renderer to do hit tests on mouseevent; assume the last one + # will do + if renderer is None: + renderer = self.figure._cachedRenderer + if renderer is None: + raise RuntimeError('No renderer defined') + + if not self.get_visible(): + return + renderer.open_group('table') + self._update_positions(renderer) + + for key in sorted(self._cells): + self._cells[key].draw(renderer) + + renderer.close_group('table') + self.stale = False + + def _get_grid_bbox(self, renderer): + """Get a bbox, in axes co-ordinates for the cells. + + Only include those in the range (0,0) to (maxRow, maxCol)""" + start_row = 0 + if self.has_column_labels: + start_row = -1 + boxes = [cell.get_window_extent(renderer) + for (row, col), cell in self._cells.items() + if row >= start_row and col >= 0] + bbox = Bbox.union(boxes) + + return bbox.inverse_transformed(self.get_transform()) + + def contains(self, mouseevent): + # docstring inherited + if self._contains is not None: + return self._contains(self, mouseevent) + + # TODO: Return index of the cell containing the cursor so that the user + # doesn't have to bind to each one individually. + renderer = self.figure._cachedRenderer + if renderer is not None: + boxes = [cell.get_window_extent(renderer) + for (row, col), cell in self._cells.items() + if row >= 0 and col >= 0] + bbox = Bbox.union(boxes) + return bbox.contains(mouseevent.x, mouseevent.y), {} + else: + return False, {} + + def get_children(self): + """Return the Artists contained by the table.""" + return list(self._cells.values()) + + def get_window_extent(self, renderer): + """Return the bounding box of the table in window coords.""" + self._update_positions(renderer) + boxes = [cell.get_window_extent(renderer) + for cell in self._cells.values()] + return Bbox.union(boxes) + + def _do_cell_alignment(self): + """ + Calculate row heights and column widths; position cells accordingly. + """ + # Calculate row/column widths + widths = {} + heights = {} + for (row, col), cell in self._cells.items(): + height = heights.setdefault(row, 0.0) + heights[row] = max(height, cell.get_height()) + width = widths.setdefault(col, 0.0) + widths[col] = max(width, cell.get_width()) + + # work out left position for each column + xpos = 0 + lefts = {} + for col in sorted(widths): + lefts[col] = xpos + xpos += widths[col] + + ypos = 0 + bottoms = {} + for row in sorted(heights, reverse=True): + bottoms[row] = ypos + ypos += heights[row] + + # set cell positions + for (row, col), cell in self._cells.items(): + cell.set_x(lefts[col]) + cell.set_y(bottoms[row]) + + def auto_set_column_width(self, col): + """ + Automatically set the widths of given columns to optimal sizes. + + Parameters + ---------- + col : int or sequence of ints + The indices of the columns to auto-scale. + """ + # check for col possibility on iteration + try: + iter(col) + except (TypeError, AttributeError): + self._autoColumns.append(col) + else: + for cell in col: + self._autoColumns.append(cell) + + self.stale = True + + def _auto_set_column_width(self, col, renderer): + """Automatically set width for column.""" + cells = [cell for key, cell in self._cells.items() if key[1] == col] + max_width = max((cell.get_required_width(renderer) for cell in cells), + default=0) + for cell in cells: + cell.set_width(max_width) + + def auto_set_font_size(self, value=True): + """Automatically set font size. + + Set flag which triggers automatic font size selection. + """ + self._autoFontsize = value + self.stale = True + + def _auto_set_font_size(self, renderer): + + if len(self._cells) == 0: + return + fontsize = next(iter(self._cells.values())).get_fontsize() + + grow = self._bbox is not None + + for key, cell in self._cells.items(): + # ignore auto-sized columns + if key[1] in self._autoColumns: + continue + + # set initial guess at cell font size + cell.set_fontsize(fontsize) + + size = cell.auto_set_font_size(renderer, grow=grow) + + # no point in trying bigger font after first + if grow: + grow = False + fontsize = size + else: + fontsize = min(fontsize, size) + + # now set all fontsizes equal + self.set_fontsize(fontsize) + + return fontsize + + def scale(self, xscale, yscale): + """Scale column widths by *xscale* and row heights by *yscale*.""" + for c in self._cells.values(): + c.set_width(c.get_width() * xscale) + c.set_height(c.get_height() * yscale) + + def set_fontsize(self, size): + """ + Set the font size, in points, of the cell text. + + Parameters + ---------- + size : float + + Notes + ----- + As long as auto font size has not been disabled, the value will be + clipped such that the text fits horizontally into the cell. + + You can disable this behavior using `.auto_set_font_size`. + + >>> the_table.auto_set_font_size(False) + >>> the_table.set_fontsize(20) + + """ + for cell in self._cells.values(): + cell.set_fontsize(size) + self.stale = True + + def _offset(self, ox, oy): + """Move all the artists by ox, oy (axes coords).""" + for c in self._cells.values(): + x, y = c.get_x(), c.get_y() + c.set_x(x + ox) + c.set_y(y + oy) + + def _update_positions(self, renderer): + # called from renderer to allow more precise estimates of + # widths and heights with get_window_extent + + if self._autoFontsize: + self._auto_set_font_size(renderer) + + # Do any auto width setting + for col in self._autoColumns: + self._auto_set_column_width(col, renderer) + + # Align all the cells + self._do_cell_alignment() + + bbox = self._get_grid_bbox(renderer) + l, b, w, h = bbox.bounds + + if self._bbox is not None: + # Position according to bbox + rl, rb, rw, rh = self._bbox + + self.scale(rw / w, rh / h) + + # Re-align all the cells + self._do_cell_alignment() + + ox = rl - l + oy = rb - b + else: + # Position using loc + (BEST, UR, UL, LL, LR, CL, CR, LC, UC, C, + TR, TL, BL, BR, R, L, T, B) = range(len(self.codes)) + # defaults for center + ox = (0.5 - w / 2) - l + oy = (0.5 - h / 2) - b + if self._loc in (UL, LL, CL): # left + ox = self.AXESPAD - l + if self._loc in (BEST, UR, LR, R, CR): # right + ox = 1 - (l + w + self.AXESPAD) + if self._loc in (BEST, UR, UL, UC): # upper + oy = 1 - (b + h + self.AXESPAD) + if self._loc in (LL, LR, LC): # lower + oy = self.AXESPAD - b + if self._loc in (LC, UC, C): # center x + ox = (0.5 - w / 2) - l + if self._loc in (CL, CR, C): # center y + oy = (0.5 - h / 2) - b + + if self._loc in (TL, BL, L): # out left + ox = - (l + w) + if self._loc in (TR, BR, R): # out right + ox = 1.0 - l + if self._loc in (TR, TL, T): # out top + oy = 1.0 - b + if self._loc in (BL, BR, B): # out bottom + oy = - (b + h) + + self._offset(ox, oy) + + def get_celld(self): + r""" + Return a dict of cells in the table mapping *(row, column)* to + `.Cell`\s. + + Notes + ----- + You can also directly index into the Table object to access individual + cells:: + + cell = table[row, col] + + """ + return self._cells + + +docstring.interpd.update(Table=artist.kwdoc(Table)) + + +@docstring.dedent_interpd +def table(ax, + cellText=None, cellColours=None, + cellLoc='right', colWidths=None, + rowLabels=None, rowColours=None, rowLoc='left', + colLabels=None, colColours=None, colLoc='center', + loc='bottom', bbox=None, edges='closed', + edgeColour=None, + cellEdgeColours=None, + rowEdgeColours=None, + colEdgeColours=None, + **kwargs): + """ + Add a table to an `~.axes.Axes`. + + At least one of *cellText* or *cellColours* must be specified. These + parameters must be 2D lists, in which the outer lists define the rows and + the inner list define the column values per row. Each row must have the + same number of elements. + + The table can optionally have row and column headers, which are configured + using *rowLabels*, *rowColours*, *rowLoc* and *colLabels*, *colColours*, + *colLoc* respectively. + + For finer grained control over tables, use the `.Table` class and add it to + the axes with `.Axes.add_table`. + + Parameters + ---------- + cellText : 2D list of str, optional + The texts to place into the table cells. + + *Note*: Line breaks in the strings are currently not accounted for and + will result in the text exceeding the cell boundaries. + + cellColours : 2D list of colors, optional + The background colors of the cells. + + cellLoc : {'left', 'center', 'right'}, default: 'right' + The alignment of the text within the cells. + + colWidths : list of float, optional + The column widths in units of the axes. If not given, all columns will + have a width of *1 / ncols*. + + rowLabels : list of str, optional + The text of the row header cells. + + rowColours : list of colors, optional + The colors of the row header cells. + + rowLoc : {'left', 'center', 'right'}, optional, default: 'left' + The text alignment of the row header cells. + + colLabels : list of str, optional + The text of the column header cells. + + colColours : list of colors, optional + The colors of the column header cells. + + rowLoc : {'left', 'center', 'right'}, optional, default: 'left' + The text alignment of the column header cells. + + loc : str, optional + The position of the cell with respect to *ax*. This must be one of + the `~.Table.codes`. + + bbox : `.Bbox`, optional + A bounding box to draw the table into. If this is not *None*, this + overrides *loc*. + + edges : substring of 'BRTL' or {'open', 'closed', 'horizontal', 'vertical'} + The cell edges to be drawn with a line. See also + `~.Cell.visible_edges`. + + edgeColour : default color for cell edges. + + rowEdgeColours : list of colors, optional + The colors of the edges of the row header cells. + + colEdgeColours : list of colors, optional + The colors of the edges of the column header cells. + + cellEdgeColours : 2D list of colors, optional + The colors of the edges of the cells. + + Other Parameters + ---------------- + **kwargs + `.Table` properties. + + %(Table)s + + Returns + ------- + table : `~matplotlib.table.Table` + The created table. + """ + if cellColours is None and cellText is None: + raise ValueError('At least one argument from "cellColours" or ' + '"cellText" must be provided to create a table.') + + # Check we have some cellText + if cellText is None: + # assume just colours are needed + rows = len(cellColours) + cols = len(cellColours[0]) + cellText = [[''] * cols] * rows + + rows = len(cellText) + cols = len(cellText[0]) + for row in cellText: + if len(row) != cols: + raise ValueError( + f"Each row in 'cellText' must have {cols} columns") + + if cellColours is not None: + if len(cellColours) != rows: + raise ValueError(f"'cellColours' must have {rows} rows") + for row in cellColours: + if len(row) != cols: + raise ValueError( + "Each row in 'cellColours' must have {cols} columns") + else: + cellColours = ['w' * cols] * rows + + if edgeColour is None: + # default edge color is black + edgeColour = 'k' + + if cellEdgeColours is not None: + if len(cellEdgeColours) != rows: + raise ValueError( + f"'cellEdgeColours' must have {rows} rows") + for row in cellEdgeColours: + if len(row) != cols: + raise ValueError( + f"Each row in 'cellColours' must have {cols} columns") + else: + # default is all black cell edge colours + cellEdgeColours = [[edgeColour] * cols] * rows + + # Set colwidths if not given + if colWidths is None: + colWidths = [1.0 / cols] * cols + + # Fill in missing information for column + # and row labels + rowLabelWidth = 0 + if rowLabels is None: + if rowColours is not None: + rowLabels = [''] * rows + rowLabelWidth = colWidths[0] + elif rowColours is None: + rowColours = 'w' * rows + + if rowLabels is not None: + if len(rowLabels) != rows: + raise ValueError(f"'rowLabels' must be of length {rows}") + + if rowEdgeColours is None: + rowEdgeColours = [edgeColour] * rows + elif len(rowEdgeColours) != rows: + raise ValueError(f"'rowEdgeColours' must be of length {rows}") + + if colLabels is None: + if colColours is not None: + colLabels = [''] * cols + elif colColours is None: + colColours = 'w' * cols + + if colEdgeColours is None: + colEdgeColours = [edgeColour] * cols + elif len(colEdgeColours) != cols: + raise ValueError(f"'colEdgeColours' must be of length {cols}") + + # Now create the table + table = Table(ax, loc, bbox, **kwargs) + table.edges = edges + + if table._bbox: + height = 1.0 / rows + else: + height = table._approx_text_height() + + # Add the cells + for row in range(rows): + for col in range(cols): + table.add_cell(row, col, + width=colWidths[col], height=height, + text=cellText[row][col], + facecolor=cellColours[row][col], + edgecolor=cellEdgeColours[row][col], + loc=cellLoc) + # Do column labels + table.has_column_labels = False + if colLabels is not None: + table.has_column_labels = True + for col in range(cols): + table.add_cell(-1, col, + width=colWidths[col], height=height, + text=colLabels[col], facecolor=colColours[col], + edgecolor=colEdgeColours[col], + loc=colLoc) + + # Do row labels + if rowLabels is not None: + for row in range(rows): + table.add_cell(row, -1, + width=rowLabelWidth or 1e-15, height=height, + text=rowLabels[row], facecolor=rowColours[row], + edgecolor=rowEdgeColours[row], + loc=rowLoc) + if rowLabelWidth == 0: + table.auto_set_column_width(-1) + + ax.add_table(table) + return table diff --git a/karmapi/tankrain.py b/karmapi/tankrain.py index 4cff10b..5fab8a2 100644 --- a/karmapi/tankrain.py +++ b/karmapi/tankrain.py @@ -1,6 +1,30 @@ """ Bermuda weather + + +Or at least that is how it started. + +Download and view Bermuda Weather radar. + +tankrain being heavy rains that fill the water tanks beneath Bermuda homes. + +Now it has morphed into an image viewer. + +Sort your image into folders by year month day + +Tankrain will let you navigate. + +It also works for viewing models and data. + +Just store the images for each day. """ +import itertools import argparse +import random +import sys +import asyncio +import numpy as np +from PIL import Image + import datetime utcnow = datetime.datetime.utcnow @@ -10,12 +34,11 @@ from collections import defaultdict -import curio - -from karmapi import show, base +from karmapi import base -from karmapi import pigfarm, checksum +from blume import magic, farm +from matplotlib import figure # Paths to data url = 'http://weather.bm/images/' @@ -29,24 +52,44 @@ target = 'tankrain/{date.year}/{date.month}/{date.day}/{name}_{date:%H%M}{suffix}' -class TankRain(pigfarm.MagicCarpet): +class TankRain(magic.Ball): """ Widget to show tankrain images """ - def __init__(self, parent, path=None, version='local', *args): + def __init__(self, path=None, version='local', date=None, + save=None, dedupe=0, *args): + + super().__init__() self.version = version - self.path = path or '~/karmapi/tankrain' + self.dedupe = dedupe + self.path = path or '.' + self.save_folder = save self.timewarp = 0 - self.load_images() + self.cut = 0 + self.last_data = None + self.date = date + if self.date is None: + self.date = utcnow() + + self.title = 'k' - super().__init__(parent, axes=[111]) + self.load_images() - self.add_event_map('r', self.reverse) - self.add_event_map(' ', self.next_view) + self.add_event_map('o', self.reverse) self.add_event_map('b', self.previous_day) self.add_event_map('v', self.next_day) + self.add_event_map('l', self.fewer_images) + self.add_event_map('m', self.more_images) + self.add_event_map('X', self.switcheroo) + self.add_event_map('T', self.toggle_title) + self.add_event_map('G', self.create_gif) + + def add_event_map(self, key, coro): + + self.add_filter(key, coro) + def load_images(self): self.paths = [x for x in self.get_images()] @@ -54,9 +97,37 @@ def load_images(self): self.inc = 1 def compute_data(self): + """ Set up self.data as the image + + TODO: save history, alpha smoothing, skip to next if delta small + """ + if self.last_data is None: + self._compute_data() + self.last_data = self.data + return + + self._compute_data() + return + + alpha = 0.1 + beta = 1.0 - alpha + - from PIL import Image + ix = self.ix + while self.diff() < 7.: + + self.last_data = (alpha * self.tonp(self.last_data)) + (beta * self.tonp(self.data)) + self._compute_data() + if ix == self.ix: + break + + self.data, self.last_data = self.last_data, self.data + def _compute_data(self): + """ Set self.data to image for current ix + + also increment self.ix. + """ ix = self.ix if ix < len(self.paths): @@ -65,27 +136,70 @@ def compute_data(self): # FIXME -- create an image that shows there is no data # for now, lets just show a rainbow rainbow = [x for x in range(100)] - im = [rainbow] * 100 + im = np.array([rainbow] * 100, dtype=np.uint8) + im.resize((100, 100)) + n = len(self.paths) ix = ix + self.inc - if ix == len(self.paths): - ix = 0 + if ix >= n: + ix = self.cut if ix < 0: ix = len(self.paths) - 1 self.ix = ix - - self.data = im + print('ixixixi', ix, self.ix, n, self.inc) + self.data = im + + def tonp(self, data): + + if hasattr(data, 'getdata'): + data = np.array(data.getdata()) + + return data + + def diff(self): + + adata, bdata = self.tonp(self.data), self.tonp(self.last_data) + + if adata.size != bdata.size: + return 1000.0 - def get_images(self): + diff = np.array(adata) - np.array(bdata) + print(diff.size) + + diff = (diff * diff).sum() / diff.size + + print('DIFF', diff) + return diff + + def when(self): + """ current date """ + date = self.date + datetime.timedelta(seconds=self.timewarp) + + return date + + def where(self, when=None, path=None): + """ Path for date """ + date = when or self.when() + + path = path or self.path + path = Path(f'{path}/{date.year}/{date.month}/{date.day}/').expanduser() + + return path + + + def get_images(self, when=None, path=None): # FIXME -- create key bindings to select time - date = utcnow() + datetime.timedelta(seconds=self.timewarp) - path = Path(f'{self.path}/{date.year}/{date.month}/{date.day}/').expanduser() + date = when or self.when() + path = self.where(date) print(f'loading images for path: {path} v{self.version}v') + + jpegs = path.glob('{}*.[jp][np]g'.format(self.version)) + gifs = path.glob('{}*.gif'.format(self.version)) - for image in sorted(path.glob('{}*.[jp][np]g'.format(self.version))): + for image in sorted(itertools.chain(jpegs, gifs)): if image.stat().st_size == 0: continue @@ -93,6 +207,80 @@ def get_images(self): yield image + async def save(self): + """ Save image somewhere else + + This one saves the current data, not the PIL file + so can be used to make transforms along the way. + """ + # save relative to cwd + target = self.where(self.when(), self.save_folder or '.') + + + target /= self.paths[self.ix].name + # fixme -- where's the path + print('saving to', target) + target.parent.mkdir(parents=True, exist_ok=True) + self.data.save(target) + + async def create_gif(self): + """ Turn images into a gif """ + frames = [] + for path in self.paths: + frames.append(Image.open(path)) + + when = self.when() + time = 10e3 # micro seconds + target = Path(self.save_folder or '.') + target /= f'{when.year}{when.month:02d}{when.day:02d}.gif' + + # fixme -- where's the path + print('saving to', target) + target.parent.mkdir(parents=True, exist_ok=True) + + duration = 1000 * self.sleep + + n = int(time // duration) + + n = min(n, len(self.paths)) + print(target, n, time, duration) + + frames[0].save( + str(target), + format='GIF', + append_images=frames[1:n], + save_all=True, + duration=duration, loop=0) + + + async def switcheroo(self): + """ switcheroo + + Swap images with those for previous day + + """ + current = self.when() + previous = current - datetime.timedelta(days=1) + + cfolder = self.where(current) + pfolder = self.where(previous) + + # Get the lists of image names before we start moving things around + cimages = list(self.get_images(current)) + pimages = list(self.get_images(previous)) + print('switcheroo time') + print(cimages) + print(pimages) + + for image in cimages: + image.rename(pfolder / image.name) + + for image in pimages: + image.rename(cfolder / image.name) + + self.load_images() + + async def next_view(self): switch = dict( @@ -108,52 +296,89 @@ async def next_view(self): self.load_images() async def previous_day(self): - + """ previous day """ self.timewarp -= 24 * 3600 - - self.load_images() + self.set_for_day() async def next_day(self): - + """ next day """ self.timewarp += 24 * 3600 + self.set_for_day() + + def set_for_day(self): + self.paused = False + self.cut = 0 self.load_images() async def reverse(self): - + """ Rongo Rongo change direction """ + self.paused = False self.inc *= -1 - async def start(self): - """ FIXME: get yoser to run fetch """ - #farm.yosser.run(fetch, minutes=20, sleep=300) - pass + async def pause(self): + """ pause the show """ + self.paused = not self.paused + + async def fewer_images(self): + """ Skip some images """ + self.inc = int(self.inc * 2) + self.cut = self.ix % abs(self.inc) + + + async def more_images(self): + """ Show more images """ + if abs(self.inc) > 1: + self.inc = int(self.inc / 2) + + self.cut = self.ix % abs(self.inc) + + async def toggle_title(self): + """ toggle titles """ + if self.title == 'k': + self.title = 'gold' + else: + self.title = 'k' + async def run(self): - # use yosser? - await pigfarm.aside(runfetch) + # use yosser? ironically awaiting yosser + #await pigfarm.aside(runfetch) - self.dark() - while True: + #self.dark() + if self.paths: + title = self.paths[self.ix] + else: + title = f'{self.ix} : {len(self.paths)} {self.path}' - #title = self.paths[self.ix] - if self.paths: - title = self.paths[self.ix] - else: - title = f'{self.ix} : {len(self.paths)} {self.path}' - - self.compute_data() - self.axes.clear() - print('TITLE:', title) - try: - self.axes.set_title(title) - self.axes.imshow(self.data) - except OSError: - print('dodgy image:', self.paths[self.ix]) + self.compute_data() + + + print('TITLE:', title) + try: + #self.axes.set_title(title, color=self.title) + #self.axes.set_title(title, color=self.title or 'k') + #fig = figure.Figure() + #ax = fig.add_subplot() + #ax.imshow(self.data) + #ax.set_title(title) + #self.draw_ball(self.ball) - self.draw() + print(type(self.data)) + #await self.put(self.data) + ax = await self.get() + print('sps', ax.get_subplotspec()) + print('margins', ax.margins()) + print('pos', ax.get_position()) + ax.imshow(self.data) + + # need to trigger an axes draw??? + ax.show() + #self.axes.imshow(self.data) + except OSError: + print('dodgy image:', self.paths[self.ix]) - await curio.sleep(self.sleep) @@ -252,7 +477,7 @@ async def fetch(minutes=30, sleep=300): # FIXME -- shrink bad from time to time await curio.sleep(300) - + def main(args=None): """ Retrieve images currently available @@ -263,23 +488,32 @@ def main(args=None): parser = argparse.ArgumentParser() parser.add_argument('--pig', action='store_false', default=True) - parser.add_argument('--minutes', type=int, default=30) - parser.add_argument('path', nargs='?', default='~/karmapi/tankrain') + parser.add_argument('--minutes', type=int, default=0.33) + parser.add_argument('path', nargs='?', default='.') parser.add_argument('--version', default='') + parser.add_argument('--save', + help='folder to save to') + + parser.add_argument('--date') + parser.add_argument('--dedupe', type=int, default=0) args = parser.parse_args() + args.date = base.parse_date(args.date) + if args.pig: - farm = pigfarm.PigFarm() - farm.add(TankRain, dict(path=args.path, version=args.version)) + frm = farm.Farm() + + tankrain = TankRain(path=args.path, version=args.version, date=args.date, + save=args.save, dedupe=args.dedupe) - from karmapi.mclock2 import GuidoClock - farm.add(GuidoClock) + frm.add(tankrain) + frm.shep.path.append(tankrain) + farm.run(frm) - pigfarm.run(farm) sys.exit() else: - curio.run(fetch(args.minutes)) + asyncio.run(fetch(args.minutes)) if __name__ == '__main__': # Radar diff --git a/karmapi/tpot.py b/karmapi/tpot.py index a1489aa..b769264 100644 --- a/karmapi/tpot.py +++ b/karmapi/tpot.py @@ -10,246 +10,248 @@ import numpy as np # tea -A = None -B = None -P0 = None -ALPHA = None -BETA = None -GAMMA = None -SCALE = None +class TeaPlot: -# beer -R_A = None -R_B = None -R_P0 = None -R_ALPHA = None -R_BETA = None -R_GAMMA = None - - -# ingredients -OBSERVATIONS = None - -def alpha(): - """ Alpha pass - - observations: array with observations at time t=0,1, .. T - - A: state transition matrix. n x n, n = number of states - - B: prob of observation given hidden state, n * k, - k = size of observation space. - - p0: initial probability of each state. - - another turning point.. - - fork in the road... - - time will show the way. - """ - - observations = OBSERVATIONS - - T = len(OBSERVATIONS) - - n = A.shape[0] - k = B.shape[1] - - alpha = np.zeros(shape=(T, n)) - scale = np.zeros(T) - - # calculate alpha[0] - alpha[0] = P0 * B[observations[0]] - scale[0] = sum(alpha[0]) - alpha[0] /= scale[0] - - # spin through the remaining observations - for t in range(1, T): - o = observations[t] - alpha[t] = (alpha[t-1] @ A) * B[o] + def __init__(self, + A=None, B=None, P0=None): - # normalise - scale[t] = sum(alpha[t]) - alpha[t] /= scale[t] - - # Save results for later passes - global ALPHA, SCALE, SCORE - ALPHA = alpha - SCALE = scale - - SCORE = sum(np.log(scale)) - -def beta(): - """ Beta pass - - observations: array with observations at time t=0,1, .. T - - A: state transition matrix. n x n, n = number of states - - B: prob of observation given hidden state, n * k, - k = size of observation space. - - scale: scaling factors from alpha pass - - it is something unpredictable ... - """ - observations = OBSERVATIONS - scale = SCALE - - T = len(observations) + self.A = A + self.B = B + self.P0 = P0 + self.ALPHA = None + self.BETA = None + self.GAMMA = None + self.SCALE = None + + # beer + self.R_A = None + self.R_B = None + self.R_P0 = None + self.R_ALPHA = None + self.R_BETA = None + self.R_GAMMA = None + + + # ingredients + self.OBSERVATIONS = None + + def alpha(self): + """ Alpha pass + + observations: array with observations at time t=0,1, .. T + + A: state transition matrix. n x n, n = number of states - n = A.shape[0] - k = B.shape[1] + B: prob of observation given hidden state, n * k, + k = size of observation space. - beta = np.zeros(shape=(T, n)) + p0: initial probability of each state. - # Beta[T-1] uniformly set to 1.0 - beta[T-1] = 1 + another turning point.. + + fork in the road... - # spin through the remaining observations - for t in range(T-2, -1, -1): - o = observations[t+1] + time will show the way. + """ - beta[t] = (beta[t+1] * B[o]) @ A.T + observations = self.OBSERVATIONS - # normalise - beta[t] /= scale[t+1] - - # save beta pass results - global BETA - BETA = beta + T = len(observations) + A = self.A + B = self.B + P0 = self.P0 + + n = A.shape[0] + k = B.shape[1] + + alpha = np.zeros(shape=(T, n)) + scale = np.zeros(T) + + # calculate alpha[0] + alpha[0] = P0 * B[observations[0]] + scale[0] = sum(alpha[0]) + alpha[0] /= scale[0] + + # spin through the remaining observations + for t in range(1, T): + o = observations[t] + alpha[t] = (alpha[t-1] @ A) * B[o] + + # normalise + scale[t] = sum(alpha[t]) + alpha[t] /= scale[t] + + # Save results for later passes + self.ALPHA = alpha + self.SCALE = scale + + self.SCORE = sum(np.log(scale)) + + def beta(self): + """ Beta pass + + observations: array with observations at time t=0,1, .. T + + A: state transition matrix. n x n, n = number of states + B: prob of observation given hidden state, n * k, + k = size of observation space. -def gamma(): - """ Gamma pass + scale: scaling factors from alpha pass - but in the end is right.. - """ - global GAMMA + it is something unpredictable ... + """ + observations = self.OBSERVATIONS + scale = self.SCALE + A = self.A + B = self.B + + T = len(observations) - GAMMA = ALPHA * BETA + n = A.shape[0] + k = B.shape[1] -def bm_rest(): - """ Re-estimate B matrix """ - - # spin through observations to re-estimate B - bdash = np.zeros(shape=B.shape) + beta = np.zeros(shape=(T, n)) - for obs, gam in zip(OBSERVATIONS, GAMMA): - bdash[obs, :] += gam + # Beta[T-1] uniformly set to 1.0 + beta[T-1] = 1 - nstates = B.shape[1] - - for i in range(nstates): - bdash[:, i] /= sum(GAMMA[:, i]) + # spin through the remaining observations + for t in range(T-2, -1, -1): + o = observations[t+1] - global R_B + beta[t] = (beta[t+1] * B[o]) @ A.T + + # normalise + beta[t] /= scale[t+1] - R_B = bdash + # save beta pass results + self.BETA = beta -def am_rest(): - pass + def gamma(self): + """ Gamma pass -def p0_rest(): - """ Re-estimate initial state probabilities """ - global R_P0 + but in the end is right.. + """ + self.GAMMA = self.ALPHA * self.BETA - R_P0 = GAMMA[0] / sum(GAMMA[0]) + def bm_rest(self): + """ Re-estimate B matrix """ + + # spin through observations to re-estimate B + B = self.B + bdash = np.zeros(shape=B.shape) -def am_rest(): - """ Re-estimate A matrix. """ - - ksi = np.zeros(shape=A.shape) - T = ALPHA.shape[0] - n = A.shape[0] - - for t in range(1, T): - obs = OBSERVATIONS[t] - totweight = 0. - weights = np.zeros(shape=A.shape) + for obs, gam in zip(self.OBSERVATIONS, self.GAMMA): + bdash[obs, :] += gam - for i in range(n): - for j in range(n): - # alpha[t] = (alpha[t-1] @ A) * B[o] - weight = ALPHA[t-1, i] * A[i, j] * BETA[t, j] * B[obs, j] / SCALE[n] - totweight += weight - weights[i, j] += weight + nstates = B.shape[1] + + for i in range(nstates): + bdash[:, i] /= sum(self.GAMMA[:, i]) + + self.R_B = bdash + + def p0_rest(self): + """ Re-estimate initial state probabilities """ + self.R_P0 = self.GAMMA[0] / sum(self.GAMMA[0]) + + def am_rest(self): + """ Re-estimate A matrix. """ + A = self.A + B = self.B + ALPHA = self.ALPHA + BETA = self.BETA + SCALE = self.SCALE + + ksi = np.zeros(shape=A.shape) + T = ALPHA.shape[0] + n = A.shape[0] + + for t in range(1, T): + obs = self.OBSERVATIONS[t] + totweight = 0. + weights = np.zeros(shape=A.shape) - weights /= totweight - ksi += weights + for i in range(n): + for j in range(n): + # alpha[t] = (alpha[t-1] @ A) * B[o] + weight = ALPHA[t-1, i] * A[i, j] * BETA[t, j] * B[obs, j] / SCALE[n] + totweight += weight + weights[i, j] += weight - # do some gymnastics to scale ksi - ksi = (ksi.T / ksi.T.sum(0)).T + weights /= totweight + ksi += weights - # Save the re-estimate - global R_A - R_A = ksi + # do some gymnastics to scale ksi + ksi = (ksi.T / ksi.T.sum(0)).T + # Save the re-estimate + self.R_A = ksi -def fill(parms): - """ Fill the teapot """ - global A, B, P0, ALPHA, BETA, GAMMA, OBSERVATIONS - A = parms.get('a') - B = parms.get('b') - P0 = parms.get('p0') + def fill(self, parms): + """ Fill the teapot from parms - OBSERVATIONS = parms.get('observations') - - ALPHA = parms.get('alpha') - BETA = parms.get('beta') - GAMMA = parms.get('gamma') - ALPHA = parms.get('alpha') + parms: a dictionary of goodies. + """ + self.A = parms.get('a') + self.B = parms.get('b') + self.P0 = parms.get('p0') + self.OBSERVATIONS = parms.get('observations') -def brew(): - """ Brew some T """ - alpha() - beta() - gamma() - -def beer(): - """ RE-Estimate B matrix + self.ALPHA = parms.get('alpha') + self.BETA = parms.get('beta') + self.GAMMA = parms.get('gamma') + self.ALPHA = parms.get('alpha') - beer = reverse(reeb) - Since we are in Bermuda, ginger beer perhaps. + def brew(self): + """ Brew some T """ + self.alpha() + self.beta() + self.gamma() + + def beer(self): + """ RE-Estimate B matrix - I hope you have the time of your life... - """ - bm_rest() - am_rest() - p0_rest() + beer = reverse(reeb) -def stir(): + Since we are in Bermuda, ginger beer perhaps. - global P0, A, B + I hope you have the time of your life... + """ + self.bm_rest() + self.am_rest() + self.p0_rest() - A = R_A - B = R_B - P0 = R_P0 + def stir(self): -def stew(iters = 100, epsilon=.01): + self.A = self.R_A + self.B = self.R_B + self.P0 = self.R_P0 - xscore = None - for iter in range(iters): - brew() - beer() - stir() + def stew(self, iters = 100, epsilon=.01): - # check in case we seem to have converged - if xscore is not None: - delta = SCORE - xscore - if delta < epsilon: - break - - xscore = SCORE + xscore = None + for iter in range(iters): + self.brew() + self.beer() + self.stir() + print(f'SCORE {self.SCORE}') + # check in case we seem to have converged + if xscore is not None: + delta = self.SCORE - xscore + if delta < epsilon: + break + + xscore = self.SCORE -def ferment(): - pass + def ferment(): + pass diff --git a/karmapi/usgs.py b/karmapi/usgs.py index e917ff0..580493e 100644 --- a/karmapi/usgs.py +++ b/karmapi/usgs.py @@ -11,12 +11,18 @@ http://earthquake.usgs.gov/data/scr_catalog.txt """ +import math import datetime import requests URL = 'http://earthquake.usgs.gov/data/centennial/centennial_Y2K.CAT' import pandas +import ephem + +from karmapi import base + +EPOCH = datetime.datetime(1900, 1, 1) def parse(record): """ Parse a record @@ -44,16 +50,7 @@ def timestamp(x): return datetime.datetime(int(x.year), int(x.month), int(x.day), int(x.hour), int(x.minute), int(x.second)) -def load(infile): - - data = [] - for line in infile: - data.append(parse(line)) - - columns = ['year', 'month', 'day', 'hour', 'minute', 'second', - 'lat', 'lon', 'foo', 'bar', 'foobar', 'severity'] - - df = pandas.DataFrame(data, columns=columns) +def timewarp(df): # at least one date has 0 for the day :( df.day = df.day.clip_lower(1) @@ -68,4 +65,147 @@ def get(): data = requests.get(URL).content.decode() return load(data.split('\n')[:-1]) + +def rows(df): + """ generate observations """ + + for row in df.itertuples(): + yield row + +def moontime(dates, epoch=EPOCH): + """ Convert dates to moontime + + FIXME; calulate number of full moons since some epoch + """ + return dates + +def load(path): + + df = base.load(path) + + return timewarp(df) + + +def moon_phase(when): + + nmoon = ephem.next_full_moon(when).datetime() + pmoon = ephem.previous_full_moon(when).datetime() + + month_seconds = (nmoon - pmoon).total_seconds() + + phase = (when - pmoon).total_seconds() / month_seconds + + return phase + +def observation(row): + """Turn a row into an observation + + That is just a list of integers. + + Shorter vectors with the same information content a bonus. + + Or maybe a lack of variability giving a false confidence in the true information? + + For now, aim that each variable should have p states. Primes might + be good choices for number of states. + + """ + obs = [] + pi = math.pi + + # throw the year in, so we can sort of track time + #obs.append(row.year) + + # now month, would be good to use new moon count + current phase? + ix = row.Index + obs.append(moon_phase(ix)) + + # Conjure up time of day stamp + otime = row.hour + ((row.minute) / 60) + + otime += row.second / (60 * 60) + + otime = int(otime) + + obs.append(otime) + + # ok now where? + lat = row.lat + lat = (lat + 90) / 15 + obs.append(int(lat)) + + lon = row.lon + lon = (lon + 180) / 15 + obs.append(int(lon)) + + # how much? + severity = row.severity + obs.append(severity) + + #for x in dir(row.Index): print(x) + #print(row.Index.toordinal()) + #obs.append(row.month) + + + return obs + +def main(): + + import argparse + from karmapi import tpot, sonogram + + Path = base.Path + + parser = argparse.ArgumentParser() + + parser.add_argument('--path', default='karmapi/data/quake/') + parser.add_argument('--value', default='t2m') + parser.add_argument('--raw', default='centennial') + parser.add_argument('--date') + parser.add_argument( + '--pc', action='store_true', + help='do principal components') + + parser.add_argument('--delta', action='store_true') + parser.add_argument('--model', action='store_true') + parser.add_argument('--offset', type=int, default=0) + + args = parser.parse_args() + + path = Path(args.path) + + df = load(path / args.raw) + + print(df.describe()) + print(df.info()) + print() + + observations = [observation(x) for x in rows(df)] + + print(len(observations)) + print(type(observations)) + + data = [] + for row in rows(df): + obs = observation(row) + print(obs) + data.append(tuple(obs)) + + items = set() + for item in data: + items.add(tuple(item)) + + print('number of items', len(items)) + + # Build A, B, P0 and fill the tpot + + + + exit() + + +if __name__ == '__main__': + + + main() diff --git a/karmapi/veyes.py b/karmapi/veyes.py index 1712fdf..6bf04dc 100644 --- a/karmapi/veyes.py +++ b/karmapi/veyes.py @@ -5,13 +5,114 @@ import datetime from pathlib import Path import random +import subprocess +import asyncio + +from collections import deque + +from io import BytesIO -from picamera import PiCamera import time import curio -from fractions import Fraction +from PIL import Image + +from blume import farm, magic + + +class PiCamera(magic.Ball): + """ The new kid in town is libcamera-still + It does everything I need, except... + + So the plan here is to just call libcamera-still with a bunch of options + and see how it goes. + """ + def __init__(self): + + super().__init__() + + self.timestamp = False + self.datetime = True + self.latest = 'latest.jpg' + self.shutter = 1e6 # micro seconds + self.qtpreview = 0 + self.nopreview = 1 + #self.output = 'preview.jpg' + self.framerate = 2 + self.timelapse = 2000 + self.timeout = 10000 + self.gain = 10 + self.sizes = deque((0, 256, 512, 1024)) + + def normal(self): + + self.shutter = 0 + self.gain = 0 + self.timelapse = 0 + self.immediate = True + self.timeout = 0 + + + def make_cmd(self): + + cmd = ['libcamera-still'] + + flags = ['timestamp', 'datetime', 'nopreview', 'qt-preview'] + flags += ['immediate'] + for key in flags: + value = getattr(self, key.replace('-', '')) + + if value: + cmd.append('--' + key) + + keys = ('shutter', 'timelapse', 'timeout', 'framerate', 'latest') + keys += ('gain', ) + for key in keys: + + value = getattr(self, key.replace('-', '')) + if value: + cmd.append('--' + key) + cmd.append(str(value)) + + return cmd + + + async def run(self): + """ Make one call to libcamera""" + + cmd = self.make_cmd() + pipe = asyncio.subprocess.PIPE + print('running:', ' '.join(cmd)) + import time + t1 = time.time() + proc = await asyncio.create_subprocess_shell( + ' '.join(cmd), + stdout=pipe, stderr=pipe) + #subprocess.run(cmd, capture_output=True) + print(proc) + await proc.wait() + t2 = time.time() + print(f'DONE libcamera call {t2-t1}') + image = Image.open(self.latest) + + size = self.sizes[0] + if size != 0: + x, y = image.size + scale = size / max(x, y) + image = image.resize((int(x * scale), int(y * scale))) + + ax = await self.get() + + ax.imshow(image) + + ax.show() + t3 = time.time() + print(f'done imshow {t3-t2}') + + + +from fractions import Fraction def long_exposure(length=6, framerate=6, @@ -27,10 +128,8 @@ def long_exposure(length=6, # Set a framerate of 1/6fps, then set shutter # speed to 6s and ISO to 800 camera = PiCamera(resolution=resolution, framerate=Fraction(1, framerate)) - camera.shutter_speed = length * 1000000 - camera.iso = 800 - - camera.exposure_mode = 'off' + camera.shutter_speed = framerate * 1000000 + #camera.exposure_mode = 'off' # return a camera object return camera @@ -48,6 +147,19 @@ def random_picture(cam): return cam +def as_pil(camera): + """ Capture an image and return as PIL.Image """ + # Create the in-memory stream + stream = BytesIO() + camera.capture(stream, format='rgb') + + # "Rewind" the stream to the beginning so we can read its content + stream.seek(0) + image = Image.open(stream) + + return image + + async def capture(args): if args.long: @@ -56,6 +168,9 @@ async def capture(args): camera = PiCamera() camera.start_preview() + await curio.sleep(2) + + last = None while True: now = datetime.datetime.now() @@ -64,25 +179,43 @@ async def capture(args): path = path / f'{now.hour:02}{now.minute:02}{now.second:02}.jpg' print(path) - camera.capture(str(path)) + camera.capture(str(path)) + #image = as_pil(camera) await curio.sleep(args.sleep) + if args.dedupe: + # Compare image to last and save if it is different enough + pass + + # save the image + #image.save(path) + if args.random: camera = random_picture(camera) -def main(): +def xmain(): parser = argparse.ArgumentParser() parser.add_argument('--sleep', type=float, default=60) parser.add_argument('path', nargs='?', default='.') parser.add_argument('--long', action='store_true') parser.add_argument('--random', action='store_true') + parser.add_argument('--dedupe', action='store_true') args = parser.parse_args() curio.run(capture(args)) +def main(): + + fm = farm.Farm() + + camera = PiCamera() + camera.normal() + fm.add(camera) + fm.shep.path.append(camera) + farm.run(fm) if __name__ == '__main__': diff --git a/karmapi/wc/__init__.py b/karmapi/wc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/karmapi/wc/events.csv b/karmapi/wc/events.csv new file mode 100644 index 0000000..70abd41 --- /dev/null +++ b/karmapi/wc/events.csv @@ -0,0 +1,668 @@ +#year,month,day,hour,ateam,bteam,minute,what,team,player +2018,6,14,15,rus,sau,0,ko,0,0 +2018,6,14,15,rus,sau,42,goal,rus,5 +2018,6,14,15,rus,sau,45,ht,2,0 +2018,6,14,15,rus,sau,71,goal,rus,22 +2018,6,14,15,rus,sau,88,yellow,rus,17 +2018,6,14,15,rus,sau,91,goal,rus,6 +2018,6,14,15,rus,sau,94,goal,rus,11 +2018,6,14,15,rus,sau,95,ft,5,0 + +2018,6,15,12,egy,urg,0,ko,0,0 +2018,6,15,12,egy,urg,89,goal,urg,2 +2018,6,15,12,egy,urg,93,yellow,egy,5 +2018,6,15,12,egy,urg,96,yellow,egy,6 +2018,6,15,12,egy,urg,96,ft,1,0 + +2018,6,15,15,mor,ira,0,ko,0,0 +2018,6,15,15,mor,ira,10,yellow,ira,7 +2018,6,15,15,mor,ira,30,yellow,ira,8 +2018,6,15,15,mor,ira,45,ht,0,0 +2018,6,15,15,mor,ira,47,yellow,ira,18 +2018,6,15,15,mor,ira,94,goal,ira,122 +2018,6,15,15,mor,ira,96,ft,1,0 + + +2018,6,15,18,por,spa,0,ko,0,0 +2018,6,15,18,por,spa,4,goal,por,7 +2018,6,15,18,por,spa,17,yellow,spa,5 +2018,6,15,18,por,spa,24,goal,spa,19 +2018,6,15,18,por,spa,28,yellow,por,16 +2018,6,15,18,por,spa,44,goal,por,7 +2018,6,15,18,por,spa,45,ht,2,1 +2018,6,15,18,por,spa,55,goal,spa,19 +2018,6,15,18,por,spa,58,goal,spa,4 +2018,6,15,18,por,spa,88,goal,por,7 +2018,6,15,18,por,spa,90,ft,3,3 + +2018,6,16,10,fra,aus,0,ko,0,0 +2018,6,13,10,fra,aus,13,yellow aus,7 +2018,6,16,10,fra,aus,45,ht,0,0 +2018,6,16,10,fra,aus,57,yellow aus,19 +2018,6,16,10,fra,aus,58,goal,fra,7 +2018,6,16,10,fra,aus,62,goal,aus,15 +2018,6,16,10,fra,aus,57,yellow fra,12 +2018,6,16,10,fra,aus,80,goal,fra,6 +2018,6,16,10,fra,aus,87,yellow aus,16 +2018,6,16,10,fra,aus,96,ft,2,1 + +2018,6,16,13,arg,ice,0,ko,0,0 +2018,6,16,13,arg,ice,19,goal,arg,19 +2018,6,16,13,arg,ice,23,goal,ice,11 +2018,6,16,13,arg,ice,45,ht,1,1 +2018,6,16,13,arg,ice,90,ft,1,1 + +2018,6,16,14,PER,DEN,0,ko,0,0 +2018,6,16,14,PER,DEN,38,yellow,per,13 +2018,6,16,14,PER,DEN,45,ht,0,0 +2018,6,16,14,PER,DEN,58,goal,den,20 +2018,6,16,14,PER,DEN,86,yellow,den,8 +2018,6,16,14,PER,DEN,93,yellow,den,20 +2018,6,16,14,PER,DEN,94,ft,0,1 + +2018,6,16,19,CRO,NIG,0,ko,0,0 +2018,6,16,19,CRO,NIG,30,yellow,cro,7 +2018,6,16,19,CRO,NIG,32,goal,cro,108 +2018,6,16,19,CRO,NIG,45,ht,0,0 +2018,6,16,19,CRO,NIG,70,yellow,nig,5 +2018,6,16,19,CRO,NIG,71,goal,cro,10 +2018,6,16,19,CRO,NIG,89,yellow,cro,11 +2018,6,16,19,CRO,NIG,90,ft,2,0 + +2018,6,17,12,CRC,SER,0,ko,0,0 +2018,6,17,12,CRC,SER,15,yellow,crc,15 +2018,6,17,12,CRC,SER,45,ht,0,0 +2018,6,17,12,CRC,SER,56,yellow,crc,20 +2018,6,17,12,CRC,SER,56,goal,ser,11 +2018,6,17,12,CRC,SER,59,yellow,ser,6 +2018,6,17,12,CRC,SER,98,yellow,ser,8 +2018,6,17,12,CRC,SER,98,ft,0,1 + +2018,6,17,15,GER,MEX,0,ko,0,0 +2018,6,17,15,GER,MEX,35,goal,mex,22 +2018,6,17,15,GER,MEX,40,yellow,mex,15 +2018,6,17,15,GER,MEX,45,ht,0,1 +2018,6,17,15,GER,MEX,83,yellow,ger,13 +2018,6,17,15,GER,MEX,84,yellow,ger,5 +2018,6,17,15,GER,MEX,90,yellow,mex,16 +2018,6,17,15,GER,MEX,93,ft,0,1 + +2018,6,17,18,BRA,SWI,0,ko,0,0 +2018,6,17,18,BRA,SWI,20,goal,bra,11 +2018,6,17,18,BRA,SWI,31,yellow,swi,2 +2018,6,17,18,BRA,SWI,45,ht,1,0 +2018,6,17,18,BRA,SWI,47,yellow,swi,5 +2018,6,17,18,BRA,SWI,49,goal,swi,14 +2018,6,17,18,BRA,SWI,65,yellow,swi,22 +2018,6,17,18,BRA,SWI,68,yellow,swi,11 +2018,6,17,18,BRA,SWI,90,ft,BRA,1,1 + +2018,6,18,12,SWE,SKO,0,ko,0,0 +2018,6,18,12,SWE,SKO,12,yellow,sko,9 +2018,6,18,12,SWE,SKO,45,ht,0,0 +2018,6,18,12,SWE,SKO,55,yellow,sko,11 +2018,6,18,12,SWE,SKO,61,yellow,swe,17 +2018,6,18,12,SWE,SKO,65,goal,swe,17 +2018,6,18,12,SWE,SKO,90,ft,1,0 + +2018,6,18,15,BEL,PAN,0,ko,0,0 +2018,6,18,15,BEL,PAN,14,yellow,bel,15 +2018,6,18,15,BEL,PAN,18,yellow,pan,15 +2018,6,18,15,BEL,PAN,45,ht,0,0 +2018,6,18,15,BEL,PAN,47,goal,bel,14 +2018,6,18,15,BEL,PAN,49,yellow,pan,11 +2018,6,18,15,BEL,PAN,51,yellow,pan,2 +2018,6,18,15,BEL,PAN,57,yellow,pan,20 +2018,6,18,15,BEL,PAN,59,yellow,bel,5 +2018,6,18,15,BEL,PAN,51,yellow,pan,2 +2018,6,18,15,BEL,PAN,69,goal,bel,9 +2018,6,18,15,BEL,PAN,75,goal,bel,9 +2018,6,18,15,BEL,PAN,88,yellow,bel,7 +2018,6,18,15,BEL,PAN,90,ft,3,0 + +2018,6,18,18,TUN,ENG,0,ko,0,0 +2018,6,18,18,TUN,ENG,11,goal,eng,9 +2018,6,18,18,TUN,ENG,33,yellow,eng,2 +2018,6,18,18,TUN,ENG,35,goal,tun,13 +2018,6,18,18,TUN,ENG,45,ht,1,1 +2018,6,18,18,TUN,ENG,91,goal,eng,9 +2018,6,18,18,TUN,ENG,95,ft,1,2 + +2018,6,19,12,COL,JAP,0,ko,0,0 +2018,6,19,12,COL,JAP,3,red,urg,6 +2018,6,19,12,COL,JAP,6,goal,jap,10 +2018,6,19,12,COL,JAP,39,goal,col,20 +2018,6,19,12,COL,JAP,45,ht,1,1 +2018,6,19,12,COL,JAP,64,yellow,col,5 +2018,6,19,12,COL,JAP,73,goal,jap,15 +2018,6,19,12,COL,JAP,86,yellow,col,10 +2018,6,19,12,COL,JAP,93,yellow,jap,1 +2018,6,19,12,COL,JAP,94,ft,1,2 + +2018,6,19,15,POL,SEN,0,ko,0,0 +2018,6,19,15,POL,SEN,12,yellow,pol,10 +2018,6,19,15,POL,SEN,37,goal,sen,104 +2018,6,19,15,POL,SEN,45,ht,0,1 +2018,6,19,15,POL,SEN,49,yellow,sen,6 +2018,6,19,15,POL,SEN,60,goal,sen,19 +2018,6,19,15,POL,SEN,72,yellow,sen,5 +2018,6,19,15,POL,SEN,86,goal,pol,10 +2018,6,19,15,POL,SEN,95,ft,1,2 + +2018,6,19,18,RUS,EGY,0,ko,0,0 +2018,6,19,18,RUS,EGY,45,ht,0,0 +2018,6,19,18,RUS,EGY, 46, goal, rus, 107 +2018,6,19,18,RUS,EGY, 57, yellow, egy, 21 +2018,6,19,18,RUS,EGY, 59, goal, rus, 6 +2018,6,19,18,RUS,EGY, 62, goal, rus, 22 +2018,6,19,18,RUS,EGY, 73, goal, egy, 10 +2018,6,19,18,RUS,EGY, 84, yellow, rus, 10 +2018,6,19,18,RUS,EGY,90,ft,3,1 + +2018, 6, 20, 12, POR, MOR, 0, ko, 0, 0 +2018, 6, 20, 12, POR, MOR, 4, goal, por, 7 +2018, 6, 20, 12, POR, MOR, 40, yellow, mor, 5 +2018, 6, 20, 12, POR, MOR, 45, ht, 1, 0 +2018, 6, 20, 12, POR, MOR, 90, ft, 1, 0 + +2018, 6, 20, 15, URG, SAU, 0, ko, 0, 0 +2018, 6, 20, 15, URG, SAU, 23, goal, urg, 9 +2018, 6, 20, 15, URG, SAU, 45, ht, 1, 0 +2018, 6, 20, 15, URG, SAU, 90, ft, 1, 0 + +2018, 6, 20, 18, IRA, SPA, 0, ko, 0, 0 +2018, 6, 20, 18, IRA, SPA, 45, ht, 0, 0 +2018, 6, 20, 18, IRA, SPA, 54, goal, spa, 19 +2018, 6, 20, 18, IRA, SPA, 79, yellow, ira, 11 +2018, 6, 20, 18, IRA, SPA, 92, yellow, ira, 9 +2018, 6, 20, 18, IRA, SPA, 90, ft, 0, 0 + +2018, 6, 21, 12, DEN, AUS, 0, ko, 0, 0 +2018, 6, 21, 12, DEN, AUS, 7, goal, den, 10 +2018, 6, 21, 12, DEN, AUS, 37, yellow, den, 20 +2018, 6, 21, 12, DEN, AUS, 38, goal, aus, 15 +2018, 6, 21, 12, DEN, AUS, 45, ht, 1, 1 +2018, 6, 21, 12, DEN, AUS, 84, yellow, den, 23 +2018, 6, 21, 12, DEN, AUS, 90, ft, 1, 1 + +2018, 6, 21, 15, FRA, PER, 0, ko, 0, 0 +2018, 6, 21, 15, FRA, PER, 18, yellow, fra, 14 +2018, 6, 21, 15, FRA, PER, 23, yellow, per, 9 +2018, 6, 21, 15, FRA, PER, 34, goal, fra, 10 +2018, 6, 21, 15, FRA, PER, 45, ht, 1, 0 +2018, 6, 21, 15, FRA, PER, 81, yellow, per, 23 +2018, 6, 21, 15, FRA, PER, 86, yellow, fra, 6 +2018, 6, 21, 15, FRA, PER, 90, ft, 1, 0 + +2018, 6, 21, 18, ARG, CRO, 0, ko, 0, 0 +2018, 6, 21, 18, ARG, CRO, 39, yellow, cro, 18 +2018, 6, 21, 18, ARG, CRO, 45, ht, 0, 0 +2018, 6, 21, 18, ARG, CRO, 51, yellow, arg, 2 +2018, 6, 21, 18, ARG, CRO, 53, goal, cro, 18 +2018, 6, 21, 18, ARG, CRO, 58, yellow, cro, 17 +2018, 6, 21, 18, ARG, CRO, 67, yellow, cro, 2 +2018, 6, 21, 18, ARG, CRO, 80, goal, cro, 10 +2018, 6, 21, 18, ARG, CRO, 85, yellow, arg, 17 +2018, 6, 21, 18, ARG, CRO, 87, yellow, arg, 8 +2018, 6, 21, 18, ARG, CRO, 91, goal, cro, 7 +2018, 6, 21, 18, ARG, CRO, 94, yellow, cro, 5 +2018, 6, 21, 18, ARG, CRO, 95, ft, 0, 0 + +2018, 6, 22, 12, BRA, CRC, 0, ko, 0, 0 +2018, 6, 22, 12, BRA, CRC, 45, ht, 0, 0 +2018, 6, 22, 12, BRA, CRC, 81, yellow, bra, 10 +2018, 6, 22, 12, BRA, CRC, 81, yellow, bra, 11 +2018, 6, 22, 12, BRA, CRC, 84, yellow, crc, 2 +2018, 6, 22, 12, BRA, CRC, 91, goal, bra, 11 +2018, 6, 22, 12, BRA, CRC, 97, goal, bra, 10 +2018, 6, 22, 12, BRA, CRC, 99, ft, 2, 0 + +2018, 6, 22, 15, NIG, ICE, 0, ko, 0, 0 +2018, 6, 22, 15, NIG, ICE, 44, yellow, nig, 2 +2018, 6, 22, 15, NIG, ICE, 45, ht, 0, 0 +2018, 6, 22, 15, NIG, ICE, 49, goal, nig, 7 +2018, 6, 22, 15, NIG, ICE, 75, goal, nig, 7 +2018, 6, 22, 15, NIG, ICE, 90, ft, 2, 0 + +2018, 6, 22, 18, SER, SWI, 0, ko, 0, 0 +2018, 6, 22, 18, SER, SWI, 5, goal, ser, 9 +2018, 6, 22, 18, SER, SWI, 33, yellow, ser, 20 +2018, 6, 22, 18, SER, SWI, 39, yellow, ser, 4 +2018, 6, 22, 18, SER, SWI, 47, yellow, ser, 21 +2018, 6, 22, 18, SER, SWI, 47, ht, 1, 0 +2018, 6, 22, 18, SER, SWI, 52, goal, swi, 10 +2018, 6, 22, 18, SER, SWI, 89, goal, swi, 23 +2018, 6, 22, 18, SER, SWI, 90, ft, 1, 2 + +2018, 6, 23, 12, BEL, TUN, 0, ko, 0, 0 +2018, 6, 23, 12, BEL, TUN, 6, goal, bel, 10 +2018, 6, 23, 12, BEL, TUN, 14, yellow, tun, 14 +2018, 6, 23, 12, BEL, TUN, 16, goal, bel, 9 +2018, 6, 23, 12, BEL, TUN, 18, goal, tun, 11 +2018, 6, 23, 12, BEL, TUN, 48, goal, bel, 9 +2018, 6, 23, 12, BEL, TUN, 49, ht, 3, 1 +2018, 6, 23, 12, BEL, TUN, 51, goal, bel, 10 +2018, 6, 23, 12, BEL, TUN, 90, goal, bel, 21 +2018, 6, 23, 12, BEL, TUN, 93, goal, tun, 10 +2018, 6, 23, 12, BEL, TUN, 94, ft, 5, 2 + +2018, 6, 23, 15, SKO, MEX, 0, ko, 0, 0 +2018, 6, 23, 15, SKO, MEX, 25, goal, mex, 11 +2018, 6, 23, 15, SKO, MEX, 45, ht, 0, 1 +2018, 6, 23, 15, SKO, MEX, 58, yellow, sko, 19 +2018, 6, 23, 15, SKO, MEX, 63, yellow, sko, 2 +2018, 6, 23, 15, SKO, MEX, 66, goal, mex, 14 +2018, 6, 23, 15, SKO, MEX, 72, yellow, sko, 10 +2018, 6, 23, 15, SKO, MEX, 80, yellow, sko, 15 +2018, 6, 23, 15, SKO, MEX, 93, goal, sko, 7 +2018, 6, 23, 15, SKO, MEX, 96, ft, 1, 2 + +2018, 6, 23, 18, GER, SWE, 0, ko, 0, 0 +2018, 6, 23, 18, GER, SWE, 31, goal, swe, 20 +2018, 6, 23, 18, GER, SWE, 45, ht, 0, 1 +2018, 6, 23, 18, GER, SWE, 48, goal, ger, 11 +2018, 6, 23, 18, GER, SWE, 52, yellow, swe, 8 +2018, 6, 23, 18, GER, SWE, 71, yellow, ger, 17 +2018, 6, 23, 18, GER, SWE, 82, red, ger, 17 +2018, 6, 23, 18, GER, SWE, 94, goal, ger, 8 +2018, 6, 23, 18, GER, SWE, 95, ft, 2, 1 + +2018, 6, 24, 12, ENG, PAN, 0, ko, 0, 0 +2018, 6, 24, 12, ENG, PAN, 8, goal, eng, 5 +2018, 6, 24, 12, ENG, PAN, 10, yellow, pan, 11 +2018, 6, 24, 12, ENG, PAN, 23, yellow, eng, 21 +2018, 6, 24, 12, ENG, PAN, 22, goal, eng, 9 +2018, 6, 24, 12, ENG, PAN, 36, goal, eng, 7 +2018, 6, 24, 12, ENG, PAN, 40, goal, eng, 5 +2018, 6, 24, 12, ENG, PAN, 45, yellow, pan, 4 +2018, 6, 24, 12, ENG, PAN, 46, goal, eng, 9 +2018, 6, 24, 12, ENG, PAN, 47, ht, 5, 0 +2018, 6, 24, 12, ENG, PAN, 62, goal, eng, 9 +2018, 6, 24, 12, ENG, PAN, 72, yellow, pan, 2 +2018, 6, 24, 12, ENG, PAN, 77, goal, pan, 23 +2018, 6, 24, 12, ENG, PAN, 90, ft, 6, 1 + + +2018, 6, 24, 15, JAP, SEN, 0, ko, 0, 0 +2018, 6, 24, 15, JAP, SEN, 11, goal, sen, 10 +2018, 6, 24, 15, JAP, SEN, 33, goal, jap, 14 +2018, 6, 24, 15, JAP, SEN, 45, ht, 1, 1 +2018, 6, 24, 15, JAP, SEN, 59, yellow, sen, 19 +2018, 6, 24, 15, JAP, SEN, 68, yellow, jap, 14 +2018, 6, 24, 15, JAP, SEN, 71, goal, sen, 22 +2018, 6, 24, 15, JAP, SEN, 78, goal, jap, 4 +2018, 6, 24, 15, JAP, SEN, 90, yellow, sen, 12 +2018, 6, 24, 15, JAP, SEN, 91, yellow, sen, 11 +2018, 6, 24, 15, JAP, SEN, 94, yellow, jap, 17 +2018, 6, 24, 15, JAP, SEN, 95, ft, 2, 2 + +2018, 6, 24, 18, POL, COL, 0, ko, 0, 0 +2018, 6, 24, 18, POL, COL, 40, goal, col, 13 +2018, 6, 24, 18, POL, COL, 45, ht, 0, 1 +2018, 6, 24, 18, POL, COL, 61, yellow, pol, 5 +2018, 6, 24, 18, POL, COL, 70, goal, col, 9 +2018, 6, 24, 18, POL, COL, 75, goal, col, 11 +2018, 6, 24, 18, POL, COL, 85, yellow, pol, 6 +2018, 6, 24, 18, POL, COL, 96, ft, 0, 3 + +2018, 6, 25, 14, URG, RUS, 0, ko, 0, 0 +2018, 6, 25, 14, URG, RUS, 9, yellow, urg, 8 +2018, 6, 25, 14, URG, RUS, 10, goal, urg, 9 +2018, 6, 25, 14, URG, RUS, 22, goal, urg, 10 +2018, 6, 25, 14, URG, RUS, 28, yellow, rus, 23 +2018, 6, 25, 14, URG, RUS, 35, red, rus, 23 +2018, 6, 25, 14, URG, RUS, 45, ht, 2, 0 +2018, 6, 25, 14, URG, RUS, 90, ft, 2, 0 + +2018, 6, 25, 14, SAU, EGY, 0, ko, 0, 0 +2018, 6, 25, 14, SAU, EGY, 22, goal, egy, 10 +2018, 6, 25, 14, SAU, EGY, 50, yellow, egy, 2 +2018, 6, 25, 14, SAU, EGY, 51, goal, sau, 7 +2018, 6, 25, 14, SAU, EGY, 53, ht, 0, 1 +2018, 6, 25, 14, SAU, EGY, 86, yellow, egy, 7 +2018, 6, 25, 14, SAU, EGY, 95, goal, sau, 18 +2018, 6, 25, 14, SAU, EGY, 96, ft, 2, 1 + +2018, 6, 25, 18, IRA, POR, 0, ko, 0, 0 +2018, 6, 25, 18, IRA, POR, 33, yellow, por, 5 +2018, 6, 25, 18, IRA, POR, 44, goal, por, 20 +2018, 6, 25, 18, IRA, POR, 45, ht, 0, 1 +2018, 6, 25, 18, IRA, POR, 52, yellow, ira, 3 +2018, 6, 25, 18, IRA, POR, 54, yellow, ira, 20 +2018, 6, 25, 18, IRA, POR, 64, yellow, por, 20 +2018, 6, 25, 18, IRA, POR, 83, yellow, por, 7 +2018, 6, 25, 18, IRA, POR, 92, goal, ira, 10 +2018, 6, 25, 18, IRA, POR, 96, ft, 1, 1 + +2018, 6, 25, 18, SPA, MOR, 0, ko, 0, 0 +2018, 6, 25, 18, SPA, MOR, 14, goal, mor, 13 +2018, 6, 25, 18, SPA, MOR, 19, goal, spa, 22 +2018, 6, 25, 18, SPA, MOR, 21, yellow, mor, 8 +2018, 6, 25, 18, SPA, MOR, 29, yellow, mor, 16 +2018, 6, 25, 18, SPA, MOR, 31, yellow, mor, 4 +2018, 6, 25, 18, SPA, MOR, 31, yellow, mor, 14 +2018, 6, 25, 18, SPA, MOR, 45, ht, 0, 0 +2018, 6, 25, 18, SPA, MOR, 81, goal, mor, 19 +2018, 6, 25, 18, SPA, MOR, 89, yellow, mor, 12 +2018, 6, 25, 18, SPA, MOR, 91, goal, spa, 17 +2018, 6, 25, 18, SPA, MOR, 94, yellow, mor, 2 +2018, 6, 25, 18, SPA, MOR, 97, ft, 2, 2 + +2018, 6, 26, 14, DEN, FRA, 0, ko, 0, 0 +2018, 6, 26, 14, DEN, FRA, 48, yellow, den, 13 +2018, 6, 26, 14, DEN, FRA, 49, ht, 0, 0 +2018, 6, 26, 14, DEN, FRA, 90, ft, 0, 0 + +2018, 6, 26, 14, AUS, PER, 0, ko, 0, 0 +2018, 6, 26, 14, AUS, PER, 10, yellow, aus, 15 +2018, 6, 26, 14, AUS, PER, 18, goal, per, 18 +2018, 6, 26, 14, AUS, PER, 44, yellow, per, 19 +2018, 6, 26, 14, AUS, PER, 45, ht, 0, 1 +2018, 6, 26, 14, AUS, PER, 50, goal, per, 9 +2018, 6, 26, 14, AUS, PER, 60, yellow, aus, 17 +2018, 6, 26, 14, AUS, PER, 66, yellow, aus, 23 +2018, 6, 26, 14, AUS, PER, 79, yellow, per, 7 +2018, 6, 26, 14, AUS, PER, 88, yellow, aus, 5 +2018, 6, 26, 14, AUS, PER, 95, ft, 0, 2 + +2018, 6, 26, 18, NIG, ARG, 0, ko, 0, 0 +2018, 6, 26, 18, NIG, ARG, 14, goal, arg, 10 +2018, 6, 26, 18, NIG, ARG, 32, yellow, nig, 6 +2018, 6, 26, 18, NIG, ARG, 45, ht, 0, 1 +2018, 6, 26, 18, NIG, ARG, 49, yellow, arg, 14 +2018, 6, 26, 18, NIG, ARG, 51, goal, nig, 11 +2018, 6, 26, 18, NIG, ARG, 64, yellow, arg, 7 +2018, 6, 26, 18, NIG, ARG, 86, goal, arg, 16 +2018, 6, 26, 18, NIG, ARG, 32, yellow, nig, 10 +2018, 6, 26, 18, NIG, ARG, 90, ft, 1, 2 + +2018, 6, 26, 18, ICE, CRO, 0, ko, 0, 0 +2018, 6, 26, 18, ICE, CRO, 14, yellow, cro, 20 +2018, 6, 26, 18, ICE, CRO, 45, ht, 0, 0 +2018, 6, 26, 18, ICE, CRO, 53, goal, cro, 19 +2018, 6, 26, 18, ICE, CRO, 59, yellow, ice, 20 +2018, 6, 26, 18, ICE, CRO, 64, yellow, ice, 11 +2018, 6, 26, 18, ICE, CRO, 76, goal, ice, 10 +2018, 6, 26, 18, ICE, CRO, 84, yellow, ice, 2 +2018, 6, 26, 18, ICE, CRO, 90, goal, cro, 4 +2018, 6, 26, 18, ICE, CRO, 92, ft, 1, 2 + + +2018, 6, 27, 14, SKO, GER, 0, ko, 0, 0 +2018, 6, 27, 14, SKO, GER, 9, yellow, sko, 15 +2018, 6, 27, 14, SKO, GER, 23, yellow, sko, 17 +2018, 6, 27, 14, SKO, GER, 45, ht, 0, 0 +2018, 6, 27, 14, SKO, GER, 48, yellow, sko, 18 +2018, 6, 27, 14, SKO, GER, 65, yellow, sko, 7 +2018, 6, 27, 14, SKO, GER, 92, goal, sko, 19 +2018, 6, 27, 14, SKO, GER, 96, goal, sko, 7 +2018, 6, 27, 14, SKO, GER,100, ft, 0, 2 + +2018, 6, 27, 14, MEX, SWE, 0, ko, 0, 0 +2018, 6, 27, 14, MEX, SWE, 1, yellow, mex, 23 +2018, 6, 27, 14, MEX, SWE, 26, yellow, swe, 7 +2018, 6, 27, 14, MEX, SWE, 45, ht, 0, 0 +2018, 6, 27, 14, MEX, SWE, 50, goal, swe, 6 +2018, 6, 27, 14, MEX, SWE, 59, yellow, mex, 15 +2018, 6, 27, 14, MEX, SWE, 61, goal, swe, 4 +2018, 6, 27, 14, MEX, SWE, 74, goal, swe, 121 +2018, 6, 27, 14, MEX, SWE, 85, yellow, mex, 7 +2018, 6, 27, 14, MEX, SWE, 88, yellow, swe, 2 +2018, 6, 27, 14, MEX, SWE, 95, ft, 0, 3 + +2018, 6, 27, 18, SER, BRA, 0, ko, 0, 0 +2018, 6, 27, 18, SER, BRA, 33, yellow, ser, 22 +2018, 6, 27, 18, SER, BRA, 36, goal, bra, 15 +2018, 6, 27, 18, SER, BRA, 45, ht, 0, 0 +2018, 6, 27, 18, SER, BRA, 48, yellow, ser, 21 +2018, 6, 27, 18, SER, BRA, 68, goal, bra, 2 +2018, 6, 27, 18, SER, BRA, 70, yellow, ser, 9 +2018, 6, 27, 18, SER, BRA, 90, ft, 0, 0 + +2018, 6, 27, 18, SWI, CRC, 0, ko, 0, 0 +2018, 6, 27, 18, SWI, CRC, 11, yellow, crc, 16 +2018, 6, 27, 18, SWI, CRC, 29, yellow, crc, 12 +2018, 6, 27, 18, SWI, CRC, 31, goal, swi, 15 +2018, 6, 27, 18, SWI, CRC, 37, yellow, swi, 2 +2018, 6, 27, 18, SWI, CRC, 45, ht, 1, 0 +2018, 6, 27, 18, SWI, CRC, 56, goal, crc, 19 +2018, 6, 27, 18, SWI, CRC, 75, yellow, swi, 17 +2018, 6, 27, 18, SWI, CRC, 83, yellow, swi, 22 +2018, 6, 27, 18, SWI, CRC, 88, goal, swi, 19 +2018, 6, 27, 18, SWI, CRC, 89, yellow, crc, 19 +2018, 6, 27, 18, SWI, CRC, 93, goal, crc, 101 +2018, 6, 27, 18, SWI, CRC, 94, ft, 2, 2 + +2018, 6, 28, 14, JAP, POL, 0, ko, 0, 0 +2018, 6, 28, 14, JAP, POL, 45, ht, 0, 0 +2018, 6, 28, 14, JAP, POL, 59, goal, pol, 5 +2018, 6, 28, 14, JAP, POL, 66, yellow, jap, 20 +2018, 6, 28, 14, JAP, POL, 90, ft, 0, 0 + +2018, 6, 28, 14, SEN, COL, 0, ko, 0, 0 +2018, 6, 28, 14, SEN, COL, 44, yellow, col, 17 +2018, 6, 28, 14, SEN, COL, 45, ht, 0, 0 +2018, 6, 28, 14, SEN, COL, 51, yellow, sen, 19 +2018, 6, 28, 14, SEN, COL, 74, goal, col, 13 +2018, 6, 28, 14, SEN, COL, 90, ft, 0, 0 + +2018, 6, 28, 18, ENG, BEL, 0, ko, 0, 0 +2018, 6, 28, 18, ENG, BEL, 19, yellow, bel, 17 +2018, 6, 28, 18, ENG, BEL, 33, yellow, bel, 23 +2018, 6, 28, 18, ENG, BEL, 45, ht, 0, 0 +2018, 6, 28, 18, ENG, BEL, 51, goal, bel, 18 +2018, 6, 28, 18, ENG, BEL, 90, ft, 0, 1 + +2018, 6, 28, 18, PAN, TUN, 0, ko, 0, 0 +2018, 6, 28, 18, PAN, TUN, 33, goal, pan, 104 +2018, 6, 28, 18, PAN, TUN, 44, yellow, tun, 13 +2018, 6, 28, 18, PAN, TUN, 45, ht, 1, 0 +2018, 6, 28, 18, PAN, TUN, 51, goal, tun, 8 +2018, 6, 28, 18, PAN, TUN, 66, goal, tun, 10 +2018, 6, 28, 18, PAN, TUN, 71, yellow, tun, 9 +2018, 6, 28, 18, PAN, TUN, 80, yellow, tun, 6 +2018, 6, 28, 18, PAN, TUN, 90, ft, 1, 2 + +2018, 6, 30, 14, fra, arg, 0, ko, 0, 0 +2018, 6, 30, 14, fra, arg, 11, yellow, arg, 16 +2018, 6, 30, 14, fra, arg, 13, goal, fra, 7 +2018, 6, 30, 14, fra, arg, 19, yellow, arg, 3 +2018, 6, 30, 14, fra, arg, 41, goal, arg, 11 +2018, 6, 30, 14, fra, arg, 45, ht, 1, 1 +2018, 6, 30, 14, fra, arg, 48, goal, arg, 2 +2018, 6, 30, 14, fra, arg, 57, goal, fra, 2 +2018, 6, 30, 14, fra, arg, 64, goal, fra, 10 +2018, 6, 30, 14, fra, arg, 43, yellow, arg, 14 +2018, 6, 30, 14, fra, arg, 50, yellow, arg, 7 +2018, 6, 30, 14, fra, arg, 68, goal, fra, 10 +2018, 6, 30, 14, fra, arg, 72, yellow, fra, 14 +2018, 6, 30, 14, fra, arg, 73, yellow, fra, 2 +2018, 6, 30, 14, fra, arg, 93, goal, arg, 19 +2018, 6, 30, 14, fra, arg, 93, yellow, arg, 17 +2018, 6, 30, 14, fra, arg, 93, yellow, fra, 9 +2018, 6, 30, 14, fra, arg, 96, ft + +2018, 6, 30, 18, urg, por, 0, ko, 0, 0 +2018, 6, 30, 18, urg, por, 7, goal, urg, 21 +2018, 6, 30, 18, urg, por, 45, ht, 0, 0 +2018, 6, 30, 18, urg, por, 55, goal, por, 3 +2018, 6, 30, 18, urg, por, 62, goal, urg, 21 +2018, 6, 30, 18, urg, por, 93, yellow, por, 7 +2018, 6, 30, 18, urg, por, 97, ft, 2, 1 + +2018, 7, 1, 14, spa, rus, 0, ko, 0, 0 +2018, 7, 1, 14, spa, rus, 12, goal, spa, 104 +2018, 7, 1, 14, spa, rus, 41, goal, rus, 22 +2018, 7, 1, 14, spa, rus, 45, ht, 1, 1 +2018, 7, 1, 14, spa, rus, 40, yellow, spa, 3 +2018, 7, 1, 14, spa, rus, 54, yellow, rus, 3 +2018, 7, 1, 14, spa, rus, 71, yellow, rus, 11 +2018, 7, 1, 14, spa, rus, 120, penalty, spa, 6, 1 +2018, 7, 1, 14, spa, rus, 121, penalty, rus, 10, 1 +2018, 7, 1, 14, spa, rus, 122, penalty, spa, 3, 1 +2018, 7, 1, 14, spa, rus, 123, penalty, rus, 4, 1 +2018, 7, 1, 14, spa, rus, 124, penalty, spa, 8, 0 +2018, 7, 1, 14, spa, rus, 125, penalty, rus, 17, 1 +2018, 7, 1, 14, spa, rus, 126, penalty, spa, 15, 1 +2018, 7, 1, 14, spa, rus, 127, penalty, rus, 6, 1 +2018, 7, 1, 14, spa, rus, 128, penalty, spa, 17, 0 +2018, 7, 1, 14, spa, rus, 129, ft, 1.3, 1.4 + + +2018, 7, 1, 18, cro, den, 0, ko, 0, 0 +2018, 7, 1, 18, cro, den, 1, goal, den, 13 +2018, 7, 1, 18, cro, den, 4, goal, cro, 17 +2018, 7, 1, 18, cro, den, 45, ht, 1, 1 +2018, 7, 1, 18, cro, den, 115, yellow, den, 13 +2018, 7, 1, 18, cro, den, 120, penalty, den, 10, 0 +2018, 7, 1, 18, cro, den, 121, penalty, cro, 19, 0 +2018, 7, 1, 18, cro, den, 122, penalty, den, 4, 1 +2018, 7, 1, 18, cro, den, 123, penalty, cro, 9, 1 +2018, 7, 1, 18, cro, den, 124, penalty, den, 2, 1 +2018, 7, 1, 18, cro, den, 125, penalty, cro, 10, 1 +2018, 7, 1, 18, cro, den, 126, penalty, den, 19, 0 +2018, 7, 1, 18, cro, den, 127, penalty, cro, 22, 0 +2018, 7, 1, 18, cro, den, 128, penalty, den, 9, 0 +2018, 7, 1, 18, cro, den, 129, penalty, cro, 7, 1 +2018, 7, 1, 18, cro, den, 130, ft, 1.3, 1.2 + +2018, 7, 2, 14, bra, mex, 0, ko, 0, 0 +2018, 7, 2, 14, bra, mex, 38, yellow, mex, 21 +2018, 7, 2, 14, bra, mex, 43, yellow, bra, 6 +2018, 7, 2, 14, bra, mex, 45, ht, 0, 0 +2018, 7, 2, 14, bra, mex, 50, goal, bra, 10 +2018, 7, 2, 14, bra, mex, 54, yellow, mex, 16 +2018, 7, 2, 14, bra, mex, 59, yellow, bra, 5 +2018, 7, 2, 14, bra, mex, 77, yellow, mex, 3 +2018, 7, 2, 14, bra, mex, 88, goal, bra, 20 +2018, 7, 2, 14, bra, mex, 92, yellow, mex, 18 +2018, 7, 2, 14, bra, mex, 97, ft, 2, 0 + +2018, 7, 2, 18, bel, jap, 0, ko, 0, 0 +2018, 7, 2, 18, bel, jap, 40, yellow, jap, 7 +2018, 7, 2, 18, bel, jap, 45, ht, 0, 0 +2018, 7, 2, 18, bel, jap, 47, goal, jap, 8 +2018, 7, 2, 18, bel, jap, 52, goal, jap, 14 +2018, 7, 2, 18, bel, jap, 69, goal, bel, 5 +2018, 7, 2, 18, bel, jap, 73, goal, bel, 8 +2018, 7, 2, 18, bel, jap, 92, goal, bel, 22 +2018, 7, 2, 18, bel, jap, 93, ft, 3, 2 + +2018, 7, 3, 14, swe, swi, 0, ko, 0, 0 +2018, 7, 3, 14, swe, swi, 31, yellow, swe, 2 +2018, 7, 3, 14, swe, swi, 45, ht, 0, 0 +2018, 7, 3, 14, swe, swi, 61, yellow, swi, 11 +2018, 7, 3, 14, swe, swi, 66, goal, swe, 10 +2018, 7, 3, 14, swe, swi, 68, yellow, swi, 10 +2018, 7, 3, 14, swe, swi, 94, red, swi, 6 +2018, 7, 3, 14, swe, swi, 96, ft, 1, 0 + +2018, 7, 3, 18, col, eng, 0, ko, 0, 0 +2018, 7, 3, 18, col, eng, 41, yellow, col, 5 +2018, 7, 3, 18, col, eng, 45, ht, 0, 0 +2018, 7, 3, 18, col, eng, 57, goal, eng, 9 +2018, 7, 3, 18, col, eng, 93, goal, col, 13 + +2018, 7, 3, 18, col, eng, 120, penalty, col, 9, 1 +2018, 7, 3, 18, col, eng, 121, penalty, eng, 9, 1 +2018, 7, 3, 18, col, eng, 122, penalty, col, 7, 1 +2018, 7, 3, 18, col, eng, 123, penalty, eng, 10, 1 +2018, 7, 3, 18, col, eng, 124, penalty, col, 14, 1 +2018, 7, 3, 18, col, eng, 125, penalty, eng, 8, 0 +2018, 7, 3, 18, col, eng, 126, penalty, col, 15, 0 +2018, 7, 3, 18, col, eng, 127, penalty, eng, 12, 1 +2018, 7, 3, 18, col, eng, 128, penalty, col, 7, 0 +2018, 7, 3, 18, col, eng, 127, penalty, eng, 4, 1 +2018, 7, 3, 18, col, eng, 130, ft, 1, 1 + +2018, 7, 6, 14, urg, fra, 0, ko, 0, 0 +2018, 7, 6, 14, urg, fra, 33, yellow, fra, 21 +2018, 7, 6, 14, urg, fra, 38, yellow, urg, 6 +2018, 7, 6, 14, urg, fra, 40, goal, fra, 4 +2018, 7, 6, 14, urg, fra, 45, ht, 0, 1 +2018, 7, 6, 14, urg, fra, 61, goal, fra, 7 +2018, 7, 6, 14, urg, fra, 69, yellow, fra, 10 +2018, 7, 6, 14, urg, fra, 69, yellow, urg, 7 +2018, 7, 6, 14, urg, fra, 90, ft, 0, 2 + + +2018, 7, 6, 18, bra, bel, 0, ko, 0, 0 +2018, 7, 6, 18, bra, bel, 13, goal, bel, 107 +2018, 7, 6, 18, bra, bel, 31, goal, bel, 7 +2018, 7, 6, 18, bra, bel, 45, ht, 0, 2 +2018, 7, 6, 18, bra, bel, 47, yellow, bel, 2 +2018, 7, 6, 18, bra, bel, 71, yellow, bel, 15 +2018, 7, 6, 18, bra, bel, 75, goal, bra, 8 +2018, 7, 6, 18, bra, bel, 90, ft, 1, 2 + +2018, 7, 7, 14, swe, eng, 0, ko, 0, 0 +2018, 7, 7, 14, swe, eng, 31, goal, eng, 6 +2018, 7, 7, 14, swe, eng, 45, ht, 0, 1 +2018, 7, 7, 14, swe, eng, 58, goal, eng, 20 +2018, 7, 7, 14, swe, eng, 87, yellow, eng, 6 +2018, 7, 7, 14, swe, eng, 87, yellow, swe, 11 +2018, 7, 7, 14, swe, eng, 94, yellow, swe, 7 +2018, 7, 7, 14, swe, eng, 96, ft, 0, 2 + +2018, 7, 7, 18, rus, cro, 0, ko, 0, 0 +2018, 7, 7, 18, rus, cro, 31, goal, rus, 6 +2018, 7, 7, 18, rus, cro, 35, yellow, cro, 6 +2018, 7, 7, 18, rus, cro, 38, yellow, cro, 3 +2018, 7, 7, 18, rus, cro, 39, goal, cro, 9 +2018, 7, 7, 18, rus, cro, 45, ht, 1, 1 +2018, 7, 7, 18, rus, cro, 100, goal, cro, 21 +2018, 7, 7, 18, rus, cro, 102, yellow, cro, 21 +2018, 7, 7, 18, rus, cro, 114, yellow, rus, 22 +2018, 7, 7, 18, rus, cro, 115, goal, rus, 2 +2018, 7, 7, 18, rus, cro, 120, penalty, rus, 10, 0 +2018, 7, 7, 18, rus, cro, 121, penalty, cro, 11, 1 +2018, 7, 7, 18, rus, cro, 122, penalty, rus, 9, 1 +2018, 7, 7, 18, rus, cro, 123, penalty, cro, 8, 0 +2018, 7, 7, 18, rus, cro, 124, penalty, rus, 2, 0 +2018, 7, 7, 18, rus, cro, 125, penalty, cro, 10, 1 +2018, 7, 7, 18, rus, cro, 126, penalty, rus, 4, 1 +2018, 7, 7, 18, rus, cro, 127, penalty, cro, 21, 1 +2018, 7, 7, 18, rus, cro, 128, penalty, rus, 7, 1 +2018, 7, 7, 18, rus, cro, 129, penalty, cro, 7, 1 +2018, 7, 7, 18, rus, cro, 130, ft, 1, 1 + +2018, 7, 10, 18, fra, bel, 0, ko, 0, 0 +2018, 7, 10, 18, fra, bel, 45, ht, 0, 0 +2018, 7, 10, 18, fra, bel, 51, goal, fra, 5 +2018, 7, 10, 18, fra, bel, 63, yellow, bel, 10 +2018, 7, 10, 18, fra, bel, 71, yellow, fra, 2 +2018, 7, 10, 18, fra, bel, 87, yellow, fra, 13 +2018, 7, 10, 18, fra, bel, 92, yellow, fra, 10 +2018, 7, 10, 18, fra, bel, 94, yellow, bel, 5 +2018, 7, 10, 18, fra, bel, 97, ft, 1, 0 + +2018, 7, 11, 18, cro, eng, 0, ko, 0, 0 +2018, 7, 11, 18, cro, eng, 5, goal, eng, 12 +2018, 7, 11, 18, cro, eng, 45, ht, 0, 1 +2018, 7, 11, 18, cro, eng, 47, yellow, cro, 7 +2018, 7, 11, 18, cro, eng, 54, yellow, eng, 2 +2018, 7, 11, 18, cro, eng, 68, goal, cro, 4 +2018, 7, 11, 18, cro, eng, 109, goal, cro, 17 +2018, 7, 11, 18, cro, eng, 120, ft, 2, 1 + +2018, 7, 14, 14, bel, eng, 0, ko, 0, 0 +2018, 7, 14, 14, bel, eng, 4, goal, bel, 5 +2018, 7, 14, 14, bel, eng, 45, ht, 1, 0 +2018, 7, 14, 14, bel, eng, 52, yellow, eng, 5 +2018, 7, 14, 14, bel, eng, 76, yellow, eng, 6 +2018, 7, 14, 14, bel, eng, 82, goal, bel, 10 +2018, 7, 14, 14, bel, eng, 93, yellow, bel, 6 +2018, 7, 14, 14, bel, eng, 94, ft, 2, 0 + +2018, 7, 15, 15, fra, cro, 0, ko, 0, 0 +2018, 7, 15, 15, fra, cro, 18, goal, fra, 117 +2018, 7, 15, 15, fra, cro, 27, yellow, fra, 13 +2018, 7, 15, 15, fra, cro, 28, goal, cro, 4 +2018, 7, 15, 15, fra, cro, 38, goal, fra, 7 +2018, 7, 15, 15, fra, cro, 41, yellow, fra, 21 +2018, 7, 15, 15, fra, cro, 45, ht, 2, 1 +2018, 7, 15, 15, fra, cro, 59, goal, fra, 6 +2018, 7, 15, 15, fra, cro, 65, goal, fra, 10 +2018, 7, 15, 15, fra, cro, 69, goal, cro, 17 +2018, 7, 15, 15, fra, cro, 92, yellow, cro, 2 +2018, 7, 15, 15, fra, cro, 96, ft, 4, 2 diff --git a/karmapi/wc/events.py b/karmapi/wc/events.py new file mode 100644 index 0000000..42d34a7 --- /dev/null +++ b/karmapi/wc/events.py @@ -0,0 +1,117 @@ +import curio + +class GameEvent: + + def __init__(self, when=None, game=None, jsf=None): + + self.when = when + self.game = game + self.jsf = jsf + self.start_evt = curio.Event() + + async def start(self): + + # want to wait appropriate time, for now just 1 + delay = self.jsf.warp(self.when) + try: + await curio.timeout_after(delay, self.start_evt.wait) + except curio.TaskTimeout: + pass + + await self.run() + + async def run(self): + + print('ruunning: ', self.when, self.game) + + + def __str__(self): + + return 'GAMEEVENT ' + str(self.when) + +class CheckPoint(GameEvent): + + async def run(self): + + print('check point: ', self.when, self.game) + + await self.jsf.check_point() + + def __str__(self): + + return 'CHECK POINT ' + str(self.when) + + + +class TeamEvent(GameEvent): + """ An event that involves one team in the game """ + + def __init__(self, team, who=None, when=None, game=None, og=False, **kwargs): + + super().__init__(when, game, **kwargs) + + self.team = team + self.who = who + self.og = og + +class Goal(TeamEvent): + + async def run(self): + + print('goal', self.team, self.when, self.who, self.game, self.og) + # this sort of seems weird + await self.game.goal(self.team, self.who, self.when) + + +class Yellow(TeamEvent): + + async def run(self): + + print('yellow', self.team, self.when, self.who, self.game, self.og) + # this sort of seems weird + await self.game.yellow(self.team, self.who, self.when) + + +class KickOff(GameEvent): + + async def run(self): + + print('ko', self.when, self.game, 'KICK OFF') + await self.game.kick_off(self.jsf) + +class HalfTime(GameEvent): + + async def run(self): + + print(self.when, self.game, 'HALF TIME') + await self.game.half_time() + +class FullTime(GameEvent): + + async def run(self): + + print(self.when, self.game, 'FULL TIME') + await self.game.full_time() + + self.jsf.apres_match(self.game) + + + +class Penalty(Goal): + """ Penalty in a shoot out + + which: which penalty: 1, 2, 3 etc + """ + def __init__(self, team, who=None, when=None, game=None, score=False, **kwargs): + + super().__init__(team, who=who, when=when, game=game, **kwargs) + + print('PEN', self.when, team, score) + + self.score = score + self.penalty = True + + async def run(self): + + await self.game.penalty(self) + diff --git a/karmapi/wc/game.py b/karmapi/wc/game.py new file mode 100644 index 0000000..24585f3 --- /dev/null +++ b/karmapi/wc/game.py @@ -0,0 +1,361 @@ +import calendar +from datetime import datetime, timedelta +from random import random, randint + +from .events import Penalty + +class Game: + + NUMBER = 1 + + def __init__(self, a, b, when, where=None, ascore=None, bscore=None): + + self.a = a + self.b = b + self.when = when + self.where = where + self.label = '' + + # ignore ascore/bscore, let events do the work + self.ascore = None + self.bscore = None + + self.apen = [] + self.bpen = [] + + self.minute = 0 + + # flag if score was simulated - do this if game is in the future + self.simulated = self.when > datetime.utcnow() + if self.simulated: + print('SIMULATED', self.simulated, self) + + # this has to go away.. + self.number = Game.NUMBER + Game.NUMBER += 1 + + + def __hash__(self): + + return id(self) + + def reset(self): + """ Reset score if it was random """ + self.ascore = self.bscore = 0 + + self.apen = [] + self.bpen = [] + + self.minute = 0 + + def __str__(self): + + aname = bname = '---' + if self.a: + aname = self.a.name + + if self.b: + bname= self.b.name + + msg = ' '. join(( + str(self.label), + aname, + 'v', + bname, + self.day_name(), + str(self.when), + str(self.where))) + + if self.ascore is not None: + msg += ' ' + '-'.join((str(self.ascore), str(self.bscore))) + + return msg + + def day_name(self): + + return calendar.day_name[self.when.weekday()] + + def __eq__(self, other): + + return self.number == other.number + + def __ne__(self, other): + + return self.number != other.number + + def __gt__(self, other): + + return (self.when, self.number) > (other.when, other.number) + + def __le__(self, other): + + return (self.when, self.number) <= (other.when, other.number) + + def __ge__(self, other): + + return (self.when, self.number) >= (other.when, other.number) + + async def kick_off(self, jsf): + """ Game has kicked off """ + self.reset() + + if not self.simulated: + return + + print('SIMULATING', self) + + minutes = 45 + randint(0, 7) + + await self.half(minutes) + + await self.half_time() + + await self.second_half() + + await self.full_time() + + ko = not self.is_group() + + # knockout match, are we done? + if ko and self.ascore == self.bscore: + + await self.extra_time() + await self.extra_half_time() + await self.extra_full_time() + + if self.ascore == self.bscore: + await self.penalties() + + print('APRES!!!') + jsf.apres_match(self) + + def is_group(self): + + return hasattr(self, 'group') + + async def half(self, minutes): + """ Run a half """ + + for minute in range(minutes): + await self.run_minute() + + + async def run_minute(self): + + yellow_per_minute = 1 / 30 + red_per_minute = 1 / 150 + goals_per_minute = 1 / 30 + + # score a goal? + if random() < goals_per_minute: + # who scored + if random() <= 0.5: + self.ascore += 1 + else: + self.bscore += 1 + + await self.flash(" %dm" % self.minute, fill='green') + + if random() < yellow_per_minute: + # yellow card? + pass + + if random() < red_per_minute: + # red card? + pass + + self.minute += 1 + + return self.ascore, self.bscore + + async def half_time(self): + + await self.flash(fill='blue', tag='HT') + + async def second_half(self): + minutes = 45 + randint(0, 7) + await self.half(minutes) + + async def full_time(self): + + await self.flash(fill='yellow', tag='FT') + + async def extra_time(self): + minutes = 15 + randint(0, 3) + await self.half(minutes) + + async def extra_half_time(self): + pass + + async def extra_full_time(self): + minutes = 15 + randint(0, 3) + await self.half(minutes) + + async def penalties(self): + """ Don't miss this """ + first, second = self.a, self.b + + if random() < 0.5: + first, second = second, first + + total = 0 + done = False + while not done: + done = self._penalty(first) + first, second = second, first + + def _penalty(self, team): + """ Simulate a penalty """ + which = len(self.apen) + len(self.bpen) + + score = False + if random() < 0.8: + score = True + + pen = Penalty(team, score=score, game=self, + when=self.when + timedelta(minutes=120 + which), + who = randint(1, 23)) + + if team is self.a: + self.apen.append(pen) + else: + self.bpen.append(pen) + + return self.all_over() + + async def penalty(self, pen): + + if pen.team is self.a: + self.apen.append(pen) + else: + self.bpen.append(pen) + + def pens_score(self): + """ score in penalties """ + apens = [x for x in self.apen if x.score] + bpens = [x for x in self.bpen if x.score] + + return len(apens), len(bpens) + + + def all_over(self): + """ Are the pens done? """ + + a, b = self.pens_score() + + if a == b: + return False + + aa = len(self.apen) + bb = len(self.bpen) + + which = aa + bb + + if which <= 10: + aleft = 5 - aa + bleft = 5 - bb + + else: + aleft = bleft = 0 + + if aa < bb: + aleft = 1 + if bb < aa: + bleft = 1 + + if b > a + aleft: + return True + + if a > b + bleft: + return True + + async def goal(self, team, who=None, when=None): + + if team is self.a: + self.ascore += 1 + else: + self.bscore += 1 + + minute = int((when - self.when).total_seconds() / 60) + await self.flash(" %dm" % minute, fill='green') + + + async def yellow(self, team, who=None, when=None): + + if team is self.a: + self.a.yellow += 1 + else: + self.b.yellow += 1 + + minute = int((when - self.when).total_seconds() / 60) + await self.flash(" %dm" % minute, fill='purple', card='yellow') + + + async def red(self, team, who=None, when=None): + pass + + async def sub(self, team, off=None, on=None, when=None): + pass + + def apres_match(self): + + a = self.a + b = self.b + + a.goals += self.ascore + b.goals += self.bscore + + a.against += self.bscore + b.against += self.ascore + + if self.is_group(): + + if self.ascore > self.bscore: + a.points += 3 + + elif self.bscore > self.ascore: + b.points += 3 + + else: + a.points += 1 + b.points += 1 + + async def flash(self, tag='', fill='red', card=False): + + a = self.a + b = self.b + ascore = self.ascore + bscore = self.bscore + if self.apen: + aa, bb = self.pens_score() + ascore = "%d(%d)" % (self.ascore, aa) + bscore = "%d(%d)" % (self.bscore, bb) + + msg = a.name + ' ' + str(ascore) + ' ' + str(bscore) + ' ' + b.name + msg += ' ' + tag + + when = self.when + timedelta(minutes=self.minute) + await self.events.put(dict(where=self.where, msg=msg, yoff=-90, + when=when, fill=fill, card=card)) + + def winner(self): + """ Return winning team """ + if self.ascore > self.bscore: + return self.a + elif self.bscore > self.ascore: + return self.b + + # penalties + aa, bb = self.pens_score() + if aa > bb: + return self.a + + return self.b + + def loser(self): + + win = self.winner() + if win == self.a: + return self.b + + return self.a diff --git a/karmapi/wc/group.py b/karmapi/wc/group.py new file mode 100644 index 0000000..7459b73 --- /dev/null +++ b/karmapi/wc/group.py @@ -0,0 +1,58 @@ +class Group: + + def __init__(self, teams=None, games=None): + + self.teams = teams + self.games = games or [] + self.played = 0 + + def winner(self): + """ Pick a winner """ + return self.get_table()[0] + + def second(self): + """ Pick a second """ + return self.get_table()[1] + + def is_finished(self): + + size = len(self.teams) + return self.played == (size * (size - 1)) / 2 + + def __str__(self): + + return str(self.teams, self.games) + + def reset(self): + """ reset for a new run """ + for game in self.games: + game.reset() + + for team in self.teams: + team.reset() + + self.played = 0 + + + def table(self): + """ Show the group table """ + teams = self.get_table() + + for team in teams: + print(team) + print(team.statto) + + + def get_table(self): + """ Return teams sorted per table """ + teams = list(self.teams) + + teams = sorted(teams, key=self.tablesort) + + return list(reversed(teams)) + + def tablesort(self, key): + """ Order teams """ + return key.points, key.goals - key.against, key.goals, -1 * key.yellow + + diff --git a/karmapi/wc/jsf.py b/karmapi/wc/jsf.py new file mode 100644 index 0000000..09a4cbe --- /dev/null +++ b/karmapi/wc/jsf.py @@ -0,0 +1,423 @@ +""" Jeus Sans Frontieres + +""" +from datetime import datetime, timedelta + +import curio + +from .events import * +from .game import Game + +class JeuxSansFrontieres: + """ The knockout stage. + + Winners and seconds from group stage come through into a + last 16 grid that looks something like this: + + + wa rb + wc rd w w w w w w W r + + we rf w w + wg rh + + wb ra w w w w s s T f + wd rc + + wf re w w + wh rg + + with abcdefgh + and badcfehg + + + So lets set it up so we can do: + + * simulate groups + * do draw for knockout stage + * get games for final stage + + """ + def __init__(self, groups, places=None, dates=None, + when=None, game_events=None, name2team=None): + self.groups = groups + + # places and dates for knockout stage + self.places = places + self.dates = dates + self.name2team = name2team + + self.when = when or datetime(2018, 6, 14) + self.start = self.when + + self.start_time = datetime.utcnow() + + # factor to warp time by + self.timewarp = 1 / (30 * 24 * 60 * 60) + self.sleep = 0.01 + + self.knockout = [] + self.winners = {} + self.seconds = {} + + self.events = curio.UniversalQueue() + + self.game_events = game_events or [] + + self.tasks = [] + + def warp(self, when): + """ convert when to a delay in seconds """ + start = self.start + seconds = (when - start).total_seconds() + + # how far are we in? + elapsed = (datetime.utcnow() - self.start_time).total_seconds() + + warp = (seconds * self.timewarp) - elapsed + return warp + + def iwarp(self, ticks): + """ convert tick time to a datetime """ + return self.start + timedelta(seconds=ticks / self.timewarp) + + + def match_game(self, key): + + when, ateam, bteam = key + + # build game lookup + gl = {} + for game in self.generate_games(): + game.events = self.events + + aname = bname = '-' + if game.a: + aname = game.a.name.lower() + bname = game.b.name.lower() + + gkey = (game.when, aname, bname) + if gkey in gl: + raise ValueError("Duplicate game key %s" % str(key)) + gl[gkey] = game + + # Now find the game for this key + game = gl.get(key) + + if game is None: + game = gl.get((key[0], '-','-')) + + return game + + + async def dispatch_events(self): + """ Dispatch events to the appropriate game """ + + if not self.game_events: + return + + knockout = [] + etasks = [] + for event in self.game_events: + + kotime, when, ateam, bteam, what, extras = event + + key = kotime, ateam, bteam + + game = self.match_game(key) + + if not game: + knockout.append((key, event)) + continue + + # turn team names into teams + ateam = self.name2team(ateam) + bteam = self.name2team(bteam) + + # got the game. now create an appropriate event + if what == 'goal': + team, who, og = self.whodunnit(extras) + event = Goal(team, who, when, game, og, jsf=self) + task = await curio.spawn(event.start) + etasks.append(task) + + elif what == 'yellow': + team, who, og = self.whodunnit(extras) + event = Yellow(team, who, when, game, jsf=self) + task = await curio.spawn(event.start) + etasks.append(task) + + + elif what == 'ko': + event = KickOff(when, game, jsf=self) + task = await curio.spawn(event.start) + etasks.append(task) + + elif what == 'penalty': + team, who, og = self.whodunnit(extras) + + score = int(extras[-1]) != 0 + + event = Penalty(team, who, when, game, score, jsf=self) + task = await curio.spawn(event.start) + etasks.append(task) + + elif what == 'ft': + + event = FullTime(when, game, jsf=self) + task = await curio.spawn(event.start) + etasks.append(task) + + else: + # just print out the event info + print('*****', when, ateam, bteam, what, extras) + + self.tasks += etasks + + + async def load_group_games(self): + """ Put the group games into the game queue """ + + kos = [] + + for label, group in self.groups.items(): + group.name = label + group.reset() + for game in group.games: + game.group = group + game.label = label.upper() + + game.a.games.append(game) + game.b.games.append(game) + + if game.simulated: + kos.append(KickOff(game.when, game, jsf=self)) + + self.its_a_knockout() + + await self.dispatch_events() + + for game in self.knockout: + game.events = self.events + if game.simulated: + kos.append(KickOff(game.when, game, jsf=self)) + + kotasks = [] + for ko in kos: + task = await curio.spawn(ko.start) + kotasks.append(task) + + self.tasks += kotasks + + + def its_a_knockout(self): + """ Set up knockout stage """ + self.knockout = [] + Game.NUMBER = 49 + + places = self.places or (['???'] * len(games)) + dates = self.dates or [datetime.today()] * len(games) + + for where, when in zip(places, dates): + self.knockout.append(Game(None, None, when, where)) + + groups = self.groups + key = sorted(groups.keys()) + + key = list(key) + + key2 = '' + for x in range(0, len(key), 2): + key2 += key[x+1] + key[x] + + games = [] + + ix = 0 + for gps in key, key2: + for x in range(0, len(key), 2): + + a = gps[x] + b = gps[x+1] + + self.winners[a] = self.knockout[ix], 'a' + self.seconds[b] = self.knockout[ix], 'b' + ix += 1 + + # now do knockout stage + ko = self.knockout + for ix, game in enumerate(ko[:8]): + gix = 8 + int(ix / 2) + if ix % 2 == 0: + self.winners[game.number] = self.knockout[gix], 'a' + else: + self.winners[game.number] = self.knockout[gix], 'b' + + for ix, game in enumerate(ko[8:12]): + gix = 12 + int(ix / 2) + if ix % 2 == 0: + self.winners[game.number] = self.knockout[gix], 'a' + else: + self.winners[game.number] = self.knockout[gix], 'b' + + for ix, game in enumerate(ko[12:14]): + if ix % 2 == 0: + self.winners[game.number] = self.knockout[14], 'a' + self.seconds[game.number] = self.knockout[15], 'b' + else: + self.winners[game.number] = self.knockout[14], 'b' + self.seconds[game.number] = self.knockout[15], 'a' + + + + def generate_teams(self): + """ Generate teams """ + for group in self.groups.values(): + for team in group.teams: + yield team + + def generate_games(self): + """ Generate games """ + games = set() + + for team in self.generate_teams(): + for game in team.games: + games.add(game) + + games.update(self.knockout) + + for game in sorted(games): + yield game + + + def apres_match(self, game): + """ Deal with updating of knockout stage """ + + game.apres_match() + + if game.number == 64: + print('third place:', game.winner()) + return + if game.number == 63: + print('Winner:', game.winner()) + return + + + if game.is_group(): + group = game.group + group.played += 1 + + game.a.played += 1 + game.b.played += 1 + + key = game.label.lower() + kgame, label = self.winners[key] + wteam = group.winner() + setattr(kgame, label, wteam) + if group.is_finished(): + wteam.games.append(kgame) + + kgame, label = self.seconds[key] + steam = group.second() + setattr(kgame, label, steam) + if group.is_finished(): + steam.games.append(kgame) + + for team in group.teams: + if team not in (wteam, steam): + print('out', team) + team.go_home() + + else: + kgame, label = self.winners[game.number] + wteam = game.winner() + + setattr(kgame, label, wteam) + print('knockout winner:', wteam, game, kgame) + wteam.games.append(kgame) + + if game.number in self.seconds: + kgame, label = self.seconds[game.number] + lteam = game.loser() + setattr(kgame, label, lteam) + lteam.games.append(kgame) + else: + game.loser().go_home() + + + async def reset(self): + """ Reset things to start again """ + for task in self.tasks: + await task.cancel() + + self.now = self.start + self.start_time = datetime.utcnow() + Game.NUMBER -= len(self.knockout) + + self.knockout = [] + self.winners = {} + self.seconds = {} + + await self.load_group_games() + + async def run(self): + """ Run the games + + run the group stage + + generate knockout bracket + + run knockout + + collect stats + + reset + + AND/OR: + + Generate events. + """ + print('jsf: run start') + await self.reset() + + if self.dump: + for game in self.generate_games(): + dump(game, self.dump) + + self.dump.close() + sys.exit(0) + + return + + + + def whodunnit(self, extras): + + team = self.name2team(extras[0]) + + who = int(extras[1]) + og = False + if who > 23: + og = True + who -= 100 + + return team, who, og + + +def dump(game, out): + + now = datetime.utcnow() + print('dumping') + when = game.when + + if when < now: + return + + print(when.year, when.month, when.day, when.hour, sep=', ', end=', ', file=out) + print(game.a, game.b, 0, 'ko', 0, 0, sep=', ', file=out) + + print(when.year, when.month, when.day, when.hour, sep=', ', end=', ', file=out) + print(game.a, game.b, 45, 'ht', 0, 0, sep=', ', file=out) + + print(when.year, when.month, when.day, when.hour, sep=', ', end=', ', file=out) + print(game.a, game.b, 90, 'ft', 0, 0, sep=', ', file=out) + diff --git a/karmapi/wc/mexwave.py b/karmapi/wc/mexwave.py new file mode 100644 index 0000000..d4ed367 --- /dev/null +++ b/karmapi/wc/mexwave.py @@ -0,0 +1,468 @@ + +from collections import defaultdict +from datetime import datetime, timedelta +import csv + +import curio + + + +from karmapi import pigfarm, beanstalk + +# add a PI Gui? +class MexicanWaves(pigfarm.Yard): + + def __init__(self, parent, jsf=None, venues=None, + back_image=None, + dump=None, events=None): + """ Initialise the thing """ + + super().__init__(parent) + + self.jsf = jsf + self.jsf.dump = dump + self.back_image = back_image + + if events: + events = list(parse_events(events)) + + self.jsf.game_events = events + + self.messages = [] + + self.start_time = datetime.utcnow() + + # teleprinter location + self.teleprint_xxyy = .85, .425 + self.teleprints = [] + + self.scan_venues(venues) + + self.add_event_map('r', self.reset) + self.add_event_map('S', self.slower) + self.add_event_map('M', self.faster) + self.add_event_map('m', self.toggle_show_games) + self.add_event_map('g', self.toggle_show_groups) + self.add_event_map('t', self.toggle_show_teams) + self.add_event_map('j', self.previous_group) + self.add_event_map('k', self.next_group) + #self.add_event_map(' ', self.toggle_pause) + + self.game_view = False + self.team_view = False + self.group_view = False + self.which_group = 0 + + + async def slower(self): + """ Go through time more slowly """ + self.jsf.timewarp *= 2 + + async def faster(self): + """ Go through time more quickly """ + self.jsf.timewarp /= 2 + + async def toggle_show_games(self): + """ Toggle matches view """ + self.game_view = not self.game_view + + async def toggle_show_teams(self): + """ Toggle teams view """ + self.game_view = not self.team_view + + async def toggle_show_groups(self): + """ Toggle groups view """ + self.group_view = not self.group_view + + async def next_group(self): + """ Go to next group """ + self.which_group += 1 + + if self.which_group == len(self.jsf.groups): + self.which_group = 0 + + async def previous_group(self): + """ Go to previous group """ + self.which_group -= 1 + + if self.which_group < 0: + self.which_group += len(self.jsf.groups) + + + def scan_venues(self, venues): + """ Set the lat lon bounds for the canvas """ + self.places = places = list(venues.values()) + + minlat = min(x.lat for x in places) + maxlat = max(x.lat for x in places) + + minlon = min(x.lon for x in places) + maxlon = max(x.lon for x in places) + + height = maxlat - minlat + width = maxlon - minlon + + wpad = width / 8 + hpad = height / 8 + + # need to add padding to make grid + self.xx = minlon - wpad + self.yy = minlat - hpad + + self.xscale = width + (2 * wpad) + self.yscale = height + (2 * hpad) + + + def latlon2xy(self, place): + """ Convert lat lon to yard coordinates """ + lat = place.lat + lon = place.lon + + xx = int(((lon - self.xx) / self.xscale) * self.width) + yy = self.height - int(((lat - self.yy) / self.yscale) * self.height) + + return xx, yy + + + async def step_balls(self): + """ do something here """ + + for place in self.places: + size = 5 + self.ball(place, fill='red', size=5) + + self.message(place.name, place, yoff=-20, fill='yellow') + + locations = defaultdict(list) + + for team in self.jsf.generate_teams(): + + wtit = self.what_time_is_it() + team.where(wtit) + xx, yy = self.latlon2xy(team) + + locations[(xx, yy)].append(team) + + # Now draw the things + for key in locations.keys(): + xx, yy = key + yoff = 30 + for team in locations[key]: + self.message(team.name, team, yoff=yoff, fill='green') + + yoff += 30 + + self.show_score_flashes() + + if self.game_view: + self.show_games() + + if self.team_view: + self.show_teams() + + if self.group_view: + self.show_groups() + + if not self.group_view and not self.team_view and not self.game_view: + self.show_tables() + + self.show_knockout() + + + def what_time_is_it(self): + + elapsed = (datetime.utcnow() - self.start_time).total_seconds() + + return self.jsf.iwarp(elapsed) + + + def draw(self): + + import time + self.beanstalk.create_time = time.time() + + self.beanstalk.draw(self.canvas, self.width, self.height, 'red') + + async def reset(self): + """ Reset timer """ + self.start_time = datetime.utcnow() + + self.messages = [] + self.teleprints =[] + + await self.jsf.reset() + #await self.jsf.load_group_games() + + + async def score_flash(self): + + while True: + info = await self.jsf.events.get() + + self.messages.append(info) + + self.teleprint(**info) + + + def show_score_flashes(self): + """ Show the score flashes """ + xx, yy = self.teleprint_xxyy + + for msg, fill, card in self.teleprints: + + self.message(msg=msg, fill=fill, card=card, xx=xx, yy=yy) + xx, yy = xx, yy + .025 + + # Now do messages + keep = {} + for info in reversed(self.messages): + when = info['when'] + + if self.what_time_is_it() < when + timedelta(hours=48): + pos = self.layout(**info) + if pos in keep: + continue + keep[pos] = info + + self.message(**info) + + self.messages = list(keep.values()) + + + def teleprint(self, msg=None, fill='orange', card=None, **kwargs): + """ teleprinter messages """ + self.teleprints.append((msg, fill, card)) + + if len(self.teleprints) > 10: + del self.teleprints[0] + + def layout(self, where=None, xx=None, yy=None, **kwargs): + """ layout for location """ + if xx is None or yy is None: + xx, yy = self.latlon2xy(where) + else: + xx *= self.width + yy *= self.height + + return xx, yy + + + def message(self, msg=None, where=None, fill='red', + card=False, + size=5, xoff=0, yoff=0, + xx=None, yy=None, **kwargs): + """ Message from a place """ + + xx, yy = self.layout(where, xx, yy) + + self.canvas.create_text((xx + xoff, yy + yoff), text=msg, fill=fill) + + if card: + #print("CARD", card, msg) + x = xx + xoff - 150 + y = yy + yoff + self.canvas.create_rectangle(x, y, x + 10, y + 10, fill=card) + + + def show_tables(self): + + position = [ + [.10, .1], + [.25, .1], + + [.10, .25], + [.25, .25], + + [.75, .75], + [.90, .75], + + [.75, .9], + [.90, .9], + ] + + for label, group in self.jsf.groups.items(): + + gindex = ord(label) - ord('a') + + xx, yy = position[gindex] + + for team in group.get_table()[::-1]: + self.message( + msg=team.statto(), + xx=xx, + yy=yy, + fill='cyan') + yy -= 0.025 + + def show_groups(self): + + xx = 0.6 + yy = 0.05 + + which = chr(self.which_group + ord('a')) + + group = self.jsf.groups[which] + + for game in group.games: + + self.message(msg=str(game), + xx=xx, yy=yy, fill='magenta') + + yy += 0.025 + + def show_teams(self): + + pass + + + def show_games(self): + + xx = 0.2 + yy = 0.05 + + for game in self.jsf.generate_games(): + self.message(msg=str(game), + xx=xx, yy=yy, fill='pink') + + yy += 0.025 + + def show_knockout(self): + + if not self.jsf.knockout: + return + xx = .1 + yy = .6 + yinc = 0.025 + for ix, game in enumerate(self.jsf.knockout): + aa = game.a or ' ' + bb = game.b or ' ' + + ascore = game.ascore + bscore = game.bscore + if ascore is None: ascore = '-' + if bscore is None: bscore = '-' + + elif ascore == bscore: + apen, bpen = game.pens_score() + ascore += apen / 10 + bscore += bpen / 10 + + self.message(msg="{} {} {} {}".format( + aa, ascore, bscore, bb), + xx=xx, yy=yy, fill='green') + + px = xx - 0.01 + dx = -0.005 + + for pens in game.apen, game.bpen: + for pix, pen in enumerate(pens): + if pen.score: + rog = 'green' + else: + rog = 'red' + + xp = px + (pix * dx) + self.ball(xx=xp, yy=yy + 0.025, fill=rog, size=3) + + px = xx + 0.01 + dx *= -1 + + yy += 0.05 + + if ix in [7, 11, 13]: + xx += .1 + yy = .6 + yinc *= 2 + + final = self.jsf.knockout[-2] + if final.ascore != None: + xx += 0.1 + yy = 0.6 + self.message(msg="{}".format( + final.winner().name), + xx=xx, yy=yy, + fill='gold') + + + + def ball(self, place=None, fill='red', size=5, xoff=0, yoff=0, + xx=None, yy=None, **kwargs): + """ Draw a filled circle at place """ + + xx, yy = self.layout(place, xx, yy) + + self.canvas.create_oval( + xx+xoff-size, + yy+yoff-size, + xx+xoff+size, yy+yoff+size, fill=fill) + + async def run(self): + """ Run the waves """ + print('running mexican wave') + + print('spawning jsf') + jsf = await curio.spawn(self.jsf.run) + + score_flashes = await curio.spawn(self.score_flash) + + self.set_background() + + self.beanstalk = beanstalk.BeanStalk() + self.beanstalk.xx = 0.5 + self.beanstalk.yy = 0.5 + self.beanstalk.x = '' + + while True: + self.canvas.delete('all') + + if self.back_image: + image = self.find_image(self.back_image) + if image: + image = self.load_image(image) + + image = image.resize((int(self.height), int(self.width))) + + self.beanstalk.image = image + + self.draw() + + # step balls + await self.step_balls() + + #self.jsf.now = self.when() + + # wait for event here. We want to repaint in a minute game time + await curio.sleep(self.sleep) + + +def parse_events(events, out=None): + + if out: + out = csv.writer(out) + + for ix, row in enumerate(csv.reader(events)): + + if out: + row = [x.strip() for x in row] + out.writerow(row) + continue + + if not row: + continue + + if row[0].startswith('#'): + continue + + year, month, day, hour = [int(x) for x in row[:4]] + + a, b = row[4], row[5] + + minute = int(row[6]) + what = row[7].strip().lower() + extras = [x.strip().lower() for x in row[8:]] + + kotime = datetime(year, month, day, hour, 0) + when = kotime + timedelta(minutes=minute) + + yield kotime, when, a.lower().strip(), b.lower().strip(), what, extras + diff --git a/karmapi/wc/place.py b/karmapi/wc/place.py new file mode 100644 index 0000000..8291e27 --- /dev/null +++ b/karmapi/wc/place.py @@ -0,0 +1,11 @@ + + +class Place: + + def __str__(self): + + return self.name + + def __repr__(self): + + return str(self) diff --git a/karmapi/wc/team.py b/karmapi/wc/team.py new file mode 100644 index 0000000..e7638ad --- /dev/null +++ b/karmapi/wc/team.py @@ -0,0 +1,154 @@ +from collections import defaultdict + +from .place import Place + + +squadsize = 23 +n = 32 + +class Team: + + def __init__(self, name=None, win=None): + """ Init the team with no name? """ + self.name = name + + # default location: North Pole + self.lat = 90 + self.lon = 0 + + self.win = win or 1 / n + self.home = False + + self.reset() + + + def reset(self): + + self.points = 0 + self.played = 0 + self.yellow = 0 + self.red = 0 + self.goals = 0 + self.against = 0 + self.home = None + + # Keep track of games played/to be played? + self.games = [] + + self.load_squad() + + def load_squad(self): + """ Numbers 1 to sqadsize """ + self.squad = defaultdict(int) + + for player in range(squadsize): + self.squad[player] = Player(player + 1) + + def where(self, when): + """ Where is the team? """ + + if self.home is not None: + self.lat, self.lon = self.home.lat, self.home.lon + return self.lat, self.lon + + last_game = None + next_game = None + for game in self.games: + if game.when < when: + last_game = game + else: + next_game = game + break + + if last_game is None and next_game is None: + # return a defualt? + return self.lat, self.lon + + # if one is missing, use the other + last_game = last_game or next_game + next_game = next_game or last_game + + # Interpolate based on time + self.lat, self.lon = warp(last_game, next_game, when) + + return self.lat, self.lon + + def go_home(self): + + self.home = NorthPole() + + def __str__(self): + + return self.name + + + def stats(self): + + return dict( + played = self.played, + points = self.points, + goals = self.goals, + against = self.against, + goal_delta = self.goals - self.against, + red = self.red, + yellow = self.yellow) + + def statto(self): + """ Return line of stats for the team """ + + stats = self.stats() + msg = "%s" % self.name + msg += " {played:4d}".format(**stats) + msg += " {points:4d} {goal_delta:4d}".format(**stats) + msg += " {goals:4d} {against:4d}".format(**stats) + + return msg + + +class NorthPole(Place): + """ Where teams go when out? """ + + name = 'North Pole' + lat = 90 + lon = 0 + + +class Player: + """ A player of class + + Tony Currie, Kyle Walker, Harry Maguire + """ + + def __init__(self, number): + + self.goals = [] + self.red = [] + self.yellow = [] + self.number = number + + +def warp(a, b, when): + """ Interpolate between a and b based on time """ + + delta_t = (b.when - a.when).total_seconds() + + if delta_t == 0: + return a.where.lat, a.where.lon + + delta_w = (when - a.when).total_seconds() + + frac = delta_w / delta_t + + aa = a.where + bb = b.where + + lat = aa.lat + lon = aa.lon + + lat += frac * (bb.lat - aa.lat) + lon += frac * (bb.lon - aa.lon) + + return lat, lon + + + diff --git a/karmapi/wc/wc.py b/karmapi/wc/wc.py new file mode 100644 index 0000000..f0d5665 --- /dev/null +++ b/karmapi/wc/wc.py @@ -0,0 +1,172 @@ +""" World Cup + +Over the years I've done a few world cup predict the scores things. + +There's another one coming so here we go. + +Eight groups of four. + +And six games per group. + +Will likely turn into a simulation of errors. + +Prior? probabilities for games.. aim it to predict first and second in each +group for now as those will be the ones that get there. + +Things to include maybe... factors for order games are played. + +Oh and stuff like what will be going on at home by June 2018. + +Russia are the hosts, and I understand have graciously offered to represent the +USA and Italy too, sorry you couldn't make the party. + +Seek Irish, Scots or English for advice on how to survive when your team is not +there. + +All times are UTC and subject to typos and other delights. + +The story so far. + +It's December 2017. World Cup finals draw in Russia is out. + +Italy and USA are already out. Sweden eliminated Italy and the USA story is more complex. + +On the Mueller advent calendar Michael Flynn pleaded guilty on the 1st. + +Picture wasn't clear on the 2nd. 3-4 maybe more faces? + +Back to the world cup. + +Group A. + +rus sau egy urg + + +OK.. back from the fixture lists. + +Order of games interesting and need to add places. Fair bit of moving around +in some groups. + +Some teams get to play after seeing the other game in their group in first two +rounds of games. + +As groups progress teams will be looking at what comes next, if they have a +couple of wins, or otherwise just how to get out of the group. + +Seeding has placed the teams with higher FIFA rankings with potentially less +travel complications, but then there are the fans back home and time zone +considerations. + +Now it is 2017 so there may be an obligatory block chain connection, but if so +it well be super low tech. + +And simulations. For now stuck deciding what to simulate.. oh and priors.. + +I think we may need some events here soon. + +Back to the coding. So rule 0: keep it under 1000 lines, bonus marks under +500. World cup rules, so you decide how to count. + +Subtracting docstrings there should be a lot less. And with luck sphinx will +magically turn the code into ok docs. + +rule 1: there is no rule one. It's the world cup, so breaking all the coding +rules. See also counting lines of code, world cup style. + +Or rather just writing what seems easiest at the time. + +There is a fair bit of going round in circles: check the commit log see git. + +Ok.. back to the football. + +The world cup mixes up 32 teams from around the world. The final draw mixes +everything up and there are some fascinating match ups. + +Simon Kuiper, football anthropologist?, wrote a fascinating book about matches +between countries, places that had been at war in the very recent past. Many +of the games covered were at world cups or big football federation finals. + +Others were just qualifying games. + +Sources: Wikipedia and scriblings on beer mats. + +Places coming along. + +Rostov-on-Don. Lots of twin towns, including Toronto. + +Some interesting games there too. + +545km to the south + +Simulations +=========== + +Run the code and you get a draw for the last 16. + +I am starting to simulate the first round games with 4 bottles in a pool. It's +like Paul the octobpus, but not quite so scientific. Or maybe it is? + +eng tun bel and pan played already. See Game's for results. + + +""" +import argparse +import curio + +from .jsf import JeuxSansFrontieres +from .mexwave import MexicanWaves + +# break with tradition and import * +# so if you can't fint it here, check wcYYYY +from .wc2018 import * + +from karmapi import pigfarm + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--nopig', action='store_true') + parser.add_argument('--back_image') + parser.add_argument('--dump') + parser.add_argument('--events') + parser.add_argument('--warp', type=float, default=1.0, + help="warp speed") + parser.add_argument('--outfile') + args = parser.parse_args() + + if args.nopig: + sys.exit() + + farm = pigfarm.PigFarm() + + from karmapi.mclock2 import GuidoClock + + xdump = args.dump + if xdump: + xdump = open(args.dump, 'w') + + if args.outfile: + args.outfile = open(args.outfile, 'w') + + if args.events: + args.events = open(args.events) + + #parse_events(args.events, args.outfile) + #sys.exit() + + jsf.timewarp *= args.warp + farm.add(GuidoClock) + farm.add(MexicanWaves, dict(jsf=jsf, + venues=places, + back_image=args.back_image, + events=args.events, + dump=xdump)) + + # add a random wc time warper? + curio.run(farm.run(), with_monitor=True) + + + +if __name__ == '__main__': + + main() diff --git a/karmapi/wc/wc2018.py b/karmapi/wc/wc2018.py new file mode 100644 index 0000000..b339fad --- /dev/null +++ b/karmapi/wc/wc2018.py @@ -0,0 +1,464 @@ +""" 2018 FIFA World Cup + +""" + +from datetime import datetime + +from .jsf import JeuxSansFrontieres +from .game import Game +from .group import Group +from .team import Team +from .place import Place + + +class Moscow(Place): + """ Final """ + + name = 'Moscow Luzhniki' + lat = 55 + (45 / 60) + lon = 37 + (37 / 60) + +class Spartak(Place): + """ Spartak Moscow """ + + name = 'Moscow Oktkrytiye' + lat = 57 + (49 / 60) + lon = 34 + (26 / 60) + + xlat = 55 + (49 / 60) + xlon = 37 + (26 / 60) + + +class StPetersberg(Place): + """ Place of many names """ + + name = 'St Petersberg' + lat = 59 + (58 / 60) + lon = 30 + (14 / 60) + +class Volgograd(Place): + """ Down south """ + + name = 'Volgograd' + lat = 48 + (45 / 60) + lon = 44 + (33 / 60) + +class Novgorod(Place): + """ Central """ + + name = 'Nizhny Novgorod' + lat = 56 + (20 / 60) + lon = 43 + (57 / 60) + +class Kaliningrad(Place): + """ North West port """ + + name = 'Kaliningrad' + lat = 54 + (42 / 60) + lon = 20 + (32 / 60) + +class RostovOnDon(Place): + """ Sheffield in Russia """ + name = "Rostov-on-Don" + lat = 47 + (13 / 60) + lon = 39 + (44 / 60) + +class Kazan(Place): + """ + + https://tools.wmflabs.org/geohack/geohack.php? + + pagename=Kazan_Arena& + + params=55_49_14.3_N_49_9_40.0_E_type:landmark """ + + name = 'Kazan' + lat = 55 + (49 / 60) + (14.3 / 3600) + lon = 49 + (9 / 60) + (40.0 / 3600) + +class Samara(Place): + """ """ + + name = 'Samara' + lat = 53 + (17 / 60) + lon = 10 + (14 / 60) + +class Yekaterinburg(Place): + """ """ + + name = 'Central Stadium' + lat = 56 + (50 / 60) + lon = 60 + (34 / 60) + +class Saransk(Place): + """ """ + + name = 'Mordovia Arena' + lat = 54 + (11 / 60) + lon = 45 + (12 / 60) + +class Sochi(Place): + """ """ + + name = 'Fisht Olympic Stadium' + lat = 43 + (24 / 60) + lon = 39 + (57 / 60) + + +places = dict( + + moscow=Moscow(), + spartak=Spartak(), + stpetersberg=StPetersberg(), + + kaliningrad=Kaliningrad(), + + novgorod=Novgorod(), + yekaterinburg=Yekaterinburg(), + kazan=Kazan(), + saransk=Saransk(), + samara=Samara(), + + volgograd=Volgograd(), + rostovondon=RostovOnDon(), + sochi=Sochi(), + ) + +# Group A +rus = Team('RUS') +sau = Team('SAU') +egy = Team('EGY') +urg = Team('URG') + +# Group B +por = Team('POR') +spa = Team('SPA') +mor = Team('MOR') +ira = Team('IRA') + +# group C +fra = Team('FRA') +aus = Team('AUS') +per = Team('PER') +den = Team('DEN') + +# group D +arg = Team('ARG') +ice = Team('ICE') +cro = Team('CRO') +nig = Team('NIG') + +# group E +bra = Team('BRA') +swi = Team('SWI') +crc = Team('CRC') +ser = Team('SER') + +# group F +ger = Team('GER') +swe = Team('SWE') +mex = Team('MEX') +sko = Team('SKO') + +# group G +bel = Team('BEL') +pan = Team('PAN') +tun = Team('TUN') +eng = Team('ENG') + +# group H +pol = Team('POL') +sen = Team('SEN') +col = Team('COL') +jap = Team('JAP') + + +groups = dict( + a=Group(teams = [rus, sau, egy, urg], + games = [ + Game(rus, sau, datetime(2018, 6, 14, 15, 0), + where=places['moscow'], + ascore=5, bscore=0), + + Game(egy, urg, datetime(2018, 6, 15, 12, 0), + where=places['yekaterinburg'], + ascore=0, bscore=1), + + + Game(rus, egy, datetime(2018, 6, 19, 18, 0), + where=places['stpetersberg'], + ascore=3, bscore=1), + + Game(urg, sau, datetime(2018, 6, 20, 15, 0), + where=places['rostovondon'], + ), + + + Game(urg, rus, datetime(2018, 6, 25, 14, 0), + where=places['samara'], + ), + Game(sau, egy, datetime(2018, 6, 25, 14, 0), + where=places['volgograd'], + ), + ]), + + b=Group(teams = [por, spa, mor, ira], + games = [ + Game(mor, ira, datetime(2018, 6, 15, 15, 0), + where=places['stpetersberg'], + ascore=0, bscore=1), + + Game(por, spa, datetime(2018, 6, 15, 18, 0), + where=places['sochi'], + ascore=3, bscore=3), + + + Game(por, mor, datetime(2018, 6, 20, 12, 0), + where=places['moscow'], + ), + Game(ira, spa, datetime(2018, 6, 20, 18, 0), + where=places['kazan'], + ), + + Game(ira, por, datetime(2018, 6, 25, 18, 0), + where=places['saransk'], + ), + Game(spa, mor, datetime(2018, 6, 25, 18, 0), + where=places['kaliningrad'], + ), + ]), + + c=Group(teams = [fra, aus, per, den], + + games = [ + Game(fra, aus, datetime(2018, 6, 16, 10, 0), + where=places['kazan'], + ascore=2, bscore=1), + + Game(per, den, datetime(2018, 6, 16, 14, 0), + where=places['saransk'], + ascore=0, bscore=1), + + + Game(den, aus, datetime(2018, 6, 21, 12, 0), + where=places['samara'], + ), + Game(fra, per, datetime(2018, 6, 21, 15, 0), + where=places['yekaterinburg'], + ), + + Game(den, fra, datetime(2018, 6, 26, 14, 0), + where=places['moscow'], + ), + Game(aus, per, datetime(2018, 6, 26, 14, 0), + where=places['sochi'], + ), + + ]), + + d=Group(teams = [arg, ice, cro, nig], + + games = [ + Game(arg, ice, datetime(2018, 6, 16, 13, 0), + where=places['spartak'], + ascore=1, bscore=1), + + Game(cro, nig, datetime(2018, 6, 16, 19, 0), + where=places['kaliningrad'], + ascore=2, bscore=0), + + + Game(arg, cro, datetime(2018, 6, 21, 18, 0), + where=places['novgorod'], + ), + + Game(nig, ice, datetime(2018, 6, 22, 15, 0), + where=places['volgograd'], + ), + + + Game(nig, arg, datetime(2018, 6, 26, 18, 0), + where=places['stpetersberg'], + ), + Game(ice, cro, datetime(2018, 6, 26, 18, 0), + where=places['rostovondon'], + ), + ]), + + e=Group(teams = [bra, swi, crc, ser], + + games = [ + Game(crc, ser, datetime(2018, 6, 17, 12, 0), + where=places['samara'], + ascore=0, bscore=1), + + Game(bra, swi, datetime(2018, 6, 17, 18, 0), + where=places['rostovondon'], + ascore=1, bscore=1), + + + Game(bra, crc, datetime(2018, 6, 22, 12, 0), + where=places['stpetersberg'], + ), + Game(ser, swi, datetime(2018, 6, 22, 18, 0), + where=places['kaliningrad'], + ), + + Game(ser, bra, datetime(2018, 6, 27, 18, 0), + where=places['spartak'], + ), + Game(swi, crc, datetime(2018, 6, 27, 18, 0), + where=places['novgorod'], + ), + ]), + + f=Group(teams = [ger, swe, mex, sko], + + games = [ + Game(ger, mex, datetime(2018, 6, 17, 15, 0), + where=places['moscow'], + ascore=0, bscore=1), + + Game(swe, sko, datetime(2018, 6, 18, 12, 0), + where=places['novgorod'], + ascore=1, bscore=0), + + + Game(sko, mex, datetime(2018, 6, 23, 15, 0), + where=places['rostovondon'], + ), + Game(ger, swe, datetime(2018, 6, 23, 18, 0), + where=places['sochi'], + ), + + Game(sko, ger, datetime(2018, 6, 27, 14, 0), + where=places['kazan'], + ), + Game(mex, swe, datetime(2018, 6, 27, 14, 0), + where=places['yekaterinburg'], + ), + ]), + + g=Group(teams = [bel, pan, tun, eng], + + games = [ + Game(bel, pan, datetime(2018, 6, 18, 15, 0), + where=places['sochi'], + ascore=3, bscore=0), + + Game(tun, eng, datetime(2018, 6, 18, 18, 0), + where=places['volgograd'], + ascore=1, bscore=2), + + + Game(bel, tun, datetime(2018, 6, 23, 12, 0), + where=places['spartak'], + ), + + Game(eng, pan, datetime(2018, 6, 24, 12, 0), + where=places['novgorod'], + ), + + Game(eng, bel, datetime(2018, 6, 28, 18, 0), + where=places['kaliningrad'], + ), + Game(pan, tun, datetime(2018, 6, 28, 18, 0), + where=places['saransk'], + ), + ]), + + h=Group(teams = [pol, sen, col, jap], + + games = [ + Game(col, jap, datetime(2018, 6, 19, 12, 0), + where=places['saransk'], + ascore=1, bscore=2), + + Game(pol, sen, datetime(2018, 6, 19, 15, 0), + where=places['spartak'], + ascore=1, bscore=2), + + + Game(jap, sen, datetime(2018, 6, 24, 15, 0), + where=places['yekaterinburg'], + ), + Game(pol, col, datetime(2018, 6, 24, 18, 0), + where=places['kazan'], + ), + + Game(jap, pol, datetime(2018, 6, 28, 14, 0), + where=places['volgograd'], + ), + Game(sen, col, datetime(2018, 6, 28, 14, 0), + where=places['samara'], + ), + ])) + + +print() +print("It's a knock out!") + +# Simulate a knockout draw + bugs +jsf_places = [ + places['sochi'], + places['kazan'], + places['samara'], + places['rostovondon'], + + places['moscow'], + places['novgorod'], + places['stpetersberg'], + places['spartak'], + + places['novgorod'], + places['kazan'], + places['sochi'], + places['samara'], + + + places['stpetersberg'], + places['moscow'], + + places['moscow'], + + places['stpetersberg'], + ] + +jsf_dates = [ + datetime(2018, 6, 30, 18, 0), + datetime(2018, 6, 30, 14, 0), + datetime(2018, 7, 2, 14, 0), + datetime(2018, 7, 2, 18, 0), + + datetime(2018, 7, 1, 14, 0), + datetime(2018, 7, 1, 18, 0), + datetime(2018, 7, 3, 14, 0), + datetime(2018, 7, 3, 18, 0), + + datetime(2018, 7, 6, 14, 0), + datetime(2018, 7, 6, 18, 0), + datetime(2018, 7, 7, 18, 0), + datetime(2018, 7, 7, 14, 0), + + datetime(2018, 7, 10, 18, 0), + datetime(2018, 7, 11, 18, 0), + + datetime(2018, 7, 15, 15, 0), + datetime(2018, 7, 14, 14, 0), + ] + +def name2team(name): + """ Convert string to team object """ + return globals()[name] + + +jsf = JeuxSansFrontieres( + groups, + places=jsf_places, + dates=jsf_dates, + name2team=name2team) + + + + + diff --git a/karmapi/words.py b/karmapi/words.py new file mode 100644 index 0000000..17663d4 --- /dev/null +++ b/karmapi/words.py @@ -0,0 +1,42 @@ +""" count words +""" + +from collections import Counter + +from pathlib import Path + +import argparse + +parser = argparse.ArgumentParser() + +parser.add_argument('path', nargs='+') + +parser.add_argument('--glob', default='**/*.rst') + +args = parser.parse_args() + + +totals = Counter() + +for path in args.path: + print(path) + for name in Path(path).glob(args.glob): + + print(name) + + counts = Counter() + + counts.update(name.open().read().split()) + + print(counts.most_common(7)) + print(sum(counts.values())) + print() + + totals.update(counts) + +print('Totals:') + +print(totals.most_common(26)) + +print(sum(totals.values())) + diff --git a/karmapi/zen.py b/karmapi/zen.py index b06d11e..c90615d 100644 --- a/karmapi/zen.py +++ b/karmapi/zen.py @@ -23,7 +23,50 @@ Initial mining by a network of pi's. +Update +====== + +Fast forward six months. New inspiration from Alvarro Boirac. + +So the idea here is to have a blockchain for every stream of data. + +The trick is to find streams that other people also want to see, share the work +and the trust. + +The blockchain can log blocks of data, and meta data about that data. + +A block server too. Get the blocks you need for the problems that interest you. + +Share your results. + +Share observations, numbers in time. + +And model predictions too. + +Use blockchain to sign the data blocks. An open ledger of open data. + +Copyright of data and other IP. +=============================== + +Many organisations have invaluable data that can aid research at a time when +more than ever there is a need to understand how our planet works. + +Earthquake records, give detailed data on magnitude depth latitude, longitude and time. + +Data related to climate modelling and forecasting is freely available from +organisations such as the European Centre for Medium Range Weather forecasting. + +The aim of this project here is to enable those sharing such data to share the +work of distributing and exploring that data and to feed back their discoveries too. + +The dream is that organisations will adopt something like this as a way to +share data and information in a network of open trust. + +For now, the goal is get a simple working example. Famous last words. + """ import this + +#import blockchain diff --git a/requirements.txt b/requirements.txt index d68963d..134c2f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,18 +1,29 @@ -ripl -jupyter -matplotlib # jupyter should provide this.. maybe it doesn't -pandas # this might provide matplotib -pyaudio # for sound +#jupyter for added goodness + +blume # for the blooming table and the magic farm + +astropy # so we can find jupiter and more + + +#matplotlib==2.1 # jupyter should provide this.. maybe it doesn't +#pandas # this might provide matplotib +#pyaudio # for sound curio # for async magic +#blockchain # for trust and meta data exchange + Pillow # pillow for PIL for images #sense_hat # if you are on a pi with a sense hat #gpio_zero # if you are on a pi +#picamera # for pictures veyes on pis #tkinter, with luck it comes with python. pytest # to run the test(s) hypothesis # needed to make writing tests fun -picamera # for pictures veyes + +requests # seems to be missing from core python + + diff --git a/setup.py b/setup.py index 88dbdd5..dd2bf90 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from codecs import open from os import path -__version__ = '0.6.1' +__version__ = '1.03141592' here = path.abspath(path.dirname(__file__)) @@ -22,23 +22,19 @@ version=__version__, description='Data with karma and pi', long_description=long_description, - url='https://github.com/openbermuda/karmapi', - download_url='https://github.com/openbermuda/karmapi/tarball/' + __version__, + url='https://github.com/swfiua/karmapi', + #download_url='https://github.com/swfiua/karmapi/tarball/' + __version__, license='GPL v 3', classifiers = [ 'Development Status :: 3 - Alpha', - 'Intended Audience :: End Users/Desktop', - 'Programming Language :: Python :: 3.6.1', + 'Intended Audience :: Science/Research', + 'Programming Language :: Python :: 3.6', ], entry_points = { 'console_scripts': [ - 'kpi = karmapi.kpi:main', - 'kpimage = karmapi.tools.image:main', 'tankrain = karmapi.tankrain:main', - 'checkmate = karmapi.checksum:main', - 'joy = karmapi.pigjoy:main', - 'currie = karmapi.currie:main', - 'hush = karmapi.hush:main', + 'cpr = karmapi.cpr:main', + 'fifawc = karmapi.wc:main', ], }, keywords='data pi karma', diff --git a/tests/test_gilliam.py b/tests/test_gilliam.py new file mode 100644 index 0000000..bd26d09 --- /dev/null +++ b/tests/test_gilliam.py @@ -0,0 +1,16 @@ +import curio + +from karmapi.gilliam import terry + +def func(): + + assert not terry() + +async def coro(): + + assert terry() + +func() + +xx = curio.run(coro) +