I have this script on a Raspberry Pi that runs forever and every minute will get data from my weather station and then post it to a JSON and database. The issue is that after a few days of running, the Python script stops running with the following error:
munmap_chunk(): invalid pointer
Aborted
Here is the code:
from gpiozero import Button
import bme280_sensor
import wind_direction_byo
import ds18b20_therm
import statistics
import time
import math
import json
import database
import gc
CM_IN_A_KM = 100000.0
SECS_IN_AN_HOUR = 3600
ADJUSTMENT = 1.18
BUCKET_SIZE = 0.2794
store_speeds = []
store_directions = []
wind_count = 0
rain_count = 0
radius_cm = 9.0
wind_interval = 5
interval = 60
db = database.weather_database()
def spin():
global wind_count
wind_count = wind_count + 1
# print("spin" + str(wind_count))
def calculate_speed(time_sec):
global wind_count
circumference_cm = (2 * math.pi) * radius_cm
rotations = wind_count / 2.0
dist_km = (circumference_cm * rotations) / CM_IN_A_KM
km_per_sec = dist_km / time_sec
km_per_hour = km_per_sec * SECS_IN_AN_HOUR
return km_per_hour * ADJUSTMENT
wind_speed_sensor = Button(5)
wind_speed_sensor.when_pressed = spin
def reset_wind():
global wind_count
wind_count = 0
def bucket_tipped():
global rain_count
rain_count = rain_count + 1
def reset_rainfall():
global rain_count
rain_count = 0
def updateJsonFile(wind_average, wind_speed, wind_gust, rainfall, humidity, pressure, ambient_temp, ground_temp):
jsonFile = open("/var/www/html/weatherdata.json", "r")
data = json.load(jsonFile)
jsonFile.close()
tmp = data["ambient_temp"]
data["ambient_temp"] = ambient_temp
data["humidity"] = humidity
data["pressure"] = pressure
data["ground_temp"] = ground_temp
data["rainfall"] = rainfall
data["wind_average"] = wind_average
data["wind_speed"] = wind_speed
data["wind_gust"] = wind_gust
data["timestamp"] = time.time()
jsonFile = open("/var/www/html/weatherdata.json", "w+")
jsonFile.write(json.dumps(data))
jsonFile.close()
rain_sensor = Button(6)
rain_sensor.when_pressed = bucket_tipped
temp_probe = ds18b20_therm.DS18B20()
while True:
start_time = time.time()
while time.time() - start_time <= interval:
wind_start_time = time.time()
reset_wind()
#time.sleep(wind_interval)
while time.time() - wind_start_time <= wind_interval:
store_directions.append(wind_direction_byo.get_value())
final_speed = calculate_speed(wind_interval)
store_speeds.append(final_speed)
wind_average = wind_direction_byo.get_average(store_directions)
wind_gust = max(store_speeds)
wind_speed = statistics.mean(store_speeds)
rainfall = rain_count * BUCKET_SIZE
reset_rainfall()
humidity, pressure, ambient_temp = bme280_sensor.read_all()
ground_temp = temp_probe.read_temp()
#print(wind_average, wind_speed, wind_gust, rainfall, humidity, pressure, ambient_temp, ground_temp)
updateJsonFile(wind_average, wind_speed, wind_gust, rainfall, humidity, pressure, ambient_temp, ground_temp)
db.insert(ambient_temp, ground_temp, 0, pressure, humidity, wind_average, wind_speed, wind_gust, rainfall)
store_speeds = []
store_directions = []
gc.collect()
Most of the code is taken from Raspberry Pi's Weather Station guide. My addition is the updateJsonFile function and some other little things to get that to work. The website doesn't mention this problem however there was other errors in the guide they didn't mention.
My guess is that it's running out of memory (despite the garbage collect) considering the timing of when the error happens. I'm going to investigate that but if anyone else has a solution, that would be great.
Related
I'm having a few problems.
First, given wind speeds seem to be low, especially compared to other weather stations reporting close by (apparently there are lots of enthusiasts in my area). Just watching the trees, flag, bushes, small animals flying across my yard, I can tell 1.6mph is a wee bit low. Everything tested fine inside, and when I run the test script outside its picking up the signal as it spins.
the 2nd problem is it always reports the "mean" and "max" speeds as exactly the same. I've tried to adjust the intervals, but no matter what length of time I put in, they always report as the same numbers.
from gpiozero import Button
import requests
import time
import math
import statistics
import database
wind_count = 0
radius_cm = 9.0
wind_interval = 5
ADJUSTMENT = 1.18
interval = 60
gust = 0
def spin():
global wind_count
wind_count = wind_count + 1
def calculate_speed(time_sec):
global wind_count
global gust
circumference_cm = (2 * math.pi) * radius_cm
rotations = wind_count / 2.0
dist_cm = circumference_cm * rotations
dist_km = (circumference_cm * rotations) / 100000
dist_mi = dist_km * 0.621371
mi_per_sec = dist_mi / time_sec
mi_per_hour = mi_per_sec * 3600
return mi_per_hour * ADJUSTMENT
def reset_wind():
global wind_count
wind_count = 0
def reset_gust():
global gust
gust = 0
wind_speed_sensor = Button(16)
wind_speed_sensor.when_activated = spin
while True:
print("Starting Weather Sensor Read Loop...")
start_time = time.time()
while time.time() - start_time <= interval:
print("Start timed loop...")
wind_start_time = time.time()
reset_wind()
reset_gust()
store_speeds = []
time.sleep(wind_interval)
final_speed = calculate_speed(wind_interval)
store_speeds.append(final_speed)
wind_gust_speed = (max(store_speeds))
wind_speed = (statistics.mean(store_speeds))
print(wind_average, wind_speed)
When I comment out "store_speeds = [ ]" the first loop the speeds are reported the same, every loop after I get a "max" reading thats "different" than the mean. This still troubles me, because why on the first loop are they the same? Am I wrong for thinking with the wind_interval set at 5, and the interval set to 60, that its taking 5 second samples over a 60 second period, giving me 12 sample to get the mean and max from?
My goal is every time it reports, I get a mean and max for that "loop" if possible, and not a mean/max over the time the script stays running before its interrupted/stopped.
Here is the working and corrected code:
from gpiozero import Button
import time
import math
import statistics
wind_count = 0
radius_cm = 9.0
wind_interval = 5
interval = 30
CM_IN_A_KM = 100000.0
SECS_IN_AN_HOUR = 3600
ADJUSTMENT = 1.18
store_speeds = []
def reset_wind():
global wind_count
wind_count = 0
def spin():
global wind_count
wind_count = wind_count + 1
def calculate_speed(time_sec):
global wind_count
circumference_cm = (2 * math.pi) * radius_cm
rotations = wind_count / 2.0
dist_km = (circumference_cm * rotations) / CM_IN_A_KM
km_per_sec = dist_km / time_sec
km_per_hour = km_per_sec * SECS_IN_AN_HOUR
mi_per_hour = km_per_hour * 0.6214
return mi_per_hour * ADJUSTMENT
wind_speed_sensor = Button(16)
wind_speed_sensor.when_pressed = spin
while True:
store_speeds = []
for _ in range (interval//wind_interval):
reset_wind()
#reset_gust()
time.sleep(wind_interval) # counter is spinning in background
final_speed = calculate_speed(wind_interval)
store_speeds.append(final_speed)
wind_gust = max(store_speeds)
wind_speed = statistics.mean(store_speeds)
print(wind_speed, wind_gust)
I am having a bit of a struggle with parsing values between these def functions. The base code getSensorData() and main() works fine, values are read from the sensor and sent to thingspeak. However, I wanted to add a calculation function called calcDewPoint() to the original code to calculate dewpoint from the sensor values (RH, T) but it seems that the code gets stuck :/
Output from terminal when I run the code as is:
starting...
sense1
sense2
dewpoint1
gamma1
exiting.
Temperature/Humidity monitor using Raspberry Pi and DHT22. Data is displayed at thingspeak.com
Change list 02/06/2020
Add dewpoint calculations
import sys
import RPi.GPIO as GPIO
from time import sleep
import Adafruit_DHT
import urllib2
import math #(using numPy instead of math lib)
#import numPy as np
#import constant (Create a *.py file to be able to use constant accross multiple projects)
#Constant Variables - Magnus Parameters
m = 17.62 #Mass Constant (Water Vapour)
Tn = 243.12 #Tempreture Constant
Ah = 6.112 #hPa Pressure Constant
Ak = 0.611 #kPa Pressure Constant
K = 273.15 #Kelvin constant
Ta = 216.7 #Tempreture Constant
myAPI = 'FZZHL7N2R2AXXXXX'
def getSensorData():
print 'sense1'
RH, T = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 17)
print 'sense2'
return (str(RH), str(T))
def calcDewPoint(RH, T):
print 'dewpoint1'
Td = (K * gamma(RH, T)) / (m - gamma(RH, T))
print 'dewpoint2'
return str(Td)
def gamma(RH, T):
print 'gamma1'
g = math.log(RH/100.0) + ((m * T) / (c + T))
print 'gamma2'
return str(g)
def main():
print 'starting...'
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
try:
RH, T = getSensorData() #Call function to Read DHT22 sensor conencted to RaspberryPi
Td = calcDewPoint(RH, T) #Call function to calculate dewpoint
f = urllib2.urlopen(baseURL + "&field1=%s&field2=%s&field3=%s" % (RH, T, Td))
print f.read()
f.close()
sleep(60) #uploads DHT22 sensor values every 1 minutes
except:
print 'exiting.'
break
# call main
if __name__ == '__main__':
main()
Your variable c is not defined. When you call calcDewPoint, it then calls gamma, which tries to run your math expression. However, c does not exist at that point.
Everything is running smooth, Code works with the odd exception in the debugger,
File "/usr/lib/python3/dist-packages/thonny/backend.py", line 305, in _custom_import
module = self._original_import(*args, **kw)
ImportError: No module named 'urllib2'
but overall it functions well. We can close up the thread.
"""
dht22.py
Temperature/Humidity monitor using Raspberry Pi and DHT22.
Data is displayed at thingspeak.com
Original author: Mahesh Venkitachalam at electronut.in
Modified by Jacques Kleynhans 06062020
Return rounded string values
Created Temporary variables Hum and Tair
"""
#import sys
import math
#import RPi.GPIO as GPIO
from time import sleep
import Adafruit_DHT
import urllib2
#Constant Variables - Magnus Parameters Max 0.083 Tair Range -20C + 50C
m = 17.62 # g/mol Mass Constant (Water Vapour)
Tn = 240.7263 #Tempreture Constant
Ah = 6.116441 #hPa Pressure Constant
Ak = 0.611 #kPa Pressure Constant
K = 273.15 #Kelvin constant
Ta = 216.7 #Tempreture Constant
#constant for leaf Temperature
Tc = 2.0
myAPI = 'FZZHL7N2R2AXXXXX'
def getSensorData():
RH, T = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 17)
return (round(RH,3), round(T,3))
# Define functions to calculate dewpoint, return a rounded string)
def calcDewPoint(Hum,Tair):
#print('dewpoint1')
Td = (Tn * gamma(Hum,Tair)) / (m - gamma(Hum,Tair))
#print('dewpoint2')
return round(Td,3)
def gamma(Hum,Tair):
#print ('gamma1')
g = math.log(Hum/100.0) + ((m * Tair) / (Tn + Tair))
#print('gamma2')
return round(g,3)
# Define functions to calculate VPD, return a rounded integer)
#Vapor pressure deficit control strategies for plant production
#IFAC Control applications and Ergonomics in Agriculture, Athens, Greece, 1998
def satVaporPres(Tair):
es = 6.1078*math.exp((Tair*17.2694)/(Tair+237.3)) #mPa
return round(es,3)
def actVaporPres(Hum, es):
ea = (Hum/100)*es
return round(ea,3)
def leafEs(Tair):
leafTemp = Tair - Tc
les = 6.1078*math.exp((leafTemp*17.2694)/(leafTemp+237.3))
return round(les, 3)
#Partial pressure of water vapour Pw in the air surrounding the plant
def parPressureW(Hum, es, Tair):
Pw = Hum*es*Tair
return(Pw)
def VPD(les, ea): #VPD air / crop
VPD = (les - ea)/10
return round(VPD,3)
def main():
print('starting...')
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
try:
RH, T = getSensorData()
Hum = RH
Tair = T
Td = calcDewPoint(Hum,Tair)
es = satVaporPres(Tair)
ea = actVaporPres(Hum, es)
les = leafEs(Tair)
TempVPD = VPD(les,ea)
print(Hum, Tair, Td, TempVPD)
f = urllib2.urlopen(baseURL + "&field1=%s&field2=%s&field3=%s&field4=%s" % (RH, T, Td, TempVPD))
print f.read()
f.close()
sleep(60) #uploads DHT22 sensor values every 1 minutes
except:
print('exiting.')
break
# call main
if __name__ == '__main__':
main()
I've been trying to make some sort of simulation of the solar system, and I came across Kepler's equation in order to give me the position of the planet at any given time. I used the Newton-Raphson method in order to calculate the eccentric anomaly. However, I can't seem to make the planet actually orbit properly, and I am not sure what is wrong. The planet simply goes back and forth in a very tiny spot.
I appreciate the help in advance.
from datetime import datetime, timedelta
from math import *
from vpython import *
scene = canvas(title='Solar system simulation',
width=1024, height=720,
center=vector(0,0,0), background = color.black)
sun = sphere(pos = vector(0,0,0), radius = 5, color = color.yellow)
earth = sphere(pos=vector(1,1,0), radius = 1, color = color.blue, make_trail = True)
earth.trail_color = color.white
d1 = datetime.now()
while True:
d1 = d1 + timedelta(minutes = 1)
d2 = datetime(2000, 1, 1, 00, 00)
SecondsFrom2000 = (d1 - d2).total_seconds() #seconds between today and 01.01.2000 at midnight
CenturiesFrom2000 = SecondsFrom2000/(60*60*24*365.25*100) #centuries between today and 2000
e0Earth = 0.01671123 #eccentricity
edotEarth = -0.00004392
eEarth = e0Earth + edotEarth*CenturiesFrom2000
a0Earth = 1.00000018 #semi-major axis[au], from 3000 BC - 3000 AD
adotEarth = -0.00000003 #[au/century]
aEarth = a0Earth + adotEarth*CenturiesFrom2000
L0Earth = 100.46691572 #mean longitude [deg]
LdotEarth = 35999.37306329 #[deg/century]
LEarth = (L0Earth + LdotEarth*CenturiesFrom2000)*(pi/180) #[rad/century]
Pi0Earth = 102.93005885 #longitude of the perihelion [deg]
PidotEarth = 0.31795260 #[deg/century]
PiEarth = (Pi0Earth + PidotEarth*CenturiesFrom2000)*(pi/180)
W0Earth = -5.11260389 #longitude of the ascending node [deg]
WdotEarth = -0.24123856
WEarth = (W0Earth + WdotEarth*CenturiesFrom2000)*(pi/180)
I0Earth = -0.00054346 #inclination [deg]
IdotEarth = -0.01337178
IEarth = (I0Earth + IdotEarth*CenturiesFrom2000)*(pi/180)
MEarth = LEarth - PiEarth #mean anomaly
wEarth = PiEarth - WEarth #argument of perihelion
E0 = 0.1
E1 = MEarth #E = eccentric anomaly
error = 1
while error > 0.000001:
E2 = E1 - (E1 - eEarth*sin(E1)/(1 - eEarth*cos(E1)))
E1 = E2
erreur = abs(E2 - E1)
E_Earth = E2
PEarth = aEarth * (cos(E_Earth) - eEarth) #[au]
QEarth = aEarth * sin(E_Earth)*sqrt(1 - eEarth*eEarth) #[au]
xEarth = cos(wEarth)*PEarth - sin(wEarth)*QEarth
yEarth = sin(wEarth)*PEarth + cos(wEarth)*QEarth
zEarth = sin(IEarth)*xEarth
xEarth = cos(IEarth)*xEarth
xtempEarth = xEarth
xEarth = cos(WEarth)*xtempEarth - sin(WEarth)*yEarth
yEarth = sin(WEarth)*xtempEarth + cos(WEarth)*yEarth
earth.pos = vector(xEarth*10,yEarth*10,zEarth*10)
Your program is too complicated for me to follow, but I would recommend inserting some print statements in the hope that they would uncover where your code is doing something different than want you wanted.
I am using SpreadedLinearZeroInterpolatedTermStructure class to price bond. I have 35 key rates, from 1M to 30Y. I also have a daily spot curve. So I want to input 35 key rates extracted from the daily spot curve to the class, then change key rates to see what's the bond price.
Giving credit to GB, and his article here:
http://gouthamanbalaraman.com/blog/bonds-with-spreads-quantlib-python.html
I followed his method which worked well, the bond price is changing due to the different values set to key rates.
Then I substituted his flat curve with my daily spot curve, his handles list with my handles (35 handles in it), and his two dates with my 35 dates.
I set values to some of the key rates while the NPV stayed still(even I gave a huge shock). I also tried to give only two key rates on a zero curve, and it worked. So I guess it's because 35 key rates is way too much? Any help is appreciated
import QuantLib as ql
# =============================================================================
# normal yc term structure
# =============================================================================
todaysDate = ql.Date(24,5,2019)
ql.Settings.instance().evaluationDate = todaysDate
KR1 = [0, 1, 3, 6, 9] # KR in month unit
KR2 = [x for x in range(1,31)] # KR in year unit
spotDates = [] # starting from today
for kr in KR1:
p = ql.Period(kr,ql.Months)
spotDates.append(todaysDate+p)
for kr in KR2:
p = ql.Period(kr,ql.Years)
spotDates.append(todaysDate+p)
spotRates = [0.02026,
0.021569,
0.02326,
0.025008,
0.026089,
0.026679,
0.028753,
0.029376,
0.030246,
0.031362,
0.033026,
0.034274,
0.033953,
0.033474,
0.033469,
0.033927,
0.03471,
0.035596,
0.036396,
0.036994,
0.037368,
0.037567,
0.037686,
0.037814,
0.037997,
0.038247,
0.038562,
0.038933,
0.039355,
0.039817,
0.040312,
0.040832,
0.041369,
0.041922,
0.042487] # matching points
dayCount = ql.Thirty360()
calendar = ql.China()
interpolation = ql.Linear()
compounding = ql.Compounded
compoundingFrequency = ql.Annual
spotCurve = ql.ZeroCurve(spotDates, spotRates, dayCount, calendar,
interpolation,compounding, compoundingFrequency)
spotCurveHandle = ql.YieldTermStructureHandle(spotCurve)
# =============================================================================
# bond settings
# =============================================================================
issue_date = ql.Date(24,5,2018)
maturity_date = ql.Date(24,5,2023)
tenor = ql.Period(ql.Semiannual)
calendar = ql.China()
business_convention = ql.Unadjusted
date_generation = ql.DateGeneration.Backward
month_end = False
schedule = ql.Schedule(issue_date,maturity_date,tenor,calendar,
business_convention, business_convention,
date_generation,month_end)
settlement_days = 0
day_count = ql.Thirty360()
coupon_rate = 0.03
coupons = [coupon_rate]
face_value = 100
fixed_rate_bond = ql.FixedRateBond(settlement_days,
face_value,
schedule,
coupons,
day_count)
#bond_engine = ql.DiscountingBondEngine(spotCurveHandle)
#fixed_rate_bond.setPricingEngine(bond_engine)
#print(fixed_rate_bond.NPV())
# =============================================================================
# non-parallel shift of yc
# =============================================================================
#def KRshocks(kr0=0.0, kr_1M=0.0, kr_3M=0.0, kr_6M=0.0, kr_9M=0.0,
# kr_1Y=0.0,kr_2Y=0.0, kr_3Y=0.0, kr_4Y=0.0, kr_5Y=0.0, kr_6Y=0.0,
# kr_7Y=0.0, kr_8Y=0.0, kr_9Y=0.0, kr_10Y=0.0, kr_11Y=0.0, kr_12Y=0.0,
# kr_13Y=0.0, kr_14Y=0.0, kr_15Y=0.0, kr_16Y=0.0, kr_17Y=0.0, kr_18Y=0.0,
# kr_19Y=0.0, kr_20Y=0.0, kr_21Y=0.0, kr_22Y=0.0, kr_23Y=0.0, kr_24Y=0.0,
# kr_25Y=0.0, kr_26Y=0.0, kr_27Y=0.0, kr_28Y=0.0, kr_29Y=0.0, kr_30Y=0.0):
# '''
#
# Parameters:
# Input shocks for each key rate.
# kr0 = today's spot rate shock;
# kr_1M = 0.083 year(1 month) later spot rate shock;
# kr_1Y = 1 year later spot rate shock;
# .
# .
# .
#
# '''
#
# krs = list(locals().keys())
# KRHandles = {}
# for k in krs:
# KRHandles['{}handle'.format(k)] = ql.QuoteHandle(ql.SimpleQuote(locals()[k]))
# return list(KRHandles.values())
#handles = KRshocks()
kr = ['kr0', 'kr_1M', 'kr_3M', 'kr_6M', 'kr_9M', 'kr_1Y','kr_2Y', 'kr_3Y',
'kr_4Y', 'kr_5Y', 'kr_6Y','kr_7Y', 'kr_8Y', 'kr_9Y', 'kr_10Y', 'kr_11Y',
'kr_12Y', 'kr_13Y', 'kr_14Y', 'kr_15Y', 'kr_16Y', 'kr_17Y', 'kr_18Y',
'kr_19Y', 'kr_20Y', 'kr_21Y', 'kr_22Y', 'kr_23Y', 'kr_24Y','kr_25Y',
'kr_26Y', 'kr_27Y', 'kr_28Y', 'kr_29Y', 'kr_30Y']
#KRQuotes = {}
handles = []
#for k in range(len(kr)):
# KRQuotes['{}'.format(kr[k])] = ql.SimpleQuote(spotRates[k])
# handles.append(ql.QuoteHandle(ql.SimpleQuote(spotRates[k])))
kr0 = ql.SimpleQuote(spotRates[0])
kr_1M = ql.SimpleQuote(spotRates[1])
kr_3M = ql.SimpleQuote(spotRates[2])
kr_6M = ql.SimpleQuote(spotRates[3])
kr_9M = ql.SimpleQuote(spotRates[4])
kr_1Y = ql.SimpleQuote(spotRates[5])
kr_2Y = ql.SimpleQuote(spotRates[6])
kr_3Y = ql.SimpleQuote(spotRates[7])
kr_4Y = ql.SimpleQuote(spotRates[8])
kr_5Y = ql.SimpleQuote(spotRates[9])
kr_6Y = ql.SimpleQuote(spotRates[10])
kr_7Y = ql.SimpleQuote(spotRates[11])
kr_8Y = ql.SimpleQuote(spotRates[12])
kr_9Y = ql.SimpleQuote(spotRates[13])
kr_10Y = ql.SimpleQuote(spotRates[14])
kr_11Y = ql.SimpleQuote(spotRates[15])
kr_12Y = ql.SimpleQuote(spotRates[16])
kr_13Y = ql.SimpleQuote(spotRates[17])
kr_14Y = ql.SimpleQuote(spotRates[18])
kr_15Y = ql.SimpleQuote(spotRates[19])
kr_16Y = ql.SimpleQuote(spotRates[20])
kr_17Y = ql.SimpleQuote(spotRates[21])
kr_18Y = ql.SimpleQuote(spotRates[22])
kr_19Y = ql.SimpleQuote(spotRates[23])
kr_20Y = ql.SimpleQuote(spotRates[24])
kr_21Y = ql.SimpleQuote(spotRates[25])
kr_22Y = ql.SimpleQuote(spotRates[26])
kr_23Y = ql.SimpleQuote(spotRates[27])
kr_24Y = ql.SimpleQuote(spotRates[28])
kr_25Y = ql.SimpleQuote(spotRates[29])
kr_26Y = ql.SimpleQuote(spotRates[30])
kr_27Y = ql.SimpleQuote(spotRates[31])
kr_28Y = ql.SimpleQuote(spotRates[32])
kr_29Y = ql.SimpleQuote(spotRates[33])
kr_30Y = ql.SimpleQuote(spotRates[34])
handles.append(ql.QuoteHandle(kr0))
handles.append(ql.QuoteHandle(kr_1M))
handles.append(ql.QuoteHandle(kr_3M))
handles.append(ql.QuoteHandle(kr_6M))
handles.append(ql.QuoteHandle(kr_9M))
handles.append(ql.QuoteHandle(kr_1Y))
handles.append(ql.QuoteHandle(kr_2Y))
handles.append(ql.QuoteHandle(kr_3Y))
handles.append(ql.QuoteHandle(kr_4Y))
handles.append(ql.QuoteHandle(kr_5Y))
handles.append(ql.QuoteHandle(kr_6Y))
handles.append(ql.QuoteHandle(kr_7Y))
handles.append(ql.QuoteHandle(kr_8Y))
handles.append(ql.QuoteHandle(kr_9Y))
handles.append(ql.QuoteHandle(kr_10Y))
handles.append(ql.QuoteHandle(kr_11Y))
handles.append(ql.QuoteHandle(kr_12Y))
handles.append(ql.QuoteHandle(kr_13Y))
handles.append(ql.QuoteHandle(kr_14Y))
handles.append(ql.QuoteHandle(kr_15Y))
handles.append(ql.QuoteHandle(kr_16Y))
handles.append(ql.QuoteHandle(kr_17Y))
handles.append(ql.QuoteHandle(kr_18Y))
handles.append(ql.QuoteHandle(kr_19Y))
handles.append(ql.QuoteHandle(kr_20Y))
handles.append(ql.QuoteHandle(kr_21Y))
handles.append(ql.QuoteHandle(kr_22Y))
handles.append(ql.QuoteHandle(kr_23Y))
handles.append(ql.QuoteHandle(kr_24Y))
handles.append(ql.QuoteHandle(kr_25Y))
handles.append(ql.QuoteHandle(kr_26Y))
handles.append(ql.QuoteHandle(kr_27Y))
handles.append(ql.QuoteHandle(kr_28Y))
handles.append(ql.QuoteHandle(kr_29Y))
handles.append(ql.QuoteHandle(kr_30Y))
ts_spreaded2 = ql.SpreadedLinearZeroInterpolatedTermStructure(spotCurveHandle,
handles,
spotDates)
ts_spreaded_handle2 = ql.YieldTermStructureHandle(ts_spreaded2)
bond_engine = ql.DiscountingBondEngine(ts_spreaded_handle2)
fixed_rate_bond.setPricingEngine(bond_engine)
#print(fixed_rate_bond.NPV())
kr0.setValue(0.1)
kr_10Y.setValue(0.2)
kr_12Y.setValue(0.2)
print(fixed_rate_bond.NPV())
no errors came out but the bond price is the same as the price before spreads added
There is my code. I fixed it like this:
# Take 3 digits for significant figures in this code
import numpy as np
from math import *
from astropy.constants import *
import matplotlib.pyplot as plt
import time
start_time = time.time()
"""
G = Gravitational constant
g0 = Standard acceleration of gravity ( 9.8 m/s2)
M_sun = Solar mass
M_earth = Earth mass
R_sun = Solar darius
R_earth = Earth equatorial radius
au = Astronomical unit
Astropy.constants doesn't have any parameter of moon.
So I bring the data from wikipedia(https://en.wikipedia.org/wiki/Moon)
"""
M_moon = 7.342E22
R_moon = 1.737E6
M_earth = M_earth.value
R_earth = R_earth.value
G = G.value
perigee, apogee = 3.626E8, 4.054E8
position_E = np.array([0,0])
position_M = np.array([(perigee+apogee)/2.,0])
position_com = (M_earth*position_E+M_moon*position_M)/(M_earth+M_moon)
rel_pE = position_E - position_com
rel_pM = position_M - position_com
F = G*M_moon*M_earth/(position_M[0]**2)
p_E = {"x":rel_pE[0], "y":rel_pE[1],"v_x":0, "v_y":(float(F*rel_pE[0])/M_earth)**.5}
p_M = {"x":rel_pM[0], "y":rel_pM[1],"v_x":0, "v_y":(float(F*rel_pM[0])/M_moon)**.5}
print(p_E, p_M)
t = range(0,365)
data_E , data_M = [], []
def s(initial_velocity, acceleration, time):
result = initial_velocity*time + 0.5*acceleration*time**2
return result
def v(initial_velocity, acceleration, time):
result = initial_velocity + acceleration*time
return result
dist = float(sqrt((p_E["x"]-p_M['x'])**2 + (p_E["y"]-p_M["y"])**2))
xE=[]
yE=[]
xM=[]
yM=[]
data_E, data_M = [None]*len(t), [None]*len(t)
for i in range(1,366):
data_E[i-1] = p_E
data_M[i-1] = p_M
dist = ((p_E["x"]-p_M["x"])**2 + (p_E["y"]-p_M["y"])**2)**0.5
Fg = G*M_moon*M_earth/(dist**2)
theta_E = np.arctan(p_E["y"]/p_E["x"])
theta_M = theta_E + np.pi #np.arctan(data_M[i-1]["y"]/data_M[i-1]["x"])
Fx_E = Fg*np.cos(theta_E)
Fy_E = Fg*np.sin(theta_E)
Fx_M = Fg*np.cos(theta_M)
Fy_M = Fg*np.sin(theta_M)
a_E = Fg/M_earth
a_M = Fg/M_moon
v_E = (p_E["v_x"]**2+p_E["v_y"]**2)**.5
v_M = (p_M["v_x"]**2+p_M["v_y"]**2)**.5
p_E["v_x"] = v(p_E["v_x"], Fx_E/M_earth, 24*3600)
p_E["v_y"] = v(p_E["v_y"], Fy_E/M_earth, 24*3600)
p_E["x"] += s(p_E['v_x'], Fx_E/M_earth, 24*3600)
p_E["y"] += s(p_E['v_y'], Fy_E/M_earth, 24*3600)
p_M["v_x"] = v(p_M["v_x"], Fx_M/M_moon, 24*3600)
p_M["v_y"] = v(p_M["v_y"], Fy_M/M_moon, 24*3600)
p_M["x"] += s(p_M['v_x'], Fx_M/M_moon, 24*3600)
p_M["y"] += s(p_M['v_y'], Fy_M/M_moon, 24*3600)
for i in range(0,len(t)):
xE += data_E[i]["x"]
yE += data_E[i]["y"]
xM += data_M[i]["x"]
yM += data_M[i]["y"]
print("\n Run time \n --- %d seconds ---" %(time.time()-start_time))
after run this code i tried to print data_E and data_M.
Then I can get data but there is no difference. All of the data is the same.
But when I printed data step by step, it totally different.
I have wrong data problem and increase distance problem. Please help me this problem..
The code exits near line 45, where you are trying to assign p_E by pulling the square root of a negative number on the right hand side (as you've moved the [0] coordinate of the Earth to negative values while shifting Earth and Moon into the coordinate system of their center of mass). In line 45, the value of F*rel_pE[0]/M_earth is negative. So the code never reaches the end of the program using python 2.7.14. That bug needs to be solved before trying to discuss any further aspects.