def shutdown(rc): """Exits the script, but first flushes all logging handles, etc.""" # Close the Ephemeris so it can do necessary cleanups. Ephemeris.closeEphemeris() logging.shutdown() sys.exit(rc)
def write_ephemeris(doc: dominate.document): """ Write ephemeris in HTML document :param doc: Dominate document """ ephemeris = Ephemeris('data\\ephemeris-fr.json') today_eph = ephemeris.get_today_ephemeris() string_eph = today_eph[1] + ' ' + today_eph[0] if today_eph[ 1] else today_eph[0] doc.add(tags.h3(string_eph))
def shutdown(rc): """Exits the script, but first flushes all logging handles, etc.""" global taskQueue global numProcesses Ephemeris.closeEphemeris() # Tell spawned processes to end. for i in range(numProcesses): taskQueue.put("STOP") logging.shutdown() sys.exit(rc)
def getPlanetsForDatetimeAndTimezone(dt, locTuple): """Returns a string with the planet longitude position for the given datetime and timezone. """ locName = locTuple[0] locLongitude = locTuple[1] locLatitude = locTuple[2] locElevation = locTuple[3] # Set the Location (required). Ephemeris.setGeographicPosition(locLongitude, locLatitude, locElevation) longitudeType = "tropical" fieldName = "longitude" rv = "For datetime: " + Ephemeris.datetimeToDayStr(dt) + \ ", location: " + locName + endl for planetName in geocentricPlanetNames: pi = Ephemeris.getPlanetaryInfo(planetName, dt) longitude = pi.geocentric[longitudeType][fieldName] # Format differently for lunation phase of G.MoSu. if planetName == "MoSu": rv += " {: <14}".format("G." + planetName + ": ") + \ "{:>.3f}".format(longitude) + \ " Phase (of max 30): {:.2f}".format(longitude / 12.0) + \ endl else: rv += " {: <14}".format("G." + planetName + ": ") + \ "{:>.3f}".format(longitude) + \ endl rv += endl for planetName in heliocentricPlanetNames: pi = Ephemeris.getPlanetaryInfo(planetName, dt) rv += " {: <14}".format("H." + planetName + ": ") + \ "{:>.3f}".format(pi.heliocentric[longitudeType][fieldName]) + \ endl return rv
def formatToDateAndDetailedTimeStr(datetimeObj): """Returns a string representation of a datetime.datetime object. Normally we wouldn't need to do this, but the datetime.strftime() does not work on years less than 1900. Arguments: datetimeObj - datetime.datetime object with a tzinfo defined. Returns: String holding the info about the datetime.datetime object, in the datetime.strftime() format: "%Y-%m-%d %H:%M:%S %Z%z" """ # Timezone name string, extracted from datetime.tzname(). # This accounts for the fact that datetime.tzname() can return None. tznameStr = datetimeObj.tzname() if tznameStr == None: tznameStr = "" # Return the formatted string. return "{:04}-{:02}-{:02} {:02}:{:02} {}{}".\ format(datetimeObj.year, datetimeObj.month, datetimeObj.day, datetimeObj.hour, datetimeObj.minute, tznameStr, Ephemeris.getTimezoneOffsetFromDatetime(datetimeObj))
def getFieldValue(dt, planetParams, fieldName): """Creates the PlanetaryInfo object for the given planetParamsList and returns the value of the field desired. """ log.debug("planetParams passed in is: {}".\ format(planetParams)) t = planetParams planetName = t[0] centricityType = t[1] longitudeType = t[2] pi = Ephemeris.getPlanetaryInfo(planetName, dt) log.debug("Planet {} has geo sid longitude: {}".\ format(planetName, pi.geocentric["sidereal"]["longitude"])) fieldValue = None if centricityType.lower() == "geocentric": fieldValue = pi.geocentric[longitudeType][fieldName] elif centricityType.lower() == "topocentric": fieldValue = pi.topocentric[longitudeType][fieldName] elif centricityType.lower() == "heliocentric": fieldValue = pi.heliocentric[longitudeType][fieldName] else: log.error("Unknown centricity type: {}".\ format(centricityType)) fieldValue = None return fieldValue
def __init__(self, config_file_path): print("PyG V 0.0.1 .. ") # Déclaration des variables d'analyse self.coord_pivot = [0.0, 0.0, 0.0] self.coord_mobile = [0.0, 0.0, 0.0] self.seuil_snr = 0 self.seuil_elev_sat = 0 self.nav_data_file = "" self.obs_data_file = [] self.obs = [] # Tableau contient les observations par cube self.dd = [] # Structure contient les DD par cube self.parseConfigFile(config_file_path) self.eph = Ephemeris(self.nav_data_file) # Instanciation des Geocubes en utilisant la liste des paths renseignée dans le fichier de conf. for i in range(0,len(self.obs_data_file)): self.obs.append(Geocube(self.obs_data_file[i])) #self.cleanObservations() print("SEUIL SNR: "+str(self.seuil_snr)+"\n") print("SEUIL ELEVATION SATELLITE: " + str(self.seuil_elev_sat) + "\n") print("OBS FILE LIST: "+ str(self.obs_data_file) +"\n") self.buildDoubleDifferences()
def processPCDD(pcdd, tag): """Module for printing generic information about the PriceBars in a PriceChartDocumentData object. The generic information that is printed includes: - Earliest pricebar timestamp as a datetime.datetime and a julian day. - Latest pricebar timestamp as a datetime.datetime and a julian day. - highest pricebar high price. - lowest pricebar low price. Arguments: pcdd - PriceChartDocumentData object that will be modified. tag - str containing the tag. The value of this field may be "" if a tag is not specified by the user. This implementation doesn't use this field. Returns: 0 if the changes are to be saved to file. 1 if the changes are NOT to be saved to file. This implementation always returns 1. """ # Return value. rv = 1 # List of tuples of the form (datetime.datetime, price). priceTimeInfoTupleList = [] # Counting the number of PriceBarChartPriceTimeInfoArtifact objects. numPriceTimeInfoArtifacts = 0 # Scene used for datetime and price conversions. scene = PriceBarChartGraphicsScene() artifacts = pcdd.priceBarChartArtifacts for artifact in artifacts: if isinstance(artifact, PriceBarChartPriceTimeInfoArtifact): numPriceTimeInfoArtifacts += 1 infoPointF = artifact.getInfoPointF() dt = scene.sceneXPosToDatetime(infoPointF.x()) price = scene.sceneYPosToPrice(infoPointF.y()) priceTimeInfoTupleList.append((dt, price)) # Sort by timestamp, because when obtained they might not be in order: sortedPriceTimeInfoTupleList = sorted(priceTimeInfoTupleList, key=lambda tup: tup[0]) # Print out the timestamps and price. for tup in sortedPriceTimeInfoTupleList: dt = tup[0] price = tup[1] log.info("{},{}".format(Ephemeris.datetimeToDayStr(dt), price)) rv = 1 return rv
def getFieldValue(dt, planetParamsList, fieldName): """Creates the PlanetaryInfo object for the given planetParamsList and returns the value of the field desired. """ log.debug("planetParamsList passed in is: {}".\ format(planetParamsList)) unAveragedFieldValues = [] for t in planetParamsList: planetName = t[0] centricityType = t[1] longitudeType = t[2] pi = Ephemeris.getPlanetaryInfo(planetName, dt) log.debug("Planet {} has geo sid longitude: {}".\ format(planetName, pi.geocentric["sidereal"]["longitude"])) fieldValue = None if centricityType.lower() == "geocentric": fieldValue = pi.geocentric[longitudeType][fieldName] elif centricityType.lower() == "topocentric": fieldValue = pi.topocentric[longitudeType][fieldName] elif centricityType.lower() == "heliocentric": fieldValue = pi.heliocentric[longitudeType][fieldName] else: log.error("Unknown centricity type: {}".\ format(centricityType)) fieldValue = None unAveragedFieldValues.append(fieldValue) log.debug("unAveragedFieldValues is: {}".\ format(unAveragedFieldValues)) # Average the field values. total = 0.0 for v in unAveragedFieldValues: total += v averagedFieldValue = total / len(unAveragedFieldValues) log.debug("averagedFieldValue is: {}".\ format(averagedFieldValue)) return averagedFieldValue
def get_ephemeris(navigation_entry, satellite_name): satellite = navigation_entry.sel(sv=satellite_name) ephem_list = [] M0_array = satellite.get('M0').data deltaN_array = satellite.get('DeltaN').data sqrtA_array = satellite.get('sqrtA').data time_array = satellite.get('time').data e_array = satellite.get('Eccentricity').data omega_array = satellite.get('omega').data Crs_array = satellite.get('Crs').data Crc_array = satellite.get('Crc').data Cuc_array = satellite.get('Cuc').data Cus_array = satellite.get('Cus').data Cic_array = satellite.get('Cic').data Cis_array = satellite.get('Cis').data IDOT_array = satellite.get('IDOT').data Io_array = satellite.get('Io').data omega0_array = satellite.get('Omega0').data omegaDot_array = satellite.get('OmegaDot').data Toe_array = satellite.get('Toe').data for index, time in enumerate(time_array): M0 = M0_array[index] e = e_array[index] omega = omega_array[index] Crs = Crs_array[index] Crc = Crc_array[index] Cuc = Cuc_array[index] Cus = Cus_array[index] Cic = Cic_array[index] Cis = Cis_array[index] IDOT = IDOT_array[index] Io = Io_array[index] omega0 = omega0_array[index] omegaDot = omegaDot_array[index] deltaN = deltaN_array[index] sqrtA = sqrtA_array[index] Toe = Toe_array[index] if not np.isnan( np.array([ e, M0, deltaN, sqrtA, omega, Crs, Crc, Cuc, Cus, Cic, Cis, IDOT, Io, omega0, omegaDot, Toe ])).any(): ephemeris = Ephemeris(time, e, M0, deltaN, sqrtA, omega, Crs, Crc, Cuc, Cus, Cic, Cis, IDOT, Io, omega0, omegaDot, Toe) ephem_list.append(ephemeris) return ephem_list
if dt.year < 10: dateStr += "000{}".format(dt.year) elif dt.year < 100: dateStr += "00{}".format(dt.year) elif dt.year < 1000: dateStr += "0{}".format(dt.year) else: dateStr += "{}".format(dt.year) return dateStr ############################################################################## # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) text = "" text += getHeaderText() startDt = getStartDatetime() endDt = getEndDatetime() currDt = startDt prevDt = None while currDt < endDt:
def getOnePlanetLongitudeAspectTimestamps(\ startDt, endDt, planet1Params, fixedDegree, degreeDifference, uniDirectionalAspectsFlag=False, maxErrorTd=datetime.timedelta(hours=1)): """Obtains a list of datetime.datetime objects that contain the moments when the aspect specified is active. The aspect is measured by formula: (planet longitude) - (fixed longitude degree) Arguments: startDt - datetime.datetime object for the starting timestamp to do the calculations for artifacts. endDt - datetime.datetime object for the ending timestamp to do the calculations for artifacts. highPrice - float value for the high price to end the vertical line. lowPrice - float value for the low price to end the vertical line. planet1Params - Tuple containing: (planetName, centricityType, longitudeType) Where: planetName - str holding the name of the second planet to do the calculations for. centricityType - str value holding either "geocentric", "topocentric", or "heliocentric". longitudeType - str value holding either "tropical" or "sidereal". fixedDegree - float holding the fixed degree in the zodiac circle. degreeDifference - float value for the number of degrees of separation for this aspect. uniDirectionalAspectsFlag - bool value for whether or not uni-directional aspects are enabled or not. By default, aspects are bi-directional, so Saturn square-aspect Jupiter would be the same as Jupiter square-aspect Saturn. If this flag is set to True, then those two combinations would be considered unique. In the case where the flag is set to True, for the aspect to be active, planet2 would need to be 'degreeDifference' degrees in front of planet1. maxErrorTd - datetime.timedelta object holding the maximum time difference between the exact planetary combination timestamp, and the one calculated. This would define the accuracy of the calculations. Returns: List of datetime.datetime objects. Each timestamp in the list is the moment where the aspect is active and satisfies the given parameters. In the event of an error, the reference None is returned. """ log.debug("Entered " + inspect.stack()[0][3] + "()") # List of timestamps of the aspects found. aspectTimestamps = [] # Make sure the inputs are valid. if endDt < startDt: log.error("Invalid input: 'endDt' must be after 'startDt'") return None # Check to make sure planet params were given. if len(planet1Params) != 3: log.error("planet1Params must be a tuple with 3 elements.") return None if not isinstance(fixedDegree, (int, float, complex)): log.error("fixedDegree must be a number.") return None # Normalize the fixed degree. fixedDegree = Util.toNormalizedAngle(fixedDegree) log.debug("planet1Params passed in is: {}".\ format(planet1Params)) log.debug("fixedDegree passed in is: {}".\ format(fixedDegree)) # Check inputs of planet parameters. planetName = planet1Params[0] centricityType = planet1Params[1] longitudeType = planet1Params[2] # Check inputs for centricity type. loweredCentricityType = centricityType.lower() if loweredCentricityType != "geocentric" and \ loweredCentricityType != "topocentric" and \ loweredCentricityType != "heliocentric": log.error("Invalid input: Centricity type is invalid. " + \ "Value given was: {}".format(centricityType)) return None # Check inputs for longitude type. loweredLongitudeType = longitudeType.lower() if loweredLongitudeType != "tropical" and \ loweredLongitudeType != "sidereal": log.error("Invalid input: Longitude type is invalid. " + \ "Value given was: {}".format(longitudeType)) return None # Field name we are getting. fieldName = "longitude" # Initialize the Ephemeris with the birth location. log.debug("Setting ephemeris location ...") Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Set the step size. stepSizeTd = datetime.timedelta(days=1) planetName = planet1Params[0] if Ephemeris.isHouseCuspPlanetName(planetName) or \ Ephemeris.isAscmcPlanetName(planetName): # House cusps and ascmc planets need a smaller step size. stepSizeTd = datetime.timedelta(hours=1) elif planetName == "Moon": # Use a smaller step size for the moon so we can catch # smaller aspect sizes. stepSizeTd = datetime.timedelta(hours=3) log.debug("Step size is: {}".format(stepSizeTd)) # Desired angles. We need to check for planets at these angles. desiredAngleDegList = [] desiredAngleDeg1 = Util.toNormalizedAngle(degreeDifference) desiredAngleDegList.append(desiredAngleDeg1) if Util.fuzzyIsEqual(desiredAngleDeg1, 0): desiredAngleDegList.append(360) if uniDirectionalAspectsFlag == False: desiredAngleDeg2 = \ 360 - Util.toNormalizedAngle(degreeDifference) if desiredAngleDeg2 not in desiredAngleDegList: desiredAngleDegList.append(desiredAngleDeg2) # Debug output. anglesStr = "" for angle in desiredAngleDegList: anglesStr += "{} ".format(angle) log.debug("Angles in desiredAngleDegList: " + anglesStr) # Iterate through, appending to aspectTimestamps list as we go. steps = [] steps.append(copy.deepcopy(startDt)) steps.append(copy.deepcopy(startDt)) longitudesP1 = [] longitudesP1.append(None) longitudesP1.append(None) longitudesP2 = [] longitudesP2.append(None) longitudesP2.append(None) def getFieldValue(dt, planetParams, fieldName): """Creates the PlanetaryInfo object for the given planetParamsList and returns the value of the field desired. """ log.debug("planetParams passed in is: {}".\ format(planetParams)) t = planetParams planetName = t[0] centricityType = t[1] longitudeType = t[2] pi = Ephemeris.getPlanetaryInfo(planetName, dt) log.debug("Planet {} has geo sid longitude: {}".\ format(planetName, pi.geocentric["sidereal"]["longitude"])) fieldValue = None if centricityType.lower() == "geocentric": fieldValue = pi.geocentric[longitudeType][fieldName] elif centricityType.lower() == "topocentric": fieldValue = pi.topocentric[longitudeType][fieldName] elif centricityType.lower() == "heliocentric": fieldValue = pi.heliocentric[longitudeType][fieldName] else: log.error("Unknown centricity type: {}".\ format(centricityType)) fieldValue = None return fieldValue log.debug("Stepping through timestamps from {} to {} ...".\ format(Ephemeris.datetimeToStr(startDt), Ephemeris.datetimeToStr(endDt))) currDiff = None prevDiff = None while steps[-1] < endDt: currDt = steps[-1] prevDt = steps[-2] log.debug("Looking at currDt == {} ...".\ format(Ephemeris.datetimeToStr(currDt))) longitudesP1[-1] = \ Util.toNormalizedAngle(\ getFieldValue(currDt, planet1Params, fieldName)) longitudesP2[-1] = fixedDegree log.debug("{} {} is: {}".\ format(planet1Params, fieldName, longitudesP1[-1])) log.debug("fixedDegree is: {}".format(longitudesP2[-1])) currDiff = Util.toNormalizedAngle(\ longitudesP1[-1] - longitudesP2[-1]) log.debug("prevDiff == {}".format(prevDiff)) log.debug("currDiff == {}".format(currDiff)) if prevDiff != None and \ longitudesP1[-2] != None and \ longitudesP2[-2] != None: if abs(prevDiff - currDiff) > 180: # Probably crossed over 0. Adjust the prevDiff so # that the rest of the algorithm can continue to # work. if prevDiff > currDiff: prevDiff -= 360 else: prevDiff += 360 log.debug("After adjustment: prevDiff == {}".\ format(prevDiff)) log.debug("After adjustment: currDiff == {}".\ format(currDiff)) for desiredAngleDeg in desiredAngleDegList: log.debug("Looking at desiredAngleDeg: {}".\ format(desiredAngleDeg)) desiredDegree = desiredAngleDeg if prevDiff < desiredDegree and currDiff >= desiredDegree: log.debug("Crossed over {} from below to above!".\ format(desiredDegree)) # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than # the threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. timeWindowTd = t2 - t1 halfTimeWindowTd = \ datetime.\ timedelta(days=(timeWindowTd.days / 2.0), seconds=(timeWindowTd.seconds / 2.0), microseconds=\ (timeWindowTd.microseconds / 2.0)) testDt = t1 + halfTimeWindowTd testValueP1 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet1Params, fieldName)) testValueP2 = \ Util.toNormalizedAngle(fixedDegree) log.debug("testValueP1 == {}".format(testValueP1)) log.debug("testValueP2 == {}".format(testValueP2)) if longitudesP1[-2] > 240 and testValueP1 < 120: # Planet 1 hopped over 0 degrees. testValueP1 += 360 elif longitudesP1[-2] < 120 and testValueP1 > 240: # Planet 1 hopped over 0 degrees. testValueP1 -= 360 if longitudesP2[-2] > 240 and testValueP2 < 120: # Planet 2 hopped over 0 degrees. testValueP2 += 360 elif longitudesP2[-2] < 120 and testValueP2 > 240: # Planet 2 hopped over 0 degrees. testValueP2 -= 360 testDiff = Util.toNormalizedAngle(\ testValueP1 - testValueP2) # Handle special cases of degrees 0 and 360. # Here we adjust testDiff so that it is in the # expected ranges. if Util.fuzzyIsEqual(desiredDegree, 0): if testDiff > 240: testDiff -= 360 elif Util.fuzzyIsEqual(desiredDegree, 360): if testDiff < 120: testDiff += 360 log.debug("testDiff == {}".format(testDiff)) if testDiff < desiredDegree: t1 = testDt else: t2 = testDt # Update the curr values. currDt = t2 currDiff = testDiff longitudesP1[-1] = testValueP1 longitudesP2[-1] = testValueP2 currErrorTd = t2 - t1 # Update our lists. steps[-1] = currDt # Store the aspect timestamp. aspectTimestamps.append(currDt) elif prevDiff > desiredDegree and currDiff <= desiredDegree: log.debug("Crossed over {} from above to below!".\ format(desiredDegree)) # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than # the threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. timeWindowTd = t2 - t1 halfTimeWindowTd = \ datetime.\ timedelta(days=(timeWindowTd.days / 2.0), seconds=(timeWindowTd.seconds / 2.0), microseconds=\ (timeWindowTd.microseconds / 2.0)) testDt = t1 + halfTimeWindowTd testValueP1 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet1ParamsList, fieldName)) testValueP2 = \ Util.toNormalizedAngle(fixedDegree) log.debug("testValueP1 == {}".format(testValueP1)) log.debug("testValueP2 == {}".format(testValueP2)) if longitudesP1[-2] > 240 and testValueP1 < 120: # Planet 1 hopped over 0 degrees. testValueP1 += 360 elif longitudesP1[-2] < 120 and testValueP1 > 240: # Planet 1 hopped over 0 degrees. testValueP1 -= 360 if longitudesP2[-2] > 240 and testValueP2 < 120: # Planet 2 hopped over 0 degrees. testValueP2 += 360 elif longitudesP2[-2] < 120 and testValueP2 > 240: # Planet 2 hopped over 0 degrees. testValueP2 -= 360 testDiff = Util.toNormalizedAngle(\ testValueP1 - testValueP2) # Handle special cases of degrees 0 and 360. # Here we adjust testDiff so that it is in the # expected ranges. if Util.fuzzyIsEqual(desiredDegree, 0): if testDiff > 240: testDiff -= 360 elif Util.fuzzyIsEqual(desiredDegree, 360): if testDiff < 120: testDiff += 360 log.debug("testDiff == {}".format(testDiff)) if testDiff > desiredDegree: t1 = testDt else: t2 = testDt # Update the curr values. currDt = t2 currDiff = testDiff longitudesP1[-1] = testValueP1 longitudesP2[-1] = testValueP2 currErrorTd = t2 - t1 # Update our lists. steps[-1] = currDt # Store the aspect timestamp. aspectTimestamps.append(currDt) # Prepare for the next iteration. log.debug("steps[-1] is: {}".\ format(Ephemeris.datetimeToStr(steps[-1]))) log.debug("stepSizeTd is: {}".format(stepSizeTd)) steps.append(copy.deepcopy(steps[-1]) + stepSizeTd) del steps[0] longitudesP1.append(None) del longitudesP1[0] longitudesP2.append(None) del longitudesP2[0] # Update prevDiff as the currDiff. prevDiff = Util.toNormalizedAngle(currDiff) log.debug("Number of timestamps obtained: {}".\ format(len(aspectTimestamps))) log.debug("Exiting " + inspect.stack()[0][3] + "()") return aspectTimestamps
def getPlanetaryInfosForDatetime(dt, birthInfo): """Helper function for getting a list of PlanetaryInfo objects to display in the astrology chart. """ # Set the location again (required). Ephemeris.setGeographicPosition(birthInfo.longitudeDegrees, birthInfo.latitudeDegrees, birthInfo.elevation) # Get planetary info for all the planets. planets = [] # Astrological house system for getting the house cusps. houseSystem = Ephemeris.HouseSys['Porphyry'] #planets.append(Ephemeris.getH1PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH2PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH3PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH4PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH5PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH6PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH7PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH8PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH9PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH10PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH11PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH12PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getARMCPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getVertexPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getEquatorialAscendantPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getCoAscendant1PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getCoAscendant2PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getPolarAscendantPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getHoraLagnaPlanetaryInfo(dt)) #planets.append(Ephemeris.getGhatiLagnaPlanetaryInfo(dt)) #planets.append(Ephemeris.getMeanLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getOsculatingLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getInterpolatedLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getInterpolatedLunarPerigeePlanetaryInfo(dt)) planets.append(Ephemeris.getSunPlanetaryInfo(dt)) planets.append(Ephemeris.getMoonPlanetaryInfo(dt)) planets.append(Ephemeris.getMercuryPlanetaryInfo(dt)) planets.append(Ephemeris.getVenusPlanetaryInfo(dt)) planets.append(Ephemeris.getEarthPlanetaryInfo(dt)) planets.append(Ephemeris.getMarsPlanetaryInfo(dt)) planets.append(Ephemeris.getJupiterPlanetaryInfo(dt)) planets.append(Ephemeris.getSaturnPlanetaryInfo(dt)) planets.append(Ephemeris.getUranusPlanetaryInfo(dt)) planets.append(Ephemeris.getNeptunePlanetaryInfo(dt)) planets.append(Ephemeris.getPlutoPlanetaryInfo(dt)) planets.append(Ephemeris.getMeanNorthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getTrueSouthNodePlanetaryInfo(dt)) planets.append(Ephemeris.getTrueNorthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getTrueSouthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getCeresPlanetaryInfo(dt)) #planets.append(Ephemeris.getPallasPlanetaryInfo(dt)) #planets.append(Ephemeris.getJunoPlanetaryInfo(dt)) #planets.append(Ephemeris.getVestaPlanetaryInfo(dt)) planets.append(Ephemeris.getIsisPlanetaryInfo(dt)) #planets.append(Ephemeris.getNibiruPlanetaryInfo(dt)) planets.append(Ephemeris.getChironPlanetaryInfo(dt)) #planets.append(Ephemeris.getGulikaPlanetaryInfo(dt)) #planets.append(Ephemeris.getMandiPlanetaryInfo(dt)) planets.append(Ephemeris.getMeanOfFivePlanetaryInfo(dt)) planets.append(Ephemeris.getCycleOfEightPlanetaryInfo(dt)) planets.append(Ephemeris.getAvgMaJuSaUrNePlPlanetaryInfo(dt)) planets.append(Ephemeris.getAvgJuSaUrNePlanetaryInfo(dt)) planets.append(Ephemeris.getAvgJuSaPlanetaryInfo(dt)) return planets
def getPlanetaryInfosForDatetime(dt): """Helper function for getting a list of PlanetaryInfo objects to display in the astrology chart. """ # Set the location again (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Get planetary info for all the planets. planets = [] # Astrological house system for getting the house cusps. houseSystem = Ephemeris.HouseSys['Porphyry'] planets.append(Ephemeris.getH1PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH2PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH3PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH4PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH5PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH6PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH7PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH8PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH9PlanetaryInfo(dt, houseSystem)) planets.append(Ephemeris.getH10PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH11PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getH12PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getARMCPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getVertexPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getEquatorialAscendantPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getCoAscendant1PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getCoAscendant2PlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getPolarAscendantPlanetaryInfo(dt, houseSystem)) #planets.append(Ephemeris.getHoraLagnaPlanetaryInfo(dt)) #planets.append(Ephemeris.getGhatiLagnaPlanetaryInfo(dt)) #planets.append(Ephemeris.getMeanLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getOsculatingLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getInterpolatedLunarApogeePlanetaryInfo(dt)) #planets.append(Ephemeris.getInterpolatedLunarPerigeePlanetaryInfo(dt)) planets.append(Ephemeris.getSunPlanetaryInfo(dt)) planets.append(Ephemeris.getMoonPlanetaryInfo(dt)) planets.append(Ephemeris.getMercuryPlanetaryInfo(dt)) planets.append(Ephemeris.getVenusPlanetaryInfo(dt)) planets.append(Ephemeris.getEarthPlanetaryInfo(dt)) planets.append(Ephemeris.getMarsPlanetaryInfo(dt)) planets.append(Ephemeris.getJupiterPlanetaryInfo(dt)) planets.append(Ephemeris.getSaturnPlanetaryInfo(dt)) planets.append(Ephemeris.getUranusPlanetaryInfo(dt)) planets.append(Ephemeris.getNeptunePlanetaryInfo(dt)) planets.append(Ephemeris.getPlutoPlanetaryInfo(dt)) planets.append(Ephemeris.getMeanNorthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getTrueSouthNodePlanetaryInfo(dt)) planets.append(Ephemeris.getTrueNorthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getTrueSouthNodePlanetaryInfo(dt)) #planets.append(Ephemeris.getCeresPlanetaryInfo(dt)) #planets.append(Ephemeris.getPallasPlanetaryInfo(dt)) #planets.append(Ephemeris.getJunoPlanetaryInfo(dt)) #planets.append(Ephemeris.getVestaPlanetaryInfo(dt)) planets.append(Ephemeris.getIsisPlanetaryInfo(dt)) #planets.append(Ephemeris.getNibiruPlanetaryInfo(dt)) planets.append(Ephemeris.getChironPlanetaryInfo(dt)) #planets.append(Ephemeris.getGulikaPlanetaryInfo(dt)) #planets.append(Ephemeris.getMandiPlanetaryInfo(dt)) #planets.append(Ephemeris.getMeanOfFivePlanetaryInfo(dt)) #planets.append(Ephemeris.getCycleOfEightPlanetaryInfo(dt)) #planets.append(Ephemeris.getAvgMaJuSaUrNePlPlanetaryInfo(dt)) #planets.append(Ephemeris.getAvgJuSaUrNePlanetaryInfo(dt)) #planets.append(Ephemeris.getAvgJuSaPlanetaryInfo(dt)) return planets
def getEphemerisDataLineForDatetime(dt): """Obtains the line of CSV text of planetary position data. Arguments: dt - datetime.datetime object with the timestamp seeked. Returns: str in CSV format. Since there are a lot of fields, please See the section of code where we write the header info str for the format. """ # Return value. rv = "" planetaryInfos = getPlanetaryInfosForDatetime(dt) log.debug("Just obtained planetaryInfos for timestamp: {}".\ format(Ephemeris.datetimeToStr(dt))) # Planet geocentric longitude 15-degree axis points. for planetName in geocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] rv += "{:.3f},".format(lon % 15.0) # Planet geocentric longitude. for planetName in geocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] rv += "{:.3f},".format(lon) # Planet geocentric longitude in zodiac str format. for planetName in geocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] valueStr = \ AstrologyUtils.\ convertLongitudeToStrWithRasiAbbrev(lon) rv += valueStr + "," # Planet heliocentric longitude 15-degree axis points. for planetName in heliocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.heliocentric['tropical']['longitude'] rv += "{:.3f},".format(lon % 15.0) # Planet heliocentric longitude. for planetName in heliocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.heliocentric['tropical']['longitude'] rv += "{:.3f},".format(lon) # Planet heliocentric longitude in zodiac str format. for planetName in heliocentricPlanetNames: for pi in planetaryInfos: if pi.name == planetName: lon = pi.heliocentric['tropical']['longitude'] valueStr = \ AstrologyUtils.\ convertLongitudeToStrWithRasiAbbrev(lon) rv += valueStr + "," # Planet declination. for planetName in declinationPlanetNames: for pi in planetaryInfos: if pi.name == planetName: declination = pi.geocentric['tropical']['declination'] rv += "{:.3f},".format(declination) # Planet geocentric latitude. for planetName in geocentricLatitudePlanetNames: for pi in planetaryInfos: if pi.name == planetName: latitude = pi.geocentric['tropical']['latitude'] rv += "{:.3f},".format(latitude) # Planet heliocentric latitude. for planetName in heliocentricLatitudePlanetNames: for pi in planetaryInfos: if pi.name == planetName: latitude = pi.heliocentric['tropical']['latitude'] rv += "{:.3f},".format(latitude) # Remove trailing comma. rv = rv[:-1] return rv
# For logging. import logging import logging.config # Import the Ephemeris classes. from ephemeris import PlanetaryInfo from ephemeris import Ephemeris # Initialize logging. LOG_CONFIG_FILE = os.path.join(sys.path[0], "../conf/logging.conf") logging.config.fileConfig(LOG_CONFIG_FILE) #logging.disable(logging.CRITICAL) # Initialize the Ephemeris (required). Ephemeris.initialize() # New York City: lon = -74.0064 lat = 40.7142 # Set a default location (required). Ephemeris.setGeographicPosition(lon, lat) # Create the Qt application. #app = QApplication(sys.argv) # Various tests to run: def runTests():
# Update prevDiff as the currDiff. prevDiff = Util.toNormalizedAngle(currDiff) log.debug("Number of timestamps obtained: {}".\ format(len(aspectTimestamps))) log.debug("Exiting " + inspect.stack()[0][3] + "()") return aspectTimestamps ############################################################################## #if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Log the parameters that are being used. log.info("Location used is: {} (lat={}, lon={})".\ format(locationName, locationLatitude, locationLongitude)) log.info("Timezone used is: {}".format(timezone.zone)) log.info("Start timestamp: {}".format(Ephemeris.datetimeToStr(startDt))) log.info("End timestamp: {}".format(Ephemeris.datetimeToStr(endDt))) # Compile the header line text. headerLine = ""
def getGeocentricPlanetDirectRetrogradeInfo(planetName): """ Returns a list of tuples, each tuple containing: (planetName, julianDay, datetime, "R" or "D", geoTropLongitudeOfPlanet, geoSidLongitudeOfPlanet) """ # Return value. rv = [] prevDt = None currDt = copy.deepcopy(startDt) prevTropLongitudeSpeed = None currTropLongitudeSpeed = None currTropLongitude = None currSidLongitude = None while currDt <= endDt: dt = currDt pi = Ephemeris.getPlanetaryInfo(planetName, dt) log.debug("Just obtained planetaryInfo for planet '{}', timestamp: {}".\ format(planetName, Ephemeris.datetimeToStr(dt))) # Get the geocentric longitude and geocentric longitude speed. tropLongitudeSpeed = pi.geocentric['tropical']['longitude_speed'] tropLongitude = pi.geocentric['tropical']['longitude'] sidLongitude = pi.geocentric['sidereal']['longitude'] # Store new current planet values. currTropLongitudeSpeed = tropLongitudeSpeed currTropLongitude = tropLongitude currSidLongitude = sidLongitude log.debug("prevTropLongitudeSpeed={}, currTropLongitudeSpeed={}".\ format(prevTropLongitudeSpeed, currTropLongitudeSpeed)) # We need two data points to proceed. if prevTropLongitudeSpeed != None and \ currTropLongitudeSpeed != None and \ prevDt != None: # Check to see if we passed over 0 degrees. if prevTropLongitudeSpeed < 0.0 and currTropLongitudeSpeed >= 0.0: # Crossed over from negative to positive! log.debug("Crossed over from negative to positive!") # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than the # desired threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. diffTd = t2 - t1 halfDiffTd = \ datetime.\ timedelta(days=(diffTd.days / 2.0), seconds=(diffTd.seconds / 2.0), microseconds=(diffTd.microseconds / 2.0)) testDt = t1 + halfDiffTd pi = Ephemeris.getPlanetaryInfo(planetName, testDt) testTropLongitudeSpeed = \ pi.geocentric['tropical']['longitude_speed'] testTropLongitude = pi.geocentric['tropical']['longitude'] testSidLongitude = pi.geocentric['sidereal']['longitude'] if testTropLongitudeSpeed >= 0.0: t2 = testDt # Update the curr values as the later boundary. currDt = t2 currTropLongitudeSpeed = testTropLongitudeSpeed currTropLongitude = testTropLongitude currSidLongitude = testSidLongitude else: t1 = testDt currErrorTd = t2 - t1 # Broke out of while loop, meaning we have a timestamp # within our threshold. # Create a tuple to add to our list. tup = (planetName, Ephemeris.datetimeToJulianDay(currDt), currDt, directStr, currTropLongitude, currSidLongitude) # Append to the list. rv.append(tup) elif prevTropLongitudeSpeed > 0.0 and currTropLongitudeSpeed <= 0.0: # Crossed over from positive to negative! log.debug("Crossed over from positive to negative!") # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than the # desired threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. diffTd = t2 - t1 halfDiffTd = \ datetime.\ timedelta(days=(diffTd.days / 2.0), seconds=(diffTd.seconds / 2.0), microseconds=(diffTd.microseconds / 2.0)) testDt = t1 + halfDiffTd pi = Ephemeris.getPlanetaryInfo(planetName, testDt) testTropLongitudeSpeed = \ pi.geocentric['tropical']['longitude_speed'] testTropLongitude = pi.geocentric['tropical']['longitude'] testSidLongitude = pi.geocentric['sidereal']['longitude'] if testTropLongitudeSpeed <= 0.0: t2 = testDt # Update the curr values as the later boundary. currDt = t2 currTropLongitudeSpeed = testTropLongitudeSpeed currTropLongitude = testTropLongitude currSidLongitude = testSidLongitude else: t1 = testDt currErrorTd = t2 - t1 # Broke out of while loop, meaning we have a timestamp # within our threshold. # Create a tuple to add to our list. tup = (planetName, Ephemeris.datetimeToJulianDay(currDt), currDt, retrogradeStr, currTropLongitude, currSidLongitude) # Append to the list. rv.append(tup) # Increment currDt timestamp. prevDt = currDt currDt = currDt + stepSizeTd # Move the previous currTropLongitudeSpeed to prevTropLongitudeSpeed. prevTropLongitudeSpeed = currTropLongitudeSpeed currTropLongitudeSpeed = None currTropLongitude = None currSidLongitude = None log.debug("prevTropLongitudeSpeed={}, currTropLongitudeSpeed={}".\ format(prevTropLongitudeSpeed, currTropLongitudeSpeed)) return rv
def processPCDD(pcdd, tag): """Module for drawing two veritcal lines (line segments) at 1/3 and 2/3 of the way through the price chart. The lines will have a tag str matching the given tag parameter. Arguments: pcdd - PriceChartDocumentData object that will be modified. tag - str containing the tag. Returns: 0 if the changes are to be saved to file. 1 if the changes are NOT to be saved to file. """ # Return value. rv = 0 # Check input. if tag == None or tag == "": log.error("Must specify a non-empty tag str value.") rv = 1 return rv # Get the earliest and latest PriceBar. earliestPriceBar = None latestPriceBar = None lowestPrice = None highestPrice = None for pb in pcdd.priceBars: if earliestPriceBar == None: earliestPriceBar = pb elif pb.timestamp < earliestPriceBar.timestamp: earliestPriceBar = pb if latestPriceBar == None: latestPriceBar = pb elif pb.timestamp > latestPriceBar.timestamp: latestPriceBar = pb if lowestPrice == None: lowestPrice = pb.low elif pb.low < lowestPrice: lowestPrice = pb.low if highestPrice == None: highestPrice = pb.high elif pb.high > highestPrice: highestPrice = pb.high if earliestPriceBar == None or \ latestPriceBar == None or \ lowestPrice == None or \ highestPrice == None: log.info("No pricebars were found in the document. " + \ "Not doing anything.") rv = 1 return rv # Convert the datetimes to julian day. earliestPriceBarJd = \ Ephemeris.datetimeToJulianDay(earliestPriceBar.timestamp) latestPriceBarJd = \ Ephemeris.datetimeToJulianDay(latestPriceBar.timestamp) log.debug("earliestPriceBar.timestamp == {}".\ format(Ephemeris.datetimeToStr(earliestPriceBar.timestamp))) log.debug("latestPriceBar.timestamp == {}".\ format(Ephemeris.datetimeToStr(latestPriceBar.timestamp))) log.debug("earliestPriceBarJd == {}".format(earliestPriceBarJd)) log.debug("latestPriceBarJd == {}".format(latestPriceBarJd)) diff = latestPriceBarJd - earliestPriceBarJd jdLine1 = earliestPriceBarJd + (diff / 3) jdLine2 = earliestPriceBarJd + ((diff / 3) * 2) dtLine1 = Ephemeris.julianDayToDatetime(jdLine1) dtLine2 = Ephemeris.julianDayToDatetime(jdLine2) log.debug("Creating scene...") # Scene for conversion functions. scene = PriceBarChartGraphicsScene() log.debug("Converting dt to x...") line1X = scene.datetimeToSceneXPos(dtLine1) line2X = scene.datetimeToSceneXPos(dtLine2) log.debug("Converting price to y...") lowY = scene.priceToSceneYPos(lowestPrice) highY = scene.priceToSceneYPos(highestPrice) log.debug("Creating line1 artifact ...") line1Artifact = PriceBarChartLineSegmentArtifact() line1Artifact.addTag(tag) line1Artifact.setTiltedTextFlag(False) line1Artifact.setAngleTextFlag(False) line1Artifact.setColor(QColor(Qt.red)) line1Artifact.setStartPointF(QPointF(line1X, lowY)) line1Artifact.setEndPointF(QPointF(line1X, highY)) log.debug("Creating line2 artifact ...") line2Artifact = PriceBarChartLineSegmentArtifact() line2Artifact.addTag(tag) line2Artifact.setTiltedTextFlag(False) line2Artifact.setAngleTextFlag(False) line2Artifact.setColor(QColor(Qt.blue)) line2Artifact.setStartPointF(QPointF(line2X, lowY)) line2Artifact.setEndPointF(QPointF(line2X, highY)) log.debug("Appending two lines...") pcdd.priceBarChartArtifacts.append(line1Artifact) pcdd.priceBarChartArtifacts.append(line2Artifact) log.debug("Done appending two lines.") rv = 0 return rv
def generateOutputFileCsvStr(priceBars, descriptionStr): """Takes a list of PriceBar objects and generates a CSV str containing the same data and planet location information. Arguments: priceBars - list of PriceBar objects. Each of the PriceBar objects in this list have timestamp and timezone information set. descriptionStr - str containing text that describes the trading entity and other descriptive text for the data. This str will be part of the outputted CSV str. Returns: str value for the output CSV text. """ geocentricPlanetNameList = [\ "Sun", "Mercury", "Venus", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Chiron", "TrueNorthNode", #"Isis", ] endl = "\n" # Return value. rv = "" rv += "Description: {}".\ format(descriptionStr) + endl # Column headers. rv += "jd,day,date,time,timezone,tags,open,high,low,close,volume,oi" # Add the columns headers for the Geocentric planets' longitude. # Here we do it twice because the first set is the 15-degree axis # reduction, and the second set is the actual planet positions. for planetName in geocentricPlanetNameList: rv += ",G." + planetName for planetName in geocentricPlanetNameList: rv += ",G." + planetName rv += endl for pb in priceBars: # Field: jd rv += "{}".format(Ephemeris.datetimeToJulianDay(pb.timestamp)) rv += "," # Timezone name string, extracted from datetime.tzname(). # This accounts for the fact that datetime.tzname() can return None. datetimeObj = pb.timestamp tznameStr = datetimeObj.tzname() if tznameStr == None: tznameStr = "" dayOfWeekStr = datetimeObj.ctime()[0:3] offsetStr = \ Ephemeris.getTimezoneOffsetFromDatetime(datetimeObj) # Field: day rv += dayOfWeekStr rv += "," # Field: date rv += "{:04}-{:02}-{:02}".\ format(datetimeObj.year, datetimeObj.month, datetimeObj.day) #rv += "{:02}/{:02}/{:04}".\ # format(datetimeObj.month, # datetimeObj.day, # datetimeObj.year) rv += "," # Field: time rv += "{:02}:{:02}:{:02}".\ format(datetimeObj.hour, datetimeObj.minute, datetimeObj.second) rv += "," # Field: timezone. rv += "{}{}".format(tznameStr, offsetStr) rv += "," # Field: tags for tag in pb.tags: rv += tag + " " rv += "," # Field: open rv += "{}".format(pb.open) rv += "," # Field: high rv += "{}".format(pb.high) rv += "," # Field: low rv += "{}".format(pb.low) rv += "," # Field: close rv += "{}".format(pb.close) rv += "," # Field: volume rv += "{}".format(pb.vol) rv += "," # Field: oi rv += "{}".format(pb.oi) rv += "," # Get PlanetaryInfos for this timestamp. planetaryInfos = \ getPlanetaryInfosForDatetime(pb.timestamp) # Fields of the geocentric planets' longitude 15-degree axis points. for planetName in geocentricPlanetNameList: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] rv += "{:6.3f},".format(lon % 15.0) break # Fields of the geocentric planets' longitude. for planetName in geocentricPlanetNameList: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] valueStr = AstrologyUtils.\ convertLongitudeToStrWithRasiAbbrev(lon) rv += "{},".format(valueStr) break # Chop off the last trailing comma. rv = rv[:-1] rv += endl return rv
class Analyzer: ########################################################################### def __init__(self, config_file_path): print("PyG V 0.0.1 .. ") # Déclaration des variables d'analyse self.coord_pivot = [0.0, 0.0, 0.0] self.coord_mobile = [0.0, 0.0, 0.0] self.seuil_snr = 0 self.seuil_elev_sat = 0 self.nav_data_file = "" self.obs_data_file = [] self.obs = [] # Tableau contient les observations par cube self.dd = [] # Structure contient les DD par cube self.parseConfigFile(config_file_path) self.eph = Ephemeris(self.nav_data_file) # Instanciation des Geocubes en utilisant la liste des paths renseignée dans le fichier de conf. for i in range(0,len(self.obs_data_file)): self.obs.append(Geocube(self.obs_data_file[i])) #self.cleanObservations() print("SEUIL SNR: "+str(self.seuil_snr)+"\n") print("SEUIL ELEVATION SATELLITE: " + str(self.seuil_elev_sat) + "\n") print("OBS FILE LIST: "+ str(self.obs_data_file) +"\n") self.buildDoubleDifferences() ########################################################################### def parseConfigFile(self, config_file_path): """Fonction pour parser le fichier de configuration""" parser = SafeConfigParser() parser.read(config_file_path) self.seuil_snr = int(parser.get('seuils', 'snr')) self.seuil_elev_sat = int(parser.get('seuils','sat_elevation')) # nav data path self.nav_data_file = parser.get('data','nav') self.coord_pivot = [float(parser.get('data','x_pivot')), float(parser.get('data','y_pivot')), float(parser.get('data','z_pivot'))] self.coord_mobile = [float(parser.get('data','x_mobile')), float(parser.get('data','y_mobile')), float(parser.get('data','z_mobile'))] # obs data paths self.obs_data_file = parser.get('data','obs').split(",") ########################################################################### def simpleDifference(self, phase_r1_s1, phase_r1_s2): """Fonction pour calculer les simples differences""" sd = phase_r1_s1 - phase_r1_s2 return sd ########################################################################### def cleanObservations(self): j=0 """Fonction pour supprimer les observations qui ne respectent pas les seuils""" for i in range(0, len(self.obs)): # Suppression des données avec SNR for raw in self.obs[i].rxm_raw: j+=1 if raw[9] <= self.seuil_snr: self.obs[i].rxm_raw = np.delete(self.obs[i].rxm_raw, j) j-=1 def doubleDifference(self, phase_r1_s1, phase_r1_s2, phase_r2_s1, phase_r2_s2): """Fonction pour calculer les doubles differences""" dd = self.simpleDifference(phase_r1_s1, phase_r1_s2) - self.simpleDifference(phase_r2_s1, phase_r2_s2) return dd def getRo(self, x_sat, y_sat, z_sat, x_rec, y_rec, z_rec): """Calculer la pseudo distance entre le recepteur et le satellite""" return math.sqrt(pow(x_sat - x_rec, 2) + pow(y_sat - y_rec, 2) + pow(z_sat - z_rec, 2)) def getRMS(self, phase_double_difference, pseudorange_double_difference): """Fonction pour calculer le RMS""" return (phase_double_difference - (1/LAMBDA_L1 * pseudorange_double_difference + math.floor(phase_double_difference - 1/LAMBDA_L1 * pseudorange_double_difference))) ########################################################################### def sat_rec_vector(self, x_s, y_s, z_s, x_r, y_r, z_r): """Calculer le vecteur recepteur -> satellite""" V = [] V.append(x_s - x_r) V.append(y_s - y_r) V.append(z_s - z_r) return V ########################################################################### def buildDoubleDifferences(self): """Construire les doubles differences""" coord_sat_tmp = [0.0, 0.0, 0.0] t = Timing() flag = 0 # Il faut d'abord choisir le satellite pivot for i in range(0, self.obs[0].rxm_raw.shape[0]): for j in range(0, self.eph.nav_data.shape[0]): year = int(self.eph.nav_data[j, 1]) + 2000 month = int(self.eph.nav_data[j, 2]) day = int(self.eph.nav_data[j, 3]) hour = int(self.eph.nav_data[j, 4]) minute = int(self.eph.nav_data[j, 5]) sec = int(self.eph.nav_data[j, 6]) if self.obs[0].rxm_raw[i,7] == self.eph.nav_data[j,0] and math.fabs(t.weekToW_ToGPSUnixTime( self.obs[0].rxm_raw[i,1], self.obs[0].rxm_raw[i,0]) - t.iso_ToGPSUnixTime( year, month, day, hour, minute, sec )) < 7200000: coord_sat_tmp = self.eph.getSatXYZ(int(self.obs[0].rxm_raw[i, 0] / 1000), self.eph.nav_data[j]) print(coord_sat_tmp) if 10 < float(180 * self.getSatElevation(coord_sat_tmp[0], coord_sat_tmp[1], coord_sat_tmp[2], self.coord_pivot[0],self.coord_pivot[1],self.coord_pivot[2])/math.pi): print(float(180 * self.getSatElevation(coord_sat_tmp[0], coord_sat_tmp[1], coord_sat_tmp[2], self.coord_pivot[0],self.coord_pivot[1],self.coord_pivot[2])/math.pi)) print(self.eph.nav_data[j,0]) print(str(year)+"/"+str(month)+"/"+str(day)+"/"+str(hour)+"/"+str(minute)+"/"+str(sec)) print(str(self.obs[0].rxm_raw[i,0])+"/"+str(self.obs[0].rxm_raw[i,1])) flag = 1 break if flag == 1: break for i in range(1, len(self.obs)): # Le nombre des DD = Nbre de cubes fixes x Nbre de cube mobile print("OK2") ########################################################################### def getSatElevation(self, x_s, y_s, z_s, x_r, y_r, z_r): """Calculer l elevation d un satellite""" sat_rec_geoc = self.sat_rec_vector(x_s, y_s, z_s, x_r, y_r, z_r) sat_rec_loc = geocentrique2local(sat_rec_geoc[0], sat_rec_geoc[1], sat_rec_geoc[2]) norm = math.sqrt( sat_rec_loc[0,0] * sat_rec_loc[0,0] + sat_rec_loc[1,0] * sat_rec_loc[1,0] + sat_rec_loc[2,0] * sat_rec_loc[2,0] ) elevation = math.asin(sat_rec_geoc[2] / norm ) return elevation
def getTimestampInfoDataLine(dt): """Takes the timestamp described by the given datetime.datetime, and returns a str in CSV format, describing this timestamp. Arguments: dt - datetime.datetime object holding the timestamp of which to get information on. Returns: str in CSV format, holding the information regarding this timestamp. The data in this string is: jd,day,date,time,timezone """ # Return value. rv = "" # Field: jd rv += "{}".format(Ephemeris.datetimeToJulianDay(dt)) rv += "," # Timezone name string, extracted from datetime.tzname(). # This accounts for the fact that datetime.tzname() can return None. datetimeObj = dt tznameStr = datetimeObj.tzname() if tznameStr == None: tznameStr = "" dayOfWeekStr = datetimeObj.ctime()[0:3] offsetStr = \ Ephemeris.getTimezoneOffsetFromDatetime(datetimeObj) # Field: day rv += dayOfWeekStr rv += "," # Field: date rv += "{:04}-{:02}-{:02}".\ format(datetimeObj.year, datetimeObj.month, datetimeObj.day) #rv += "{:02}/{:02}/{:04}".\ # format(datetimeObj.month, # datetimeObj.day, # datetimeObj.year) rv += "," # Field: time rv += "{:02}:{:02}:{:02}".\ format(datetimeObj.hour, datetimeObj.minute, datetimeObj.second) rv += "," # Field: timezone. rv += "{}{}".format(tznameStr, offsetStr) rv += "," # Remove trailing comma. rv = rv[:-1] return rv
def filterOutNonsensicalValues(planetaryInfo): """Here we will do some filtering on the given PlanetaryInfo object. We will be setting some values to None so that the field will end up being blank on the table, where it makes sense to do so. Returns: PlanetaryInfo with some fields set to None. """ p = planetaryInfo tropical = "tropical" sidereal = "sidereal" if Ephemeris.isHouseCuspPlanetName(p.name) or \ Ephemeris.isAscmcPlanetName(p.name): p.geocentric[tropical]['longitude_speed'] = None p.geocentric[tropical]['declination'] = None p.geocentric[tropical]['declination_speed'] = None p.geocentric[tropical]['latitude'] = None p.geocentric[tropical]['latitude_speed'] = None p.geocentric[sidereal]['longitude_speed'] = None p.geocentric[sidereal]['declination'] = None p.geocentric[sidereal]['declination_speed'] = None p.geocentric[sidereal]['latitude'] = None p.geocentric[sidereal]['latitude_speed'] = None p.heliocentric[tropical]['longitude'] = None p.heliocentric[tropical]['longitude_speed'] = None p.heliocentric[tropical]['declination'] = None p.heliocentric[tropical]['declination_speed'] = None p.heliocentric[tropical]['latitude'] = None p.heliocentric[tropical]['latitude_speed'] = None p.heliocentric[sidereal]['longitude'] = None p.heliocentric[sidereal]['longitude_speed'] = None p.heliocentric[sidereal]['declination'] = None p.heliocentric[sidereal]['declination_speed'] = None p.heliocentric[sidereal]['latitude'] = None p.heliocentric[sidereal]['latitude_speed'] = None elif p.name == "Sun": p.heliocentric[tropical]['longitude'] = None p.heliocentric[tropical]['longitude_speed'] = None p.heliocentric[tropical]['declination'] = None p.heliocentric[tropical]['declination_speed'] = None p.heliocentric[tropical]['latitude'] = None p.heliocentric[tropical]['latitude_speed'] = None p.heliocentric[sidereal]['longitude'] = None p.heliocentric[sidereal]['longitude_speed'] = None p.heliocentric[sidereal]['declination'] = None p.heliocentric[sidereal]['declination_speed'] = None p.heliocentric[sidereal]['latitude'] = None p.heliocentric[sidereal]['latitude_speed'] = None elif p.name == "MeanNorthNode" or \ p.name == "TrueNorthNode" or \ p.name == "MeanLunarApogee" or \ p.name == "OsculatingLunarApogee" or \ p.name == "InterpolatedLunarApogee" or \ p.name == "InterpolatedLunarPerigee": if p.name == "MeanNorthNode" or \ p.name == "TrueNorthNode": p.geocentric[tropical]['latitude'] = None p.geocentric[tropical]['latitude_speed'] = None p.geocentric[sidereal]['latitude'] = None p.geocentric[sidereal]['latitude_speed'] = None p.heliocentric[tropical]['longitude'] = None p.heliocentric[tropical]['longitude_speed'] = None p.heliocentric[tropical]['declination'] = None p.heliocentric[tropical]['declination_speed'] = None p.heliocentric[tropical]['latitude'] = None p.heliocentric[tropical]['latitude_speed'] = None p.heliocentric[sidereal]['longitude'] = None p.heliocentric[sidereal]['longitude_speed'] = None p.heliocentric[sidereal]['declination'] = None p.heliocentric[sidereal]['declination_speed'] = None p.heliocentric[sidereal]['latitude'] = None p.heliocentric[sidereal]['latitude_speed'] = None elif p.name == "Earth": p.geocentric[tropical]['longitude'] = None p.geocentric[tropical]['longitude_speed'] = None p.geocentric[tropical]['declination'] = None p.geocentric[tropical]['declination_speed'] = None p.geocentric[tropical]['latitude'] = None p.geocentric[tropical]['latitude_speed'] = None p.geocentric[sidereal]['longitude'] = None p.geocentric[sidereal]['longitude_speed'] = None p.geocentric[sidereal]['declination'] = None p.geocentric[sidereal]['declination_speed'] = None p.geocentric[sidereal]['latitude'] = None p.geocentric[sidereal]['latitude_speed'] = None return p
def processPCDD(pcdd, tag): """Module for printing generic information about the PriceBars in a PriceChartDocumentData object. The generic information that is printed includes: - Earliest pricebar timestamp as a datetime.datetime and a julian day. - Latest pricebar timestamp as a datetime.datetime and a julian day. - highest pricebar high price. - lowest pricebar low price. Arguments: pcdd - PriceChartDocumentData object that will be modified. tag - str containing the tag. The value of this field may be "" if a tag is not specified by the user. This implementation doesn't use this field. Returns: 0 if the changes are to be saved to file. 1 if the changes are NOT to be saved to file. This implementation always returns 1. """ # Return value. rv = 1 # Get the number of PriceBars. numPriceBars = len(pcdd.priceBars) # Get the earliest and latest PriceBar. earliestPriceBar = None latestPriceBar = None lowestPrice = None highestPrice = None lowestClosePrice = None highestClosePrice = None for pb in pcdd.priceBars: if earliestPriceBar == None: earliestPriceBar = pb elif pb.timestamp < earliestPriceBar.timestamp: earliestPriceBar = pb if latestPriceBar == None: latestPriceBar = pb elif pb.timestamp > latestPriceBar.timestamp: latestPriceBar = pb if lowestPrice == None: lowestPrice = pb.low elif pb.low < lowestPrice: lowestPrice = pb.low if highestPrice == None: highestPrice = pb.high elif pb.high > highestPrice: highestPrice = pb.high if lowestClosePrice == None: lowestClosePrice = pb.close elif pb.close < lowestClosePrice: lowestClosePrice = pb.close if highestClosePrice == None: highestClosePrice = pb.close elif pb.close > highestClosePrice: highestClosePrice = pb.close log.info("") log.info("Number of PriceBars: {}".format(numPriceBars)) if numPriceBars > 0: # Make sure we got values for everything. if earliestPriceBar == None or \ latestPriceBar == None or \ lowestPrice == None or \ highestPrice == None or \ lowestClosePrice == None or \ highestClosePrice == None: log.error("PriceBars existed, but we are missing some set values.") rv = 1 return rv # Convert the datetimes to julian day. earliestPriceBarJd = \ Ephemeris.datetimeToJulianDay(earliestPriceBar.timestamp) latestPriceBarJd = \ Ephemeris.datetimeToJulianDay(latestPriceBar.timestamp) # Print the information to log. log.info("EarliestPriceBar datetime == {}".\ format(Ephemeris.datetimeToStr(earliestPriceBar.timestamp))) log.info("LatestPriceBar datetime == {}".\ format(Ephemeris.datetimeToStr(latestPriceBar.timestamp))) log.info("EarliestPriceBar julian day == {}".format(earliestPriceBarJd)) log.info("LatestPriceBar julian day == {}".format(latestPriceBarJd)) log.info("Lowest PriceBar LOW price == {}".format(highestPrice)) log.info("Highest PriceBar HIGH price == {}".format(highestPrice)) log.info("Lowest PriceBar CLOSE price == {}".format(highestPrice)) log.info("Highest PriceBar CLOSE price == {}".format(highestPrice)) log.info("") rv = 1 return rv
def main(): """ """ #global highPrice #global lowPrice # Return value. rv = 0 # Check global variable inputs. if moddedHitValue >= modulusAmt: log.error("Global input variable 'moddedHitValue' " + \ "cannot be greater than the value for 'modulusAmt'.") # Don't save pccd. rv = 1 return rv if startDt > endDt: log.error("Global input variable 'startDt' cannot be after 'endDt'.") # Don't save pccd. rv = 1 return rv # Ephemeris earliest timestamp. ephemerisEarliestTimestamp = None # Ephemeris latest timestamp. ephemerisLatestTimestamp = None # Cycle hit timestamps. cycleHitTimestamps = [] # Previous and current values held across iterations of the lines # of the CSV file. prevDt = None currDt = None prevUnmoddedValue = None currUnmoddedValue = None # Counter for the current line number. lineNum = 0 # Column name. This is obtained from the first line in the CSV file. columnName = "" try: with open(inputCsvFilename) as f: for line in f: line = line.strip() #log.debug("Looking at line [{}]: {}".format(lineNum, line)) # First line has the column headers. if lineNum == 0: line = line.strip() fieldValues = line.split(delimiter) # Make sure we have enough columns of data. if columnNumber >= len(fieldValues): log.error("The input CSV file does not have enough " + \ "columns. Could not read column {}".\ format(columnNumber)) # Don't save pcdd. rv = 1 return rv # Get the column name. columnName = fieldValues[columnNumber] if lineNum >= linesToSkip: line = line.strip() fieldValues = line.split(delimiter) # Make sure we have enough columns of data. if columnNumber >= len(fieldValues): log.error("The input CSV file does not have enough " + \ "columns. Could not read column {}".\ format(columnNumber)) # Don't save pcdd. rv = 1 return rv # Get the date from this line of text and convert # to a datetime. timestampStr = fieldValues[0] currDt = convertTimestampStrToDatetime(timestampStr) # If conversion failed then don't save. if currDt == None: # Don't save pcdd. rv = 1 return rv # Store the earliest and latest timestamps of the # Ephemeris from the CSV file, as read so far. if ephemerisEarliestTimestamp == None: ephemerisEarliestTimestamp = currDt elif currDt < ephemerisEarliestTimestamp: ephemerisEarliestTimestamp = currDt if ephemerisLatestTimestamp == None: ephemerisLatestTimestamp = currDt elif currDt > ephemerisLatestTimestamp: ephemerisLatestTimestamp = currDt # Continue only if the currDt is between the start and # end timestamps. if startDt < currDt < endDt: currUnmoddedValue = float(fieldValues[columnNumber]) currModdedValue = currUnmoddedValue % modulusAmt if prevDt != None and prevUnmoddedValue != None: # Assuming heliocentric cycles, so values change # in only one direction. prevModdedValue = prevUnmoddedValue % modulusAmt if prevUnmoddedValue < currUnmoddedValue: # Increasing values. if prevModdedValue < currModdedValue: # Curr value has not looped over the # modulus amount. This is the normal case. if prevModdedValue < moddedHitValue and \ moddedHitValue <= currModdedValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. prevDiff = abs(moddedHitValue - \ prevModdedValue) currDiff = abs(currModdedValue - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) elif prevModdedValue > currModdedValue: # Curr value has looped over the modulus # amount. We must make an adjustment when # doing calculations. if prevModdedValue < moddedHitValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. prevDiff = abs(moddedHitValue - \ prevModdedValue) currDiff = abs(currModdedValue + \ modulusAmt - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) elif moddedHitValue <= currModdedValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. prevDiff = abs(moddedHitValue + \ modulusAmt - \ prevModdedValue) currDiff = abs(currModdedValue - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) elif prevUnmoddedValue > currUnmoddedValue: # Decreasing values. if currModdedValue < prevModdedValue: # Curr value has not looped over 0. # This is the normal case. if currModdedValue <= moddedHitValue and \ moddedHitValue < prevModdedValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. currDiff = abs(moddedHitValue - \ currModdedValue) prevDiff = abs(prevModdedValue - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) elif currModdedValue > prevModdedValue: # Curr value has looped over 0. # We must make an adjustment when # doing calculations. if currModdedValue <= moddedHitValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. currDiff = abs(moddedHitValue - \ currModdedValue) prevDiff = abs(prevModdedValue + \ modulusAmt - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) elif moddedHitValue < prevModdedValue: # We crossed over the moddedHitValue. # Check to see whether the # previous or the current is # closer to the moddedHitValue. currDiff = abs(moddedHitValue + \ modulusAmt - \ currModdedValue) prevDiff = abs(prevModdedValue - \ moddedHitValue) if prevDiff < currDiff: # Prev is closer. cycleHitTimestamps.append(prevDt) else: # Curr is closer. cycleHitTimestamps.append(currDt) else: # Value is the same. This is an error. log.error("Found two values in column {} ".\ format(columnNumber) + \ "that are the same value. " + \ "See line {} in file '{}'".\ format(lineNum, inputCsvFilename)) # Update variables for reading the next line. prevDt = currDt currDt = None prevUnmoddedValue = currUnmoddedValue currUnmoddedValue = None lineNum += 1 except IOError as e: log.error("Please check to make sure input CSV file '{}'".\ format(inputCsvFilename) + \ " is a file and exists.") # Don't save pcdd. rv = 1 return rv # We now have all the cycle hit timestamps that are in the time # range desired. All these timestamps should be in the list # 'cycleHitTimestamps'. # Replace spaces in the column name with underscores. columnName = columnName.replace(" ", "_") # Set the tag name that will be used for the vertical lines. tag = "{}_Mod_{}_HitTo_{}".\ format(columnName, modulusAmt, moddedHitValue) # Newline. endl = "\n" # Write results to a CSV file. outputFileLines = [] # Add column headers. outputFileLines.append("Cycle hit dates for: " + tag + endl) for dt in cycleHitTimestamps: dateStr = formatToDateStr(dt) outputFileLines.append(dateStr + endl) # Write to file. with open(outputCsvFilename, "w", encoding="utf-8") as f: for line in outputFileLines: f.write(line) log.info("Finished writing the cycle hit dates to CSV file.") # Add the vertical lines at these timestamps. #for dt in cycleHitTimestamps: # PlanetaryCombinationsLibrary.\ # addVerticalLine(pcdd, dt, # highPrice, lowPrice, tag, color) # Calculate the minimum, maximum and average length of time # between the cycle hit timestamps. prevDt = None currDt = None minimumDiffTd = None maximumDiffTd = None averageDiffTd = None totalDiffTd = datetime.timedelta(0) for i in range(len(cycleHitTimestamps)): currDt = cycleHitTimestamps[i] # We skip calculating the timedelta for the first point # because we need two timestamps to calcate the timedelta. if i != 0 and prevDt != None: diffTd = currDt - prevDt # Update values if a new minimum or maximum is seen. if minimumDiffTd == None: minimumDiffTd = diffTd elif diffTd < minimumDiffTd: minimumDiffTd = diffTd if maximumDiffTd == None: maximumDiffTd = diffTd elif diffTd > maximumDiffTd: maximumDiffTd = diffTd # Add the diffTd to the total for the average calculation later. totalDiffTd += diffTd # Update for next iteration. prevDt = currDt currDt = None # Calculate the average. if len(cycleHitTimestamps) > 1: # Convert the timedelta to seconds. totalDiffSecs = \ (totalDiffTd.microseconds + \ (totalDiffTd.seconds + (totalDiffTd.days * 24 * 3600)) * 10**6) \ / 10**6 # Compute the average. averageDiffSec = totalDiffSecs / (len(cycleHitTimestamps) - 1) log.debug("totalDiffSecs == {}".format(totalDiffSecs)) log.debug("averageDiffSec == {}".format(averageDiffSec)) # Turn the average number of seconds to a timedelta. averageDiffTd = datetime.timedelta(seconds=averageDiffSec) # Print information about parameters and cycle hit timestamps that # were found. log.info("----------------------------------------------------") log.info("Ephemeris CSV filename: '{}'".format(inputCsvFilename)) log.info("Ephemeris CSV data column number: {}".format(columnNumber)) log.info("Ephemeris earliest timestamp: {}".\ format(ephemerisEarliestTimestamp)) log.info("Ephemeris latest timestamp: {}".\ format(ephemerisLatestTimestamp)) log.info("Modulus amount: {}".format(modulusAmt)) log.info("Modded hit value: {}".format(moddedHitValue)) log.info("startDt parameter: {}".format(startDt)) log.info("endDt parameter: {}".format(endDt)) #log.info("modifyPcddFlag: {}".format(modifyPcddFlag)) #log.info("highPrice: {}".format(highPrice)) #log.info("lowPrice: {}".format(lowPrice)) log.info("Number of cycle hit points: {}".format(len(cycleHitTimestamps))) log.info("Smallest timedelta between cycle hit points: {}".\ format(minimumDiffTd)) log.info("Largest timedelta between cycle hit points: {}".\ format(maximumDiffTd)) log.info("Average timedelta between cycle hit points: {}".\ format(averageDiffTd)) # Print the cycle turn points to debug. if printCycleTurnPointsFlag == True: log.debug("----------------------------------------------------") log.debug("Cycle hit points:") log.debug("----------------------------------------------------") for dt in cycleHitTimestamps: log.debug("{} {}".format(Ephemeris.datetimeToStr(dt), tag)) log.debug("----------------------------------------------------") if modifyPcddFlag == True: # Save changes. rv = 0 else: # Don't save changes. rv = 1 return rv
shutdown(1) else: log.debug("options.outputPcdFile == {}".format(options.outputPcdFile)) outputPcdFile = os.path.abspath(options.outputPcdFile) log.debug("outputPcdFile == {}".format(outputPcdFile)) if os.path.exists(outputPcdFile) and os.path.isfile(outputPcdFile): log.debug("The outputPcdFile path exists, and it is a file.") else: log.error("The output PCD file either does not exist or is not a file.") shutdown(1) ############################################################################## # Initialize Ephemeris (required). Ephemeris.initialize() # Set application details so the we can use QSettings default # constructor later. appAuthor = "Ryan Luu" appName = "PriceChartingTool" QCoreApplication.setOrganizationName(appAuthor) QCoreApplication.setApplicationName(appName) # Create the Qt application. app = QApplication(sys.argv) app.setApplicationName(appName) # Open the input PriceChartDocument files. log.info("Loading input template PriceChartDocument '{}' ...".\ format(inputTemplatePcdFile))
latitude = pi.heliocentric['tropical']['latitude'] rv += "{:.3f},".format(latitude) # Remove trailing comma. rv = rv[:-1] return rv ############################################################################## #if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Log the parameters that are being used. log.info("Location used is: {} (lat={}, lon={})".\ format(locationName, locationLatitude, locationLongitude)) log.info("Timezone used is: {}".format(timezone.zone)) log.info("Start timestamp: {}".format(Ephemeris.datetimeToStr(startDt))) log.info("End timestamp: {}".format(Ephemeris.datetimeToStr(endDt))) # Compile the header line text. headerLine = ""
def processPCDD(pcdd, tag): """ Module for printing information about the BirthInfo in a PriceChartDocumentData object. BirthInfo printed includes: - Birth location name. - Birth country name. - Birth location coordinates. - Birth timestamp as a UTC datetime.datetime - Birth timestamp as a julian day. Arguments: pcdd - PriceChartDocumentData object that will be modified. tag - str containing the tag. The value of this field may be "" if a tag is not specified by the user. This implementation doesn't use this field. Returns: 0 if the changes are to be saved to file. 1 if the changes are NOT to be saved to file. This implementation always returns 1. """ # Return value. rv = 1 birthInfo = pcdd.birthInfo # Convert longitude from a float value to degrees, # minutes, seconds and East/West polarity. (lonDegrees, lonMinutes, lonSeconds, lonPolarity) = \ GeoInfo.longitudeToDegMinSec(birthInfo.longitudeDegrees) # Convert latitude from a float value to degrees, minutes, # seconds and North/South polarity. (latDegrees, latMinutes, latSeconds, latPolarity) = \ GeoInfo.latitudeToDegMinSec(birthInfo.latitudeDegrees) log.info("") log.info("Birth location name: {}".format(birthInfo.locationName)) log.info("Birth location country: {}".format(birthInfo.countryName)) log.info("Birth location longitude: {} {} {}' {} ({})".\ format(lonDegrees, lonPolarity, lonMinutes, lonSeconds, birthInfo.longitudeDegrees)) log.info("Birth location latitude: {} {} {}' {} ({})".\ format(latDegrees, latPolarity, latMinutes, latSeconds, birthInfo.latitudeDegrees)) birthLocalizedDatetime = birthInfo.getBirthLocalizedDatetime() birthUtcDatetime = birthInfo.getBirthUtcDatetime() birthJd = Ephemeris.datetimeToJulianDay(birthUtcDatetime) log.info("Birth timestamp (localized): {}".\ format(Ephemeris.datetimeToStr(birthLocalizedDatetime))) log.info("Birth timestamp (UTC): {}".\ format(Ephemeris.datetimeToStr(birthUtcDatetime))) log.info("Birth timestamp (julian day): {}".\ format(birthJd)) log.info("") rv = 1 return rv
rv = "" for i in range(len(fieldValues)): rv += "," # Remove trailing comma. rv = rv[:-1] return rv ############################################################################## #if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Get the pricebar data as a list of PriceBar objects. # List of PriceBar objects. priceBars = [] inputFilename = priceBarDataCsvFilename linesToSkip = priceBarDataCsvFileLinesToSkip try: with open(inputFilename, "r") as f:
def convertSwingFileDataToCsvStr(swingFileData): """Takes a SwingFileData and generates a CSV str containing most of the swing file data. """ endl = "\n" rv = "" rv += "Trading Entity Description: {}".\ format(swingFileData.tradingEntityDescription) + endl #rv += "Swing File Description: {}".\ # format(swingFileData.swingFileDescription) + endl #rv += "User notes: {}".\ # format(swingFileData.userNotes) + endl rv += "Source Swing File: {}".\ format(swingFile) + endl #rv += "Source PCD filename: {}".\ # format(swingFileData.sourcePcdFilename) + endl #rv += "Source PriceBar data filename: {}".\ # format(swingFileData.sourcePriceBarDataFilename) + endl rv += "jd,day,date,time,timezone,tags,open,high,low,close,volume,oi" + endl for pb in swingFileData.priceBars: # Field: jd rv += "{}".format(Ephemeris.datetimeToJulianDay(pb.timestamp)) rv += "," # Timezone name string, extracted from datetime.tzname(). # This accounts for the fact that datetime.tzname() can return None. datetimeObj = pb.timestamp tznameStr = datetimeObj.tzname() if tznameStr == None: tznameStr = "" dayOfWeekStr = datetimeObj.ctime()[0:3] offsetStr = \ Ephemeris.getTimezoneOffsetFromDatetime(datetimeObj) # Field: day rv += dayOfWeekStr rv += "," # Field: date rv += "{:04}-{:02}-{:02}".\ format(datetimeObj.year, datetimeObj.month, datetimeObj.day) #rv += "{:02}/{:02}/{:04}".\ # format(datetimeObj.month, # datetimeObj.day, # datetimeObj.year) rv += "," # Field: time rv += "{:02}:{:02}:{:02}".\ format(datetimeObj.hour, datetimeObj.minute, datetimeObj.second) rv += "," # Field: timezone. rv += "{}{}".format(tznameStr, offsetStr) rv += "," # Field: tags for tag in pb.tags: rv += tag + " " rv += "," # Field: open rv += "{}".format(pb.open) rv += "," # Field: high rv += "{}".format(pb.high) rv += "," # Field: low rv += "{}".format(pb.low) rv += "," # Field: close rv += "{}".format(pb.close) rv += "," # Field: volume rv += "{}".format(pb.vol) rv += "," # Field: oi rv += "{}".format(pb.oi) rv += "," rv = rv[:-1] rv += endl return rv
def convertSwingFileDataToCsvStr(swingFileData): """Takes a SwingFileData and generates a CSV str containing most of the swing file data. """ geocentricPlanetNameList = [\ "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Chiron", "TrueNorthNode", #"Isis", ] endl = "\n" rv = "" rv += "Trading Entity Description: {}".\ format(swingFileData.tradingEntityDescription) + endl #rv += "Swing File Description: {}".\ # format(swingFileData.swingFileDescription) + endl #rv += "User notes: {}".\ # format(swingFileData.userNotes) + endl rv += "Source Swing File: {}".\ format(swingFile) + endl #rv += "Source PCD filename: {}".\ # format(swingFileData.sourcePcdFilename) + endl #rv += "Source PriceBar data filename: {}".\ # format(swingFileData.sourcePriceBarDataFilename) + endl # Column headers. rv += "jd,day,date,time,timezone,tags,open,high,low,close,volume,oi" # Add the columns headers for the Geocentric planets' longitude. # Here we do it twice because the first set is the 15-degree axis # reduction, and the second set is the actual planet positions. for planetName in geocentricPlanetNameList: rv += ",G." + planetName for planetName in geocentricPlanetNameList: rv += ",G." + planetName rv += endl for pb in swingFileData.priceBars: # Field: jd rv += "{}".format(Ephemeris.datetimeToJulianDay(pb.timestamp)) rv += "," # Timezone name string, extracted from datetime.tzname(). # This accounts for the fact that datetime.tzname() can return None. datetimeObj = pb.timestamp tznameStr = datetimeObj.tzname() if tznameStr == None: tznameStr = "" dayOfWeekStr = datetimeObj.ctime()[0:3] offsetStr = \ Ephemeris.getTimezoneOffsetFromDatetime(datetimeObj) # Field: day rv += dayOfWeekStr rv += "," # Field: date rv += "{:04}-{:02}-{:02}".\ format(datetimeObj.year, datetimeObj.month, datetimeObj.day) #rv += "{:02}/{:02}/{:04}".\ # format(datetimeObj.month, # datetimeObj.day, # datetimeObj.year) rv += "," # Field: time rv += "{:02}:{:02}:{:02}".\ format(datetimeObj.hour, datetimeObj.minute, datetimeObj.second) rv += "," # Field: timezone. rv += "{}{}".format(tznameStr, offsetStr) rv += "," # Field: tags for tag in pb.tags: rv += tag + " " rv += "," # Field: open rv += "{}".format(pb.open) rv += "," # Field: high rv += "{}".format(pb.high) rv += "," # Field: low rv += "{}".format(pb.low) rv += "," # Field: close rv += "{}".format(pb.close) rv += "," # Field: volume rv += "{}".format(pb.vol) rv += "," # Field: oi rv += "{}".format(pb.oi) rv += "," # Get PlanetaryInfos for this timestamp. planetaryInfos = \ getPlanetaryInfosForDatetime(pb.timestamp, swingFileData.birthInfo) # Fields of the geocentric planets' longitude 15-degree axis points. for planetName in geocentricPlanetNameList: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] rv += "{:6.3f},".format(lon % 15.0) break # Fields of the geocentric planets' longitude. for planetName in geocentricPlanetNameList: for pi in planetaryInfos: if pi.name == planetName: lon = pi.geocentric['tropical']['longitude'] valueStr = AstrologyUtils.\ convertLongitudeToStrWithRasiAbbrev(lon) rv += "{},".format(valueStr) break # Chop off the last trailing comma. rv = rv[:-1] rv += endl return rv
# Update prevDiff as the currDiff. prevDiff = Util.toNormalizedAngle(currDiff) log.info("Number of timestamps obtained: {}".\ format(len(aspectTimestamps))) log.debug("Exiting " + inspect.stack()[0][3] + "()") return aspectTimestamps ############################################################################## if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Dictionary of results computed. results = {} # Angle that we want to obtain for the aspect. desiredAspectDegree = 0 numPlanets = len(heliocentricPlanetNames) for i in range(numPlanets):
def getLongitudeAspectTimestamps(\ startDt, endDt, planet1ParamsList, planet2ParamsList, degreeDifference, uniDirectionalAspectsFlag=False, maxErrorTd=datetime.timedelta(minutes=1)): """Obtains a list of datetime.datetime objects that contain the moments when the aspect specified is active. Warning on usage: When planet-longitude-averaging is utilized for the longitude of planet1 or planet2, the aspects returned by this function cannot be fully relied upon. This short-coming happens under these circumstances because it is possible that the longitude can abruptly 'jump' or hop a large distance when measurements are taken between timestamp steps. For example, this 'jumping' effect can occur if two planets A and B, are both around 355 degrees, and planet A crosses the 0 degree mark. Now the average goes from around 355 degrees (355 + 355 = 710 / 2 = 355), to about 180 degrees (355 + 0 = 355 / 2 = about 180). While corrections for this can be made for the case of having only 2 planets involved, if more planets are involved then the adjustment required quickly becomes non-trivial. Arguments: startDt - datetime.datetime object for the starting timestamp to do the calculations for artifacts. endDt - datetime.datetime object for the ending timestamp to do the calculations for artifacts. planet1ParamsList - List of tuples that will be used as parameters for planet1. Each tuple contained in this list represents parameters for each planet that will get averaged to create what is known as planet1. The contents of the tuple are: (planetName, centricityType, longitudeType) Where: planetName - str holding the name of the second planet to do the calculations for. centricityType - str value holding either "geocentric", "topocentric", or "heliocentric". longitudeType - str value holding either "tropical" or "sidereal". Example: So if someone wanted planet1 to be the average location of of geocentric sidereal Saturn and geocentric sidereal Uranus, the 'planet1ParamsList' parameter would be: [("Saturn", "geocentric", "sidereal"), ("Uranus", "geocentric", "sidereal")] If the typical use-case is desired for the longitude of just a single planet, pass a list with only 1 tuple. As an example, for Mercury it would be: [("Mercury", "heliocentric", "tropical")] planet2ParamsList - List of tuples that will be used as parameters for planet2. For additional details about the format of this parameter field, please see the description for parameter 'planet1ParamsList' degreeDifference - float value for the number of degrees of separation for this aspect. uniDirectionalAspectsFlag - bool value for whether or not uni-directional aspects are enabled or not. By default, aspects are bi-directional, so Saturn square-aspect Jupiter would be the same as Jupiter square-aspect Saturn. If this flag is set to True, then those two combinations would be considered unique. In the case where the flag is set to True, for the aspect to be active, planet2 would need to be 'degreeDifference' degrees in front of planet1. maxErrorTd - datetime.timedelta object holding the maximum time difference between the exact planetary combination timestamp, and the one calculated. This would define the accuracy of the calculations. Returns: List of datetime.datetime objects. Each timestamp in the list is the moment where the aspect is active and satisfies the given parameters. In the event of an error, the reference None is returned. """ log.debug("Entered " + inspect.stack()[0][3] + "()") # List of timestamps of the aspects found. aspectTimestamps = [] # Make sure the inputs are valid. if endDt < startDt: log.error("Invalid input: 'endDt' must be after 'startDt'") return None # Check to make sure planet lists were given. if len(planet1ParamsList) == 0: log.error("planet1ParamsList must contain at least 1 tuple.") return None if len(planet2ParamsList) == 0: log.error("planet2ParamsList must contain at least 1 tuple.") return None log.debug("planet1ParamsList passed in is: {}".\ format(planet1ParamsList)) log.debug("planet2ParamsList passed in is: {}".\ format(planet2ParamsList)) # Check for valid inputs in each of the planet parameter lists. for planetTuple in planet1ParamsList + planet2ParamsList: if len(planetTuple) != 3: log.error("Input error: " + \ "Not enough values given in planet tuple.") return None planetName = planetTuple[0] centricityType = planetTuple[1] longitudeType = planetTuple[2] loweredCentricityType = centricityType.lower() if loweredCentricityType != "geocentric" and \ loweredCentricityType != "topocentric" and \ loweredCentricityType != "heliocentric": log.error("Invalid input: Centricity type is invalid. " + \ "Value given was: {}".format(centricityType)) return None # Check inputs for longitude type. loweredLongitudeType = longitudeType.lower() if loweredLongitudeType != "tropical" and \ loweredLongitudeType != "sidereal": log.error("Invalid input: Longitude type is invalid. " + \ "Value given was: {}".format(longitudeType)) return None # Field name we are getting. fieldName = "longitude" # Initialize the Ephemeris with the birth location. log.debug("Setting ephemeris location ...") Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Set the step size. stepSizeTd = datetime.timedelta(days=1) for planetTuple in planet1ParamsList + planet2ParamsList: planetName = planetTuple[0] if Ephemeris.isHouseCuspPlanetName(planetName) or \ Ephemeris.isAscmcPlanetName(planetName): # House cusps and ascmc planets need a smaller step size. stepSizeTd = datetime.timedelta(hours=1) elif planetName == "Moon": # Use a smaller step size for the moon so we can catch # smaller aspect sizes. stepSizeTd = datetime.timedelta(hours=3) log.debug("Step size is: {}".format(stepSizeTd)) # Desired angles. We need to check for planets at these angles. desiredAngleDegList = [] desiredAngleDeg1 = Util.toNormalizedAngle(degreeDifference) desiredAngleDegList.append(desiredAngleDeg1) if Util.fuzzyIsEqual(desiredAngleDeg1, 0): desiredAngleDegList.append(360) if uniDirectionalAspectsFlag == False: desiredAngleDeg2 = \ 360 - Util.toNormalizedAngle(degreeDifference) if desiredAngleDeg2 not in desiredAngleDegList: desiredAngleDegList.append(desiredAngleDeg2) # Debug output. anglesStr = "" for angle in desiredAngleDegList: anglesStr += "{} ".format(angle) log.debug("Angles in desiredAngleDegList: " + anglesStr) # Iterate through, appending to aspectTimestamps list as we go. steps = [] steps.append(copy.deepcopy(startDt)) steps.append(copy.deepcopy(startDt)) longitudesP1 = [] longitudesP1.append(None) longitudesP1.append(None) longitudesP2 = [] longitudesP2.append(None) longitudesP2.append(None) def getFieldValue(dt, planetParamsList, fieldName): """Creates the PlanetaryInfo object for the given planetParamsList and returns the value of the field desired. """ log.debug("planetParamsList passed in is: {}".\ format(planetParamsList)) unAveragedFieldValues = [] for t in planetParamsList: planetName = t[0] centricityType = t[1] longitudeType = t[2] pi = Ephemeris.getPlanetaryInfo(planetName, dt) fieldValue = None if centricityType.lower() == "geocentric": fieldValue = pi.geocentric[longitudeType][fieldName] elif centricityType.lower() == "topocentric": fieldValue = pi.topocentric[longitudeType][fieldName] elif centricityType.lower() == "heliocentric": fieldValue = pi.heliocentric[longitudeType][fieldName] else: log.error("Unknown centricity type: {}".\ format(centricityType)) fieldValue = None unAveragedFieldValues.append(fieldValue) log.debug("unAveragedFieldValues is: {}".\ format(unAveragedFieldValues)) # Average the field values. total = 0.0 for v in unAveragedFieldValues: total += v averagedFieldValue = total / len(unAveragedFieldValues) log.debug("averagedFieldValue is: {}".\ format(averagedFieldValue)) return averagedFieldValue log.debug("Stepping through timestamps from {} to {} ...".\ format(Ephemeris.datetimeToStr(startDt), Ephemeris.datetimeToStr(endDt))) currDiff = None prevDiff = None while steps[-1] < endDt: currDt = steps[-1] prevDt = steps[-2] log.debug("Looking at currDt == {} ...".\ format(Ephemeris.datetimeToStr(currDt))) longitudesP1[-1] = \ Util.toNormalizedAngle(\ getFieldValue(currDt, planet1ParamsList, fieldName)) longitudesP2[-1] = \ Util.toNormalizedAngle(\ getFieldValue(currDt, planet2ParamsList, fieldName)) log.debug("{} {} is: {}".\ format(planet1ParamsList, fieldName, longitudesP1[-1])) log.debug("{} {} is: {}".\ format(planet2ParamsList, fieldName, longitudesP2[-1])) currDiff = Util.toNormalizedAngle(\ longitudesP1[-1] - longitudesP2[-1]) log.debug("prevDiff == {}".format(prevDiff)) log.debug("currDiff == {}".format(currDiff)) if prevDiff != None and \ longitudesP1[-2] != None and \ longitudesP2[-2] != None: if abs(prevDiff - currDiff) > 180: # Probably crossed over 0. Adjust the prevDiff so # that the rest of the algorithm can continue to # work. if prevDiff > currDiff: prevDiff -= 360 else: prevDiff += 360 log.debug("After adjustment: prevDiff == {}".\ format(prevDiff)) log.debug("After adjustment: currDiff == {}".\ format(currDiff)) for desiredAngleDeg in desiredAngleDegList: log.debug("Looking at desiredAngleDeg: {}".\ format(desiredAngleDeg)) desiredDegree = desiredAngleDeg if prevDiff < desiredDegree and currDiff >= desiredDegree: log.debug("Crossed over {} from below to above!".\ format(desiredDegree)) # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than # the threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. timeWindowTd = t2 - t1 halfTimeWindowTd = \ datetime.\ timedelta(days=(timeWindowTd.days / 2.0), seconds=(timeWindowTd.seconds / 2.0), microseconds=\ (timeWindowTd.microseconds / 2.0)) testDt = t1 + halfTimeWindowTd testValueP1 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet1ParamsList, fieldName)) testValueP2 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet2ParamsList, fieldName)) log.debug("testValueP1 == {}".format(testValueP1)) log.debug("testValueP2 == {}".format(testValueP2)) if longitudesP1[-2] > 240 and testValueP1 < 120: # Planet 1 hopped over 0 degrees. testValueP1 += 360 elif longitudesP1[-2] < 120 and testValueP1 > 240: # Planet 1 hopped over 0 degrees. testValueP1 -= 360 if longitudesP2[-2] > 240 and testValueP2 < 120: # Planet 2 hopped over 0 degrees. testValueP2 += 360 elif longitudesP2[-2] < 120 and testValueP2 > 240: # Planet 2 hopped over 0 degrees. testValueP2 -= 360 testDiff = Util.toNormalizedAngle(\ testValueP1 - testValueP2) # Handle special cases of degrees 0 and 360. # Here we adjust testDiff so that it is in the # expected ranges. if Util.fuzzyIsEqual(desiredDegree, 0): if testDiff > 240: testDiff -= 360 elif Util.fuzzyIsEqual(desiredDegree, 360): if testDiff < 120: testDiff += 360 log.debug("testDiff == {}".format(testDiff)) if testDiff < desiredDegree: t1 = testDt else: t2 = testDt # Update the curr values. currDt = t2 currDiff = testDiff longitudesP1[-1] = testValueP1 longitudesP2[-1] = testValueP2 currErrorTd = t2 - t1 # Update our lists. steps[-1] = currDt # Store the aspect timestamp. aspectTimestamps.append(currDt) elif prevDiff > desiredDegree and currDiff <= desiredDegree: log.debug("Crossed over {} from above to below!".\ format(desiredDegree)) # This is the upper-bound of the error timedelta. t1 = prevDt t2 = currDt currErrorTd = t2 - t1 # Refine the timestamp until it is less than # the threshold. while currErrorTd > maxErrorTd: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. timeWindowTd = t2 - t1 halfTimeWindowTd = \ datetime.\ timedelta(days=(timeWindowTd.days / 2.0), seconds=(timeWindowTd.seconds / 2.0), microseconds=\ (timeWindowTd.microseconds / 2.0)) testDt = t1 + halfTimeWindowTd testValueP1 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet1ParamsList, fieldName)) testValueP2 = \ Util.toNormalizedAngle(getFieldValue(\ testDt, planet2ParamsList, fieldName)) log.debug("testValueP1 == {}".format(testValueP1)) log.debug("testValueP2 == {}".format(testValueP2)) if longitudesP1[-2] > 240 and testValueP1 < 120: # Planet 1 hopped over 0 degrees. testValueP1 += 360 elif longitudesP1[-2] < 120 and testValueP1 > 240: # Planet 1 hopped over 0 degrees. testValueP1 -= 360 if longitudesP2[-2] > 240 and testValueP2 < 120: # Planet 2 hopped over 0 degrees. testValueP2 += 360 elif longitudesP2[-2] < 120 and testValueP2 > 240: # Planet 2 hopped over 0 degrees. testValueP2 -= 360 testDiff = Util.toNormalizedAngle(\ testValueP1 - testValueP2) # Handle special cases of degrees 0 and 360. # Here we adjust testDiff so that it is in the # expected ranges. if Util.fuzzyIsEqual(desiredDegree, 0): if testDiff > 240: testDiff -= 360 elif Util.fuzzyIsEqual(desiredDegree, 360): if testDiff < 120: testDiff += 360 log.debug("testDiff == {}".format(testDiff)) if testDiff > desiredDegree: t1 = testDt else: t2 = testDt # Update the curr values. currDt = t2 currDiff = testDiff longitudesP1[-1] = testValueP1 longitudesP2[-1] = testValueP2 currErrorTd = t2 - t1 # Update our lists. steps[-1] = currDt # Store the aspect timestamp. aspectTimestamps.append(currDt) # Prepare for the next iteration. log.debug("steps[-1] is: {}".\ format(Ephemeris.datetimeToStr(steps[-1]))) log.debug("stepSizeTd is: {}".format(stepSizeTd)) steps.append(copy.deepcopy(steps[-1]) + stepSizeTd) del steps[0] longitudesP1.append(None) del longitudesP1[0] longitudesP2.append(None) del longitudesP2[0] # Update prevDiff as the currDiff. prevDiff = Util.toNormalizedAngle(currDiff) log.info("Number of timestamps obtained: {}".\ format(len(aspectTimestamps))) log.debug("Exiting " + inspect.stack()[0][3] + "()") return aspectTimestamps
def main(): # Create the parser parser = OptionParser() # Specify all valid options. parser.add_option("-v", "--version", action="store_true", dest="version", default=False, help="Display script version info and author contact.") parser.add_option("--pcd-file", action="store", type="str", dest="pcdFile", default=None, help="Specify the PriceChartDocument (.pcd) file " + \ "to modify.", metavar="<FILE>") parser.add_option("--print", action="store_true", dest="printFlag", default=False, help="Print the swing file's contents.") parser.add_option("--output-file", action="store", type="str", dest="outputFile", default=None, help="Specify an output filename for the swing file." + \ " The swing file data is pickled to this file.", metavar="<FILE>") # Parse the arguments into options. (options, args) = parser.parse_args() # Print version information if the flag was used. if (options.version == True): print(os.path.basename(sys.argv[0]) + " (Version " + VERSION + ")") print("By Ryan Luu, [email protected]") shutdown(0) # Get the pcd filename. if (options.pcdFile == None): log.error("Please specify a PriceChartDocument (.pcd) file with " + "the --pcd-file option.") shutdown(1) else: log.debug("options.pcdFile == {}".format(options.pcdFile)) pcdFile = os.path.abspath(options.pcdFile) log.debug("pcdFile == {}".format(pcdFile)) # Get the print flag. printFlag = options.printFlag log.debug("printFlag == {}".format(printFlag)) # Get the output filename. if (options.outputFile != None): log.debug("options.outputFile == {}".format(options.outputFile)) outputFile = os.path.abspath(options.outputFile) else: log.debug("outputFile was not specified.") outputFile = "" # Check to make sure either --print or --pcd-file was specified. if outputFile == "" and printFlag == False: log.error("Please specify either the --print option or " + "the --pcd-file option.") shutdown(1) ###################################### # Initialize Ephemeris (required). Ephemeris.initialize() # Set application details so the we can use QSettings default # constructor later. appAuthor = "Ryan Luu" appName = "PriceChartingTool" QCoreApplication.setOrganizationName(appAuthor) QCoreApplication.setApplicationName(appName) # Create the Qt application. app = QApplication(sys.argv) app.setApplicationName(appName) # Open the PriceChartDocument file. log.info("Loading PriceChartDocument '{}' ...".format(pcdFile)) priceChartDocumentData = unpicklePriceChartDocumentDataFromFile(pcdFile) if priceChartDocumentData == None: # Retrieval failed. An error message should have been logged. shutdown(1) log.info("Creating a new SwingFileData object ...") # Create SwingFileData object. swingFileData = SwingFileData() log.info("Extracting data from PriceChartDocumentData ...") # Load the PriceChartDocumentData into it. swingFileData.loadPriceChartDocumentData(pcdFile, priceChartDocumentData) log.info("Processing SwingFileData object for highs and lows ...") # Process the PriceBars in the SwingFileData object, tagging the # highs and lows. processSwingFileData(swingFileData) log.info("Processing complete.") # Print the contents if the print flag is set. if printFlag == True: log.info("Printing SwingFileData ...") print("Python object toString() output: " + os.linesep) print(swingFileData.toString()) # Write to file. if outputFile != "": log.info("Writing to output file '{}' ...".format(outputFile)) with open(outputFile, "wb") as f: try: pickle.dump(swingFileData, f) log.info("File successfully written.") except pickle.PickleError as pe: log.error("Error while pickling a " + "SwingFileData object to file " + outputFile + ". Error is: {}".format(pe) + ". SwingFileData object " + "has the following info: " + swingFileData.toString()) shutdown(1) # Execution completed. log.info("Done.") shutdown(0)
rv = "" for i in range(len(fieldValues)): rv += "," # Remove trailing comma. rv = rv[:-1] return rv ############################################################################## #if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Get the pricebar data as a list of PriceBar objects. # List of PriceBar objects. priceBars = [] inputFilename = priceBarDataCsvFilename linesToSkip = priceBarDataCsvFileLinesToSkip try: with open(inputFilename, "r") as f: # Line number index.
prevTropLongitudeSpeed = currTropLongitudeSpeed currTropLongitudeSpeed = None currTropLongitude = None currSidLongitude = None log.debug("prevTropLongitudeSpeed={}, currTropLongitudeSpeed={}".\ format(prevTropLongitudeSpeed, currTropLongitudeSpeed)) return rv ############################################################################## if __name__ == "__main__": # Initialize Ephemeris (required). Ephemeris.initialize() # Set the Location (required). Ephemeris.setGeographicPosition(locationLongitude, locationLatitude, locationElevation) # Dictionary of results computed. results = {} for planetName in geocentricPlanetNames: log.info("Obtaining planet retrograde and direct information for " + \ "'{}' ...".format(planetName)) results[planetName] = \ getGeocentricPlanetDirectRetrogradeInfo(planetName)
def getLongitudeDiffBetweenDatetimes(planetName, centricityType, dt1, loc1Tuple, dt2, loc2Tuple): startTimestamp = dt1 endTimestamp = dt2 loc1Name = loc1Tuple[0] loc1Longitude = loc1Tuple[1] loc1Latitude = loc1Tuple[2] loc1Elevation = loc1Tuple[3] loc2Name = loc2Tuple[0] loc2Longitude = loc2Tuple[1] loc2Latitude = loc2Tuple[2] loc2Elevation = loc2Tuple[3] # maxErrorTd - datetime.timedelta object holding the maximum # time difference between the exact planetary # timestamp for the phenomena, and the one # calculated. This would define the accuracy of # the calculations. # maxErrorTd = datetime.timedelta(seconds=4) # Size of a circle, in degrees. # # Here we define our own value instead of using the value in # AstrologyUtils.degreesInCircle because it is possible we may # want to test different sizes of a 'circle'. circleSizeInDegrees = 360.0 # All references to longitude_speed need to # be from tropical zodiac measurements! If I use # sidereal zodiac measurements for getting the # longitude_speed, then the measurements from the # Swiss Ephemeris do not yield the correct values. # I use the following variable in these locations. zodiacTypeForLongitudeSpeed = "tropical" tropicalZodiacFlag = True # Text to set in the text item. text = "" # Total number of degrees elapsed. totalDegrees = 0 Ephemeris.setGeographicPosition(loc1Longitude, loc1Latitude, loc1Elevation) # List of PlanetaryInfo objects for this particular # planet, sorted by timestamp. planetData = [] # Step size to use in populating the data list with # PlanetaryInfos. # # The step size should cause the planet to move less # than 120 degrees in all cases, and idealy much less # than this, that way we can easily narrow down when # the planet passes the 0 degree or 360 degree # threshold, and also so it is easier to narrow down # when retrograde periods happen. If the step size is # too large, it is possible that we would miss a whole # time window of retrograde movement, so discretion # has to be used in determining what to use for this value. # # Here we will set it to 1 day for the default case, # but if the planet name is a house cusp then shrink # the step size so we will get the correct resolution. # Also, if the planet name is an outer planet with a # large period, we can increase the step size slightly # to improve performance. stepSizeTd = datetime.timedelta(days=1) if Ephemeris.isHouseCuspPlanetName(planetName) or \ Ephemeris.isAscmcPlanetName(planetName): stepSizeTd = datetime.timedelta(hours=1) elif planetName == "Jupiter" or \ planetName == "Saturn" or \ planetName == "Neptune" or \ planetName == "Uranus" or \ planetName == "Pluto": stepSizeTd = datetime.timedelta(days=5) log.debug("Stepping through from {} to {} ...".\ format(Ephemeris.datetimeToStr(startTimestamp), Ephemeris.datetimeToStr(endTimestamp))) # Current datetime as we step through all the # timestamps between the start and end timestamp. currDt = copy.deepcopy(startTimestamp) # Step through the timestamps, calculating the planet positions. while currDt < endTimestamp: p = Ephemeris.getPlanetaryInfo(planetName, currDt) planetData.append(p) # Increment step size. currDt += stepSizeTd # We must also append the planet calculation for the end timestamp. Ephemeris.setGeographicPosition(loc2Longitude, loc2Latitude, loc2Elevation) p = Ephemeris.getPlanetaryInfo(planetName, endTimestamp) planetData.append(p) # Geocentric measurement. if centricityType == "geocentric": # Get the PlanetaryInfos for the timestamps of the # planet at the moment right after the # longitude_speed polarity changes. additionalPlanetaryInfos = [] prevLongitudeSpeed = None for i in range(len(planetData)): currLongitudeSpeed = \ planetData[i].geocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'] if prevLongitudeSpeed != None and \ ((prevLongitudeSpeed < 0 and currLongitudeSpeed >= 0) or \ (prevLongitudeSpeed >= 0 and currLongitudeSpeed < 0)): # Polarity changed. # Try to narrow down the exact moment in # time when this occured. t1 = planetData[i-1].dt t2 = planetData[i].dt currErrorTd = t2 - t1 while currErrorTd > maxErrorTd: if log.isEnabledFor(logging.DEBUG) == True: log.debug("Refining between {} and {}".\ format(Ephemeris.datetimeToStr(t1), Ephemeris.datetimeToStr(t2))) # Check the timestamp between. diffTd = t2 - t1 halfDiffTd = \ datetime.\ timedelta(days=(diffTd.days / 2.0), seconds=(diffTd.seconds / 2.0), microseconds=(diffTd.\ microseconds / 2.0)) testDt = t1 + halfDiffTd p = Ephemeris.getPlanetaryInfo(planetName, testDt) testLongitudeSpeed = \ p.geocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'] if ((prevLongitudeSpeed < 0 and \ testLongitudeSpeed >= 0) or \ (prevLongitudeSpeed >= 0 and \ testLongitudeSpeed < 0)): # Polarity change at the test timestamp. t2 = testDt else: # No polarity change yet. t1 = testDt # Update the currErrorTd. currErrorTd = t2 - t1 log.debug("Broke out of loop to find " + \ "velocity polarity change. " + \ "currErrorTd is: {}, ".\ format(currErrorTd)) # Timestamp at t2 is now within the amount # of the time error threshold ('maxErrorTd') # following the polarity change. # Append this value to the list. p = Ephemeris.getPlanetaryInfo(planetName, t2) additionalPlanetaryInfos.append(p) t1pi = planetData[i-1] t2pi = Ephemeris.getPlanetaryInfo(planetName, t2) if log.isEnabledFor(logging.DEBUG) == True: log.debug("t1 == {}, ".\ format(Ephemeris.datetimeToStr(t1pi.dt)) + \ "longitude(tropical) == {}, ".\ format(t1pi.geocentric['tropical']['longitude']) + \ "longitude(sidereal) == {}, ".\ format(t1pi.geocentric['sidereal']['longitude']) + \ "longitude_speed == {}, ".\ format(t1pi.geocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'])) log.debug("t2 == {}, ".\ format(Ephemeris.datetimeToStr(t2pi.dt)) + \ "longitude(tropical) == {}, ".\ format(t2pi.geocentric['tropical']['longitude']) + \ "longitude(sidereal) == {}, ".\ format(t2pi.geocentric['sidereal']['longitude']) + \ "longitude_speed == {}, ".\ format(t2pi.geocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'])) # There is no need to update # currLongitudeSpeed here, because the # longitude_speed for 'p' should be the # same polarity. # Update prevLongitudeSpeed. prevLongitudeSpeed = currLongitudeSpeed # Sort all the extra PlanetaryInfo objects by timestamp. additionalPlanetaryInfos = \ sorted(additionalPlanetaryInfos, key=lambda c: c.dt) # Insert PlanetaryInfos from # 'additionalPlanetaryInfos' into 'planetData' at # the timestamp-ordered location. currLoc = 0 for i in range(len(additionalPlanetaryInfos)): pi = additionalPlanetaryInfos[i] insertedFlag = False while currLoc < len(planetData): if pi.dt < planetData[currLoc].dt: planetData.insert(currLoc, pi) insertedFlag = True currLoc += 1 break else: currLoc += 1 if insertedFlag == False: # PlanetaryInfo 'pi' has a timestamp that # is later than the last PlanetaryInfo in # 'planetData', so just append it. planetData.append(pi) # Increment currLoc so that the rest of # the PlanetaryInfos in # 'additionalPlanetaryInfos' can be # appended without doing anymore timestamp tests. currLoc += 1 # Do summations to determine the measurements. showGeocentricRetroAsNegativeTextFlag = True if showGeocentricRetroAsNegativeTextFlag == True: if tropicalZodiacFlag == True: totalDegrees = 0 zodiacType = "tropical" for i in range(len(planetData)): if i != 0: prevPi = planetData[i-1] currPi = planetData[i] if prevPi.geocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'] >= 0: # Direct motion. # Elapsed amount for this segment should be positive. # Find the amount of longitude elasped. longitudeElapsed = \ currPi.geocentric[zodiacType]['longitude'] - \ prevPi.geocentric[zodiacType]['longitude'] # See if there was a crossing of the # 0 degree point or the 360 degree point. # If so, make the necessary adjustments # so that the longitude elapsed is # correct. longitudeElapsed = \ Util.toNormalizedAngle(longitudeElapsed) totalDegrees += longitudeElapsed else: # Retrograde motion. # Elapsed amount for this segment should be negative. # Find the amount of longitude elasped. longitudeElapsed = \ currPi.geocentric[zodiacType]['longitude'] - \ prevPi.geocentric[zodiacType]['longitude'] # See if there was a crossing of the # 0 degree point or the 360 degree point. # If so, make the necessary adjustments # so that the longitude elapsed is # correct. if longitudeElapsed > 0: longitudeElapsed -= 360 totalDegrees += longitudeElapsed # Line of text. We append measurements to # this line of text depending on what # measurements are enabled. line = "G T {} moves ".format(planetName) numCircles = totalDegrees / circleSizeInDegrees numBiblicalCircles = \ totalDegrees / AstrologyUtils.degreesInBiblicalCircle line += "{:.2f} deg ".format(totalDegrees) # Append last part of the line. line += "(r as -)" text += line + os.linesep if centricityType == "heliocentric": if tropicalZodiacFlag == True: totalDegrees = 0 zodiacType = "tropical" for i in range(len(planetData)): if i != 0: prevPi = planetData[i-1] currPi = planetData[i] if prevPi.heliocentric[zodiacTypeForLongitudeSpeed]['longitude_speed'] >= 0: # Direct motion. # Elapsed amount for this segment should be positive. # Find the amount of longitude elasped. longitudeElapsed = \ currPi.heliocentric[zodiacType]['longitude'] - \ prevPi.heliocentric[zodiacType]['longitude'] # See if there was a crossing of the # 0 degree point or the 360 degree point. # If so, make the necessary adjustments # so that the longitude elapsed is # correct. longitudeElapsed = \ Util.toNormalizedAngle(longitudeElapsed) totalDegrees += longitudeElapsed else: # Retrograde motion. # Elapsed amount for this segment should be negative. # Find the amount of longitude elasped. longitudeElapsed = \ currPi.heliocentric[zodiacType]['longitude'] - \ prevPi.heliocentric[zodiacType]['longitude'] # See if there was a crossing of the # 0 degree point or the 360 degree point. # If so, make the necessary adjustments # so that the longitude elapsed is # correct. if longitudeElapsed > 0: longitudeElapsed -= 360 totalDegrees += longitudeElapsed # Line of text. We append measurements to # this line of text depending on what # measurements are enabled. line = "H T {} moves ".format(planetName) numCircles = totalDegrees / circleSizeInDegrees numBiblicalCircles = \ totalDegrees / AstrologyUtils.degreesInBiblicalCircle line += "{:.2f} deg ".format(totalDegrees) text += line + os.linesep text = text.rstrip() return totalDegrees
def getPlanetDiffsForDatetimes(dt1, loc1Tuple, dt2, loc2Tuple): """Returns a string with the planet longitude differences between the given datetimes and location. """ loc1Name = loc1Tuple[0] loc1Longitude = loc1Tuple[1] loc1Latitude = loc1Tuple[2] loc1Elevation = loc1Tuple[3] loc2Name = loc2Tuple[0] loc2Longitude = loc2Tuple[1] loc2Latitude = loc2Tuple[2] loc2Elevation = loc2Tuple[3] longitudeType = "tropical" fieldName = "longitude" rv = "Between datetime: " + Ephemeris.datetimeToDayStr(dt1) + \ ", location: " + loc1Name + " and " + endl rv += " datetime: " + Ephemeris.datetimeToDayStr(dt2) + \ ", location: " + loc2Name + endl calendarDayDiff = dt2 - dt1 rv += " Diff calendar days: {}".format(calendarDayDiff) + endl for planetName in geocentricPlanetNames: longitudeDiff = getLongitudeDiffBetweenDatetimes(planetName, "geocentric", dt1, loc1Tuple, dt2, loc2Tuple) longitudeDiffFullRevs = int(longitudeDiff // 360) longitudeDiffMod360 = longitudeDiff % 360 # Format differently for lunation phase of G.MoSu. if planetName == "MoSu": rv += " {: <16}".format("Diff G." + planetName + ": ") + \ "{:>10.3f}".format(longitudeDiff) + \ " or {:>4} rev + {:>7.3f} deg".format(longitudeDiffFullRevs, longitudeDiffMod360) + \ " PhaseCountTotal: {:.2f}, Phase (of max 30): {:.2f}".\ format(longitudeDiff / 12.0, longitudeDiffMod360 / 12.0) + \ endl else: rv += " {: <16}".format("Diff G." + planetName + ": ") + \ "{:>10.3f}".format(longitudeDiff) + \ " or {:>4} rev + {:>7.3f} deg".format(longitudeDiffFullRevs, longitudeDiffMod360) + \ endl rv += endl for planetName in heliocentricPlanetNames: longitudeDiff = getLongitudeDiffBetweenDatetimes(planetName, "heliocentric", dt1, loc1Tuple, dt2, loc2Tuple) longitudeDiffFullRevs = int(longitudeDiff // 360) longitudeDiffMod360 = longitudeDiff % 360 rv += " {: <16}".format("Diff H." + planetName + ": ") + \ "{:>10.3f}".format(longitudeDiff) + \ " or {:>4} rev + {:>7.3f} deg".format(longitudeDiffFullRevs, longitudeDiffMod360) + \ endl return rv
def shutdown(rc): """Exits the script, but first flushes all logging handles, etc.""" Ephemeris.closeEphemeris() logging.shutdown() sys.exit(rc)
def processPCDD(pcdd, tag): """Module for printing generic information about the PriceBars in a PriceChartDocumentData object. The generic information that is printed includes: - Earliest pricebar timestamp as a datetime.datetime and a julian day. - Latest pricebar timestamp as a datetime.datetime and a julian day. - highest pricebar high price. - lowest pricebar low price. Arguments: pcdd - PriceChartDocumentData object that will be modified. tag - str containing the tag. The value of this field may be "" if a tag is not specified by the user. This implementation doesn't use this field. Returns: 0 if the changes are to be saved to file. 1 if the changes are NOT to be saved to file. This implementation always returns 1. """ # Return value. rv = 1 # Get the number of PriceBars. numPriceBars = len(pcdd.priceBars) # Get the earliest and latest PriceBar. earliestPriceBar = None latestPriceBar = None lowestPrice = None highestPrice = None lowestClosePrice = None highestClosePrice = None for pb in pcdd.priceBars: if earliestPriceBar == None: earliestPriceBar = pb elif pb.timestamp < earliestPriceBar.timestamp: earliestPriceBar = pb if latestPriceBar == None: latestPriceBar = pb elif pb.timestamp > latestPriceBar.timestamp: latestPriceBar = pb if lowestPrice == None: lowestPrice = pb.low elif pb.low < lowestPrice: lowestPrice = pb.low if highestPrice == None: highestPrice = pb.high elif pb.high > highestPrice: highestPrice = pb.high if lowestClosePrice == None: lowestClosePrice = pb.close elif pb.close < lowestClosePrice: lowestClosePrice = pb.close if highestClosePrice == None: highestClosePrice = pb.close elif pb.close > highestClosePrice: highestClosePrice = pb.close log.info("") log.info("Number of PriceBars: {}".format(numPriceBars)) if numPriceBars > 0: # Make sure we got values for everything. if earliestPriceBar == None or \ latestPriceBar == None or \ lowestPrice == None or \ highestPrice == None or \ lowestClosePrice == None or \ highestClosePrice == None: log.error("PriceBars existed, but we are missing some set values.") rv = 1 return rv # Convert the datetimes to julian day. earliestPriceBarJd = \ Ephemeris.datetimeToJulianDay(earliestPriceBar.timestamp) latestPriceBarJd = \ Ephemeris.datetimeToJulianDay(latestPriceBar.timestamp) # Print the information to log. log.info("EarliestPriceBar datetime == {}".\ format(Ephemeris.datetimeToStr(earliestPriceBar.timestamp))) log.info("LatestPriceBar datetime == {}".\ format(Ephemeris.datetimeToStr(latestPriceBar.timestamp))) log.info( "EarliestPriceBar julian day == {}".format(earliestPriceBarJd)) log.info("LatestPriceBar julian day == {}".format(latestPriceBarJd)) log.info("Lowest PriceBar LOW price == {}".format(highestPrice)) log.info("Highest PriceBar HIGH price == {}".format(highestPrice)) log.info("Lowest PriceBar CLOSE price == {}".format(highestPrice)) log.info("Highest PriceBar CLOSE price == {}".format(highestPrice)) log.info("") rv = 1 return rv