pyephem: can't calculate sunrise/set for polar regions - pyephem

i'm trying to calculate sunrises and sunsets using pyephem, but the algorithm never seems to converge for polar regions?
observe the sample code below. it iterates through an entire year in 10-minute increments asking for the next sunrise and sunset. pyephem always returns with an AlwaysUpError or NeverUpError, but surely the sun must rise and set at least once during the year?
import ephem
from datetime import datetime, timedelta
obs = ephem.Observer()
obs.lat = '89:30'
obs.long = '0'
start = datetime(2011, 1, 1)
end = datetime(2012, 1, 1)
step = timedelta(minutes=10)
sun = ephem.Sun()
timestamp = start
while timestamp < end:
obs.date = timestamp
try:
print obs.next_rising(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.next_setting(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.previous_rising(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
try:
print obs.previous_setting(sun)
except (ephem.AlwaysUpError, ephem.NeverUpError):
pass
timestamp += step
either i'm using the api incorrectly, there's a bug in pyephem, or i'm misunderstanding something fundamental. any help?

I suspect some sort of improper caching. Consider:
import ephem
atlanta = ephem.Observer()
atlanta.pressure = 0
atlanta.horizon = '-0:34'
atlanta.lat, atlanta.lon = '89:30', '0'
atlanta.date = '2011/03/18 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/03/19 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/03/20 12:00'
print atlanta.previous_rising(ephem.Sun())
# print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/24 12:00'
# print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/25 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
atlanta.date = '2011/09/26 12:00'
print atlanta.previous_rising(ephem.Sun())
print atlanta.next_setting(ephem.Sun())
which yields:
2011/3/18 07:49:34
2011/3/18 17:44:50
2011/3/19 05:04:49
2011/3/19 21:49:23
2011/3/20 01:26:02
2011/9/24 19:59:09
2011/9/25 04:57:21
2011/9/25 17:14:10
2011/9/26 08:37:25
2011/9/26 14:03:20
which matches to the minute with USNO results:
https://raw.github.com/barrycarter/bcapps/master/db/srss-895.txt
See also my related whiny complain in linked question.

I just ran your program and got this output (piped to "sort | uniq -c"):
260 2011/3/17 11:32:31
469 2011/3/17 13:42:56
184 2011/3/18 07:25:56
350 2011/3/18 18:13:15
191 2011/3/19 04:41:42
346 2011/9/24 20:25:13
337 2011/9/25 04:27:45
214 2011/9/25 17:36:10
166 2011/9/26 08:00:59
254 2011/9/26 14:37:06
Are you sure you have the indentations right? Here's my raw code:
https://raw.github.com/barrycarter/bcapps/master/playground4.py
(the output doesn't match my other answer above, but we're using different horizons (-34 minutes vs -50 minutes).

i've found using the start parameter to obs.next_rising(), etc., yield better results. however it still sometimes seems to miss certain crossings; the rises it finds don't always pair off with a corresponding set.

Related

How to count the numbers of elements in parts of a text file using a loop in Perl?

I´m looking for a way to create a script in Perl to count the elements in my text file and do it in parts. For example, my text file has this form:
ID Position Potential Jury agreement NGlyc result
(PART 1)
NP_073551.1_HCoV229Egp2 23 NTSY 0.5990 (8/9) +
NP_073551.1_HCoV229Egp2 62 NTSS 0.7076 (9/9) ++
NP_073551.1_HCoV229Egp2 171 NTTI 0.5743 (5/9) +
...
(PART 2)
QJY77946.1_NA 20 NGTN 0.7514 (9/9) +++
QJY77946.1_NA 23 NTSH 0.5368 (5/9) +
QJY77946.1_NA 51 NFSF 0.7120 (9/9) ++
QJY77946.1_NA 62 NTSS 0.6947 (9/9) ++
...
(PART 3)
QJY77954.1_NA 20 NGTN 0.7694 (9/9) +++
QJY77954.1_NA 23 NTSH 0.5398 (5/9) +
QJY77954.1_NA 51 NFSF 0.7121 (9/9) ++
...
(PART N°...)
Like you can see the ID is the same in each part (one for PART 1, other to PART 2 and then...). The changes only can see in the columns Position//Potential//Jury agreement//NGlyc result Then, my main goal is to count the line with Potential 0,7 >=.
With this in mind, I´m looking for output like this:
Part 1:
1 (one value 0.7 >=)
Part 2:
2 (two values 0.7 >=)
Part 3:
2 (two values 0.7 >=)
Part N°:
X numbers of values 0.7 >=
This output tells me the number of positive values (0.7 >=) for each ID.
The pseudocode I believe would be something like this:
foreach ID in LIST
foreach LINE in FILE
if (ID is in LINE)
... count the line ...
end foreach LINE
end foreach ID
I´m looking for any suggestion (for a package or script idea) or comment to create a better script.
Thanks! Best!
To count the number of lines, for each part, that match some condition on a certain column, you can just loop over the lines, skip the header, parse the part number, and use an array to count the number of lines matching for each part.
After this you can just loop over the counts recorded in the array and print them out in your specific format.
#!/usr/bin/perl
use strict;
use warnings;
my $part = 0;
my #cnt_part;
while(my $line = <STDIN>) {
if($. == 1) {
next;
}elsif($line =~ m{^\(PART (\d+)\)}) {
$part = $1;
}else {
my #cols = split(m{\s+},$line);
if(#cols == 6) {
my $potential = $cols[3];
if(0.7 <= $potential) {
$cnt_part[$part]++;
};
};
};
};
for(my $i=1;$i<=$#cnt_part;$i++){
print "Part $i:\n";
print "$cnt_part[$i] (values 0.7 <=)\n";
};
To run it, just pipe the entire file through the Perl script:
cat in.txt | perl count.pl
and you get an output like this:
Part 1:
1 (values 0.7 <=)
Part 2:
2 (values 0.7 <=)
Part 3:
2 (values 0.7 <=)
If you want to also display the counts into words, you can use Lingua::EN::Numbers (see this program ) and you get an output very similar to the one in your post:
Part 1:
1 (one values 0.7 <=)
Part 2:
2 (two values 0.7 <=)
Part 3:
2 (two values 0.7 <=)
All the code in this post is also available here.

HRULE at MIN-value in RRDTOOL

I'm trying to get a Horizontal line (HRULE) at the lowest value in my RRD-GRAPH with out any good result :(
I have only one data source in the database, end the script is coded in PEARL
#!/usr/bin/perl
use RRDs;
my $cur_time = time();
my $start_time = $cur_time - 86400; # sätt start ill 24 timmar sedan
my $end_1 = time() - 86400;
my $start_1 = $end_1 - 86400;
RRDs::graph "/var/www/ute.png",
"--start= $start_time",
"--end= $cur_time",
"--title= outdoor temperature 1-WIRE 24h",
"--height= 600",
"--width= 1000",
"--vertical-label= °C",
"--upper-limit= 30",
"--lower-limit= -30",
"DEF:Temperatur=/home/nordviken/rrddata/ute_temp.rrd:ute:AVERAGE",
"CDEF:a=Temperatur,-50,0,LIMIT",
"DEF:b=/home/nordviken/rrddata/ute_temp.rrd:ute:AVERAGE:end= $end_1:start= $start_1",
"SHIFT:b:86400",
"COMMENT:\t\t\t\t Nu Medel Max Min\\n",
"HRULE:0#003300",
"LINE1:Temperatur#ff0000:ute\t\t\t\t",
"LINE1:a#0000ff",
"LINE1:b#00ff00",
"GPRINT:Temperatur:LAST:%6.1lf",
"GPRINT:Temperatur:AVERAGE:%6.1lf",
"GPRINT:Temperatur:MAX:%6.1lf",
"GPRINT:Temperatur:MIN:%6.1lf\\n";
my $err=RRDs::error;
if ($err) {print "problem med att skapa grafen: $err\n";}
print "klar!\n"
You could use
VDEF:m=Temperatur,MINIMUM
LINE1:m#003300

Null character appearing when I print a file

I have a code where I read a file and remove a block of line if a certain keyword matches. If I see the key word THERMST, I delete the line before and all lines until I reach a & :
QNODE "CExtHrn - Heater_Bidon" 1.0 T884 TOTAL
THERMST "CExtHrn" 0 2.500000E+01 3.000000E+01 883 ID 0.000000E+00 0.000000E+00 0.000000E+00 0.000000E+00 0.000000E+00 "Heater_Bidon"
NAME2 Heater_ CExtHrn - Heater_Bidon
NAME Heater_ 40097 40170 1
TABTYPE 884 TABLE OPERATION
TABDATA 884 885 INTERP
TABDATA 884 883 THERMST
TABTYPE 885 QNODE TIME
TABDATA 885 2.000000E+01 0.000000E+00
$
However, for an obscure reason, when I print to a new file, it gives several null characters on a certain line. The weird thing is that this line is not related with the line I just changed. If I don't modify the file, by commenting the following lines, I don't get any null characters.
# We delete the last 2 line and skip the rest of the qnode/thermst definition
splice #INPF1_OUT, -2;
# Skipping the lines until next comment line.
$ii++ until substr($INPF1_IN[$ii], 0, 1) eq '$';
$ii = $ii - 1;
Any idea what this could be? The null characters are causing problems for what I do with the file.
Here is what the line should be :
NAME winte_T 101269 101270 1
here is what it prints in the new file :
NAME winte_T ULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNULNUL 101269 101270 1
You can see that the line that cause the error is not related to the one that should be modified
Thank you, the code is below
#!/bin/perl
use strict;
use Text::ParseWords;
open (INPF1_in, '<', $INPF1)
or die "Not able to open : $INPF1";
my #INPF1_IN = <INPF1_in>;
close INPF1_in;
my #INPF1_OUT; # Output INPF1
my $cardno = 1;
my $ii = 0;
until ($ii > $#INPF1_IN) {
my $INPF_line = $INPF1_IN[$ii];
push(#INPF1_OUT, $INPF_line); # Adding line
chomp($INPF_line);
if ($INPF_line eq "-1") {
$cardno++;
}
if ($cardno == 9) {
my #line = parse_line(" ", 0, $INPF_line); # parsing the line elements
if ($line[0] eq "THERMST") { # If Thermostat
# We delete the last 2 line and skip the rest of the qnode/thermst definition
splice #INPF1_OUT, -2;
$ii++ until substr($INPF1_IN[$ii], 0, 1) eq '$';
$ii = $ii-1; # Skipping the lines until next comment line.
}
}
$ii++;
}
open (INPF1_out, '>', $INPF1);
print INPF1_out $_ foreach #INPF1_OUT;
close INPF1_out;
I may be misreading your code, but it look like you're trying to do something very simple in perl, a very hard way.
If I'm reading it right, what you're trying to do is take an input record format, and conditionally print certain lines. Perl has a very good tool for this, called the 'range operator'.
I think you will be able to accomplish what you want with something considerably simpler.
#!/bin/perl
use strict;
use warnings;
while ( <DATA> ) {
print unless ( m/^THERMST/ ... m/^\$$/ );
}
__DATA__
QNODE "CExtHrn - Heater_Bidon" 1.0 T884 TOTAL
THERMST "CExtHrn" 0 2.500000E+01 3.000000E+01 883 ID 0.000000E+00 0.000000E+00 0.000000E+00 0.000000E+00 0.000000E+00 "Heater_Bidon"
NAME2 Heater_ CExtHrn - Heater_Bidon
NAME Heater_ 40097 40170 1
TABTYPE 884 TABLE OPERATION
TABDATA 884 885 INTERP
TABDATA 884 883 THERMST
TABTYPE 885 QNODE TIME
TABDATA 885 2.000000E+01 0.000000E+00
$
This is an example, based on the data you've given so far - if you can give a bit more to show exactly what you're trying to accomplish, I would be pretty sure you can extract the information you need without having to do iterating through elements in an array of words. Perl can do better than that.
(I am guessing a bit, as it's completely unclear where you're getting $cardno from. However this should be quite easy to modify to suit your needs)

Gnuplot prints a strange year, 30 years later

I have the next problem with gnuplot, when I print the time gnuplot
prints de time+30years.
This is a part of my data:
1411336800,1390,0,0,0,10,1411,0,10,0,0,0,0,0,1411
1411340400,1506,0,0,0,10,969,0,10,0,0,0,0,0,969
1411344000,1115,0,0,0,10,1108,0,10,0,0,0,0,0,1108
1411347600,719,0,0,0,10,712,0,10,0,0,0,0,0,712
A part of the script is:
set timefmt "%s"
stats "<tail -1 uur.txt " using 1:2 nooutput
tijd = strftime("%d %B %Y %H:%M", STATS_max_x)
print tijd
And then gnuplot prints: 21 September 2044 01:00. 44 ?
Has some one a clue?
I tried several formats but nothing helped.
Until version 4.6, internally gnuplot uses the 1. January 2000 as reference for its date and time functions (in version 5.0 the standard Unix timestamp is used).
You shouldn't have any problems with set timefmt "%s" if you plot the data. But when using strftime it makes a difference. Since you're using tail anyway, you can simply use
tijd = system('date -d #$(tail -1 uur.txt | cut -d, -f1) +"%d %B %Y %H:%M"')
print tijd

zrangebyscore redis in perl

I'm using Redis.pm in perl scrpit and try to execute next command:
zrevrangebyscore <key> <highscore> 0 WITHSCORES LIMIT 0 1
In appliance with redis documentation i write next and it's working fine
my $data = { $redis->zrevrangebyscore($rkey, $ipl, 0, 'WITHSCORES') };
but when i try to subst 'limit...' in perl command:
my $data = { $redis->zrevrangebyscore($rkey, $ipl, 0, 'WITHSCORES','LIMIT 0 1') };
i got error
[zrevrangebyscore] ERR syntax error, at /usr/local/lib/perl5/site_perl/5.14/Redis.pm line 163
Redis::__ANON__(undef, 'ERR syntax error') called at /usr/local/lib/perl5/site_perl/5.14/Redis.pm line 195
Redis::wait_one_response('Redis=HASH(0x801075300)') called at /usr/local/lib/perl5/site_perl/5.14/Redis.pm line 183
Redis::wait_all_responses('Redis=HASH(0x801075300)') called at /usr/local/lib/perl5/site_perl/5.14/Redis.pm line 172
How i can pass to arg 'LIMIT 0 1' in Redis.pm ?
The answer is:
my $data = { $redis->zrevrangebyscore($rkey, $ipl, 0, 'WITHSCORES', qw{LIMIT 0 1})};
May be it will be usefull for somebody. Thanks!
If you are just looking to iterate through your sorted set, and always fetch the highest entry, just use
zrange
(zrange documentation)
instead of zrevrangebyscore.
my $start = -1; #-1 is last element = the element with the highest score
my $stop = -1;
while (my $data = $redis->zrange($rkey, $start--, $stop--, 'WITHSCORES')) {
#fetch the ultimate element, then the penultimate, etc....
};