Spaces:
Sleeping
Sleeping
File size: 3,866 Bytes
6ee917b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | import Foundation
/// The required functions to implement a reader that provides derived variables
protocol GenericReaderDerived: GenericReaderProtocol {
associatedtype Derived: RawRepresentableString
associatedtype ReaderNext: GenericReaderProtocol
var reader: ReaderNext { get }
func get(derived: Derived, time: TimerangeDtAndSettings) throws -> DataAndUnit
func prefetchData(derived: Derived, time: TimerangeDtAndSettings) throws
func get(raw: ReaderNext.MixingVar, time: TimerangeDtAndSettings) throws -> DataAndUnit
func prefetchData(raw: ReaderNext.MixingVar, time: TimerangeDtAndSettings) throws
}
/// Parameters for tilted radiation calculation
struct GenericReaderOptions {
/// Tilt of a solar panel for GTI calculation. 0° horizontal, 90° vertical.
private var tilt: Float
/// Azimuth of a solar panel for GTI calculation. 0° south, -90° east, 90° west
private var azimuth: Float
public init(tilt: Float? = nil, azimuth: Float? = nil) {
self.tilt = tilt ?? 0
self.azimuth = azimuth ?? 0
}
/// Tilt of a solar panel for GTI calculation. 0° horizontal, 90° vertical. Throws out of bounds error.
func getTilt() throws -> Float {
guard tilt.isNaN || (tilt >= 0 && tilt <= 90) else {
throw ForecastapiError.generic(message: "Parameter `&tilt=` must be within 0° and 90°")
}
return tilt
}
/// Azimuth of a solar panel for GTI calculation. 0° south, -90° east, 90° west. Throws out of bounds error.
func getAzimuth() throws -> Float {
guard azimuth.isNaN || (azimuth >= -180 && azimuth <= 180) else {
throw ForecastapiError.generic(message: "Parameter `&azimuth=` must be within -180° and 180°")
}
return azimuth
}
}
extension GenericReaderDerived {
var modelLat: Float {
reader.modelLat
}
/*var domain: ReaderNext.Domain {
return reader.domain
}*/
var modelLon: Float {
reader.modelLon
}
var modelElevation: ElevationOrSea {
reader.modelElevation
}
var modelDtSeconds: Int {
reader.modelDtSeconds
}
var targetElevation: Float {
reader.targetElevation
}
func prefetchData(variable: VariableOrDerived<ReaderNext.MixingVar, Derived>, time: TimerangeDtAndSettings) throws {
switch variable {
case .raw(let raw):
return try prefetchData(raw: raw, time: time)
case .derived(let derived):
return try prefetchData(derived: derived, time: time)
}
}
func get(variable: VariableOrDerived<ReaderNext.MixingVar, Derived>, time: TimerangeDtAndSettings) throws -> DataAndUnit {
switch variable {
case .raw(let raw):
return try get(raw: raw, time: time)
case .derived(let derived):
return try get(derived: derived, time: time)
}
}
func getStatic(type: ReaderStaticVariable) throws -> Float? {
return try reader.getStatic(type: type)
}
func prefetchData(variables: [VariableOrDerived<ReaderNext.MixingVar, Derived>], time: TimerangeDtAndSettings) throws {
try variables.forEach { variable in
try prefetchData(variable: variable, time: time)
}
}
}
/// A reader that does not modify reader. E.g. pass all reads directly to reader
protocol GenericReaderDerivedSimple: GenericReaderDerived {
}
extension GenericReaderDerivedSimple {
func get(raw: ReaderNext.MixingVar, time: TimerangeDtAndSettings) throws -> DataAndUnit {
try reader.get(variable: raw, time: time)
}
func prefetchData(raw: ReaderNext.MixingVar, time: TimerangeDtAndSettings) throws {
try reader.prefetchData(variable: raw, time: time)
}
}
|