• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dsavransky / EXOSIMS / 14319210709

07 Apr 2025 08:50PM UTC coverage: 66.192% (+0.7%) from 65.466%
14319210709

Pull #408

github

web-flow
Merge d3c65c73b into 207b4b0d8
Pull Request #408: Performance optimization

769 of 923 new or added lines in 32 files covered. (83.32%)

20 existing lines in 9 files now uncovered.

9907 of 14967 relevant lines covered (66.19%)

0.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.0
/EXOSIMS/util/phaseFunctions.py
1
"""
2
Phase Functions
3

4
See also [Keithly2021]_
5
"""
6

7
import numpy as np
1✔
8
from astropy import units as u
1✔
9

10

11
def phi_lambert(beta, phiIndex=np.asarray([])):
1✔
12
    """Lambert phase function (isotropic scattering)
13

14
    See: [Sobolev1975]_
15

16
    Args:
17
        beta (astropy.units.quantity.Quantity or numpy.ndarray):
18
            phase angle array in radians
19
        phiIndex (numpy.ndarray):
20
            array of indicies of type of exoplanet phase function to use, ints 0-7
21

22
    Returns:
23
        numpy.ndarray:
24
            Phi, phase function values between 0 and 1
25
    """
26
    if isinstance(beta, u.Quantity):
1✔
NEW
27
        beta = beta.to_value(u.rad)
×
28

29
    phi = (np.sin(beta) + (np.pi - beta) * np.cos(beta)) / np.pi
1✔
30
    return phi
1✔
31

32

33
def transitionStart(x, a, b):
1✔
34
    """Smoothly transition from one 0 to 1
35

36
    Args:
37
        x (numpy.ndarray):
38
            x, in deg input value in deg, floats
39
        a (numpy.ndarray):
40
            transition midpoint in deg, floats
41
        b (numpy.ndarray):
42
            transition slope
43
    Returns:
44
        numpy.ndarray:
45
            s, Transition value from 0 to 1, floats
46
    """
47
    s = 0.5 + 0.5 * np.tanh((x - a) / b)
1✔
48
    return s
1✔
49

50

51
def transitionEnd(x, a, b):
1✔
52
    """Smoothly transition from one 1 to 0
53

54
    Smaller b is sharper step a is midpoint, s(a)=0.5
55

56
    Args:
57
        x (numpy.ndarray):
58
            x, in deg input value in deg, floats
59
        a (numpy.ndarray):
60
            a, transition midpoint in deg, floats
61
        b (numpy.ndarray):
62
            transition slope
63

64
    Returns:
65
        numpy.ndarray:
66
            s, transition value from 1 to 0
67
    """
68
    s = 0.5 - 0.5 * np.tanh((x - a) / b)
1✔
69
    return s
1✔
70

71

72
def quasiLambertPhaseFunction(beta, phiIndex=np.asarray([])):
1✔
73
    """Quasi Lambert Phase Function from [Agol2007]_
74

75
    Args:
76
        beta (astropy.units.quantity.Quantity or numpy.ndarray):
77
            planet phase angles in radians
78
        phiIndex (numpy.ndarray):
79
            array of indicies of type of exoplanet phase function to use, ints 0-7
80

81
    Returns:
82
        numpy.ndarray:
83
            Phi, phase function value
84
    """
85
    if isinstance(beta, u.Quantity):
1✔
NEW
86
        beta = beta.to_value(u.rad)
×
87

88
    Phi = np.cos(beta / 2.0) ** 4
1✔
89
    return Phi
1✔
90

91

92
def quasiLambertPhaseFunctionInverse(Phi, phiIndex=np.asarray([])):
1✔
93
    """Quasi Lambert Phase Function Inverse
94

95
    Args:
96
        Phi (numpy.ndarray):
97
            Phi, phase function value, floats
98
        phiIndex (numpy.ndarray):
99
            array of indicies of type of exoplanet phase function to use, ints 0-7
100

101
    Returns:
102
        numpy.ndarray:
103
            beta, planet phase angles in rad, floats
104
    """
105

106
    beta = 2.0 * np.arccos((Phi) ** (1.0 / 4.0))
1✔
107
    return beta
1✔
108

109

110
def hyperbolicTangentPhaseFunc(beta, A, B, C, D, planetName=None):
1✔
111
    """
112
    Optimal Parameters for Earth Phase Function basedon mallama2018 comparison using
113
    mallama2018PlanetProperties.py:
114
    A=1.85908529,  B=0.89598952,  C=1.04850586, D=-0.08084817
115
    Optimal Parameters for All Solar System Phase Function basedon mallama2018
116
    comparison using mallama2018PlanetProperties.py:
117
    A=0.78415 , B=1.86890455, C=0.5295894 , D=1.07587213
118

119
    Args:
120
        beta (astropy.units.quantity.Quantity or numpy.ndarray):
121
            Phase Angle in radians
122
        A (float):
123
            Hyperbolic phase function parameter
124
        B (float):
125
            Hyperbolic phase function paramter
126
        C (float):
127
            Hyperbolic phase function parameter
128
        D (float):
129
            Hyperbolic phase function parameter
130
        planetName (string or None):
131
            planet name string all lower case for one of 8 solar system planets
132

133
    Returns:
134
        numpy.ndarray:
135
            Phi, phase angle in degrees
136
    """
137
    if planetName is None:
1✔
138
        return None  # do nothing
×
139
    elif planetName == "mercury":
1✔
140
        A, B, C, D = (
1✔
141
            0.9441564,
142
            0.3852919,
143
            2.59291159,
144
            -0.67540991,
145
        )  # 0.93940195,  0.40446512,  2.47034733, -0.64361749
146
    elif planetName == "venus":
1✔
147
        A, B, C, D = (
1✔
148
            1.20324931,
149
            1.57402581,
150
            0.60683886,
151
            0.87010846,
152
        )  # 1.26116739, 1.53204409, 0.61961161, 0.84075693
153
    elif planetName == "earth":
1✔
154
        A, B, C, D = (
1✔
155
            0.78414986,
156
            1.86890464,
157
            0.52958938,
158
            1.07587225,
159
        )  # 0.78415   , 1.86890455, 0.5295894 , 1.07587213
160
    elif planetName == "mars":
1✔
161
        A, B, C, D = (
1✔
162
            1.89881785,
163
            0.48220465,
164
            2.02299497,
165
            -1.02612681,
166
        )  # 2.02856459,  0.29590061,  3.32324214, -1.71048535
167
    elif planetName == "jupiter":
1✔
168
        A, B, C, D = (
1✔
169
            1.3622441,
170
            1.45676529,
171
            0.64490468,
172
            0.7800663,
173
        )  # 1.3761512 , 1.45852349, 0.64157352, 0.7983722
174
    elif planetName == "saturn":
1✔
175
        A, B, C, D = (
1✔
176
            5.02672862,
177
            0.41588155,
178
            1.80205383,
179
            -1.74369974,
180
        )  # 5.49410541,  0.37274869,  2.00119662, -2.1551928
181
    elif planetName == "uranus":
1✔
182
        A, B, C, D = (
1✔
183
            1.54388146,
184
            1.18304642,
185
            0.79972526,
186
            0.37288376,
187
        )  # 1.56866334, 1.16284633, 0.81250327, 0.34759469
188
    elif planetName == "neptune":
1✔
189
        A, B, C, D = (
1✔
190
            1.31369238,
191
            1.41437107,
192
            0.67584636,
193
            0.65077278,
194
        )  # 1.37105297, 1.36886173, 0.69506274, 0.609515
195

196
    if hasattr(beta, "value"):
1✔
197
        beta = beta.to("rad").value
1✔
198

199
    Phi = -np.tanh((beta - D) / A) / B + C
1✔
200
    return Phi
1✔
201

202

203
def hyperbolicTangentPhaseFuncInverse(Phi, A, B, C, D, planetName=None):
1✔
204
    """
205
    Optimal Parameters for Earth Phase Function basedon mallama2018 comparison
206
    using mallama2018PlanetProperties.py:
207
    A=1.85908529,  B=0.89598952,  C=1.04850586, D=-0.08084817
208
    Optimal Parameters for All Solar System Phase Function basedon mallama2018
209
    comparison using mallama2018PlanetProperties.py:
210
    A=0.78415 , B=1.86890455, C=0.5295894 , D=1.07587213
211

212
    Args:
213
        Phi (numpy.ndarray):
214
            phase angle in degrees
215
        A (float):
216
            Hyperbolic phase function parameter
217
        B (float):
218
            Hyperbolic phase function paramter
219
        C (float):
220
            Hyperbolic phase function parameter
221
        D (float):
222
            Hyperbolic phase function parameter
223
        planetName (string or None):
224
            planet name string all lower case for one of 8 solar system planets
225

226
    Returns:
227
        numpy.ndarray:
228
            beta, Phase Angle  in degrees
229
    """
230
    if planetName is None:
1✔
231
        return None  # do nothing
×
232
    elif planetName == "mercury":
1✔
233
        A, B, C, D = (
1✔
234
            0.9441564,
235
            0.3852919,
236
            2.59291159,
237
            -0.67540991,
238
        )  # 0.93940195,  0.40446512,  2.47034733, -0.64361749
239
    elif planetName == "venus":
1✔
240
        A, B, C, D = (
1✔
241
            1.20324931,
242
            1.57402581,
243
            0.60683886,
244
            0.87010846,
245
        )  # 1.26116739, 1.53204409, 0.61961161, 0.84075693
246
    elif planetName == "earth":
1✔
247
        A, B, C, D = (
1✔
248
            0.78414986,
249
            1.86890464,
250
            0.52958938,
251
            1.07587225,
252
        )  # 0.78415   , 1.86890455, 0.5295894 , 1.07587213
253
    elif planetName == "mars":
1✔
254
        A, B, C, D = (
1✔
255
            1.89881785,
256
            0.48220465,
257
            2.02299497,
258
            -1.02612681,
259
        )  # 2.02856459,  0.29590061,  3.32324214, -1.71048535
260
    elif planetName == "jupiter":
1✔
261
        A, B, C, D = (
1✔
262
            1.3622441,
263
            1.45676529,
264
            0.64490468,
265
            0.7800663,
266
        )  # 1.3761512 , 1.45852349, 0.64157352, 0.7983722
267
    elif planetName == "saturn":
1✔
268
        A, B, C, D = (
1✔
269
            5.02672862,
270
            0.41588155,
271
            1.80205383,
272
            -1.74369974,
273
        )  # 5.49410541,  0.37274869,  2.00119662, -2.1551928
274
    elif planetName == "uranus":
1✔
275
        A, B, C, D = (
1✔
276
            1.54388146,
277
            1.18304642,
278
            0.79972526,
279
            0.37288376,
280
        )  # 1.56866334, 1.16284633, 0.81250327, 0.34759469
281
    elif planetName == "neptune":
1✔
282
        A, B, C, D = (
1✔
283
            1.31369238,
284
            1.41437107,
285
            0.67584636,
286
            0.65077278,
287
        )  # 1.37105297, 1.36886173, 0.69506274, 0.609515
288

289
    beta = ((A * np.arctanh(-B * (Phi - C)) + D) * u.radian).to("deg").value
1✔
290
    return beta
1✔
291

292

293
def betaFunc(inc, v, w):
1✔
294
    """Calculate the planet phase angle
295

296
    Args:
297
        inc (float or numpy.ndarray):
298
            planet inclination in rad
299
        v (numpy.ndarray):
300
            planet true anomaly in rad
301
        w (numpy.ndarray):
302
            planet argument of periapsis
303

304
    Returns:
305
        numpy.ndarray:
306
            beta, planet phase angle
307
    """
308
    beta = np.arccos(np.sin(inc) * np.sin(v + w))
1✔
309
    return beta
1✔
310

311

312
def phase_Mercury(beta):
1✔
313
    """Mercury phase function
314
    Valid from 0 to 180 deg
315

316
    Args:
317
        beta (numpy.ndarray):
318
            beta, phase angle in degrees
319

320
    Returns:
321
        numpy.ndarray:
322
            phase function values
323
    """
324
    phase = 10.0 ** (
×
325
        -0.4
326
        * (
327
            6.3280e-02 * beta
328
            - 1.6336e-03 * beta**2.0
329
            + 3.3644e-05 * beta**3.0
330
            - 3.4265e-07 * beta**4.0
331
            + 1.6893e-09 * beta**5.0
332
            - 3.0334e-12 * beta**6.0
333
        )
334
    )
335
    return phase
×
336

337

338
def phase_Venus_1(beta):
1✔
339
    """Venus phase function
340
    Valid from 0 to 163.7 deg
341

342
    Args:
343
        beta (numpy.ndarray):
344
            beta, phase angle in degrees
345

346
    Returns:
347
        numpy.ndarray:
348
            phase function values
349
    """
350
    phase = 10.0 ** (
×
351
        -0.4
352
        * (
353
            -1.044e-03 * beta
354
            + 3.687e-04 * beta**2.0
355
            - 2.814e-06 * beta**3.0
356
            + 8.938e-09 * beta**4.0
357
        )
358
    )
359
    return phase
×
360

361

362
def phase_Venus_2(beta):
1✔
363
    """Venus phase function
364
    Valid from 163.7 to 179 deg
365

366
    Args:
367
        beta (numpy.ndarray):
368
            beta, phase angle in degrees
369

370
    Returns:
371
        numpy.ndarray:
372
            phase function values
373
    """
374
    phase = 10.0 ** (-0.4 * (-2.81914e-00 * beta + 8.39034e-03 * beta**2.0))
×
375
    # 1 Scale Properly
376
    h1 = phase_Venus_1(163.7) - 0.0  # Total height desired over range
×
377
    h2 = 10.0 ** (
×
378
        -0.4 * (-2.81914e-00 * 163.7 + 8.39034e-03 * 163.7**2.0)
379
    ) - 10.0 ** (-0.4 * (-2.81914e-00 * 179.0 + 8.39034e-03 * 179.0**2.0))
380
    phase = phase * h1 / h2  # Scale so height is proper
×
381
    # 2 Lateral movement to make two functions line up
382
    difference = phase_Venus_1(163.7) - h1 / h2 * (
×
383
        10.0 ** (-0.4 * (-2.81914e-00 * 163.7 + 8.39034e-03 * 163.7**2.0))
384
    )
385
    phase = phase + difference
×
386
    return phase
×
387

388

389
def phase_Venus_melded(beta):
1✔
390
    """
391
    Venus phae function
392
    Valid from 0 to 180 deg
393

394
    Args:
395
        beta (numpy.ndarray):
396
            beta, phase angle in degrees
397

398
    Returns:
399
        numpy.ndarray:
400
            phase function values
401
    """
402
    phase = (
×
403
        transitionEnd(beta, 163.7, 5.0) * phase_Venus_1(beta)
404
        + transitionStart(beta, 163.7, 5.0)
405
        * transitionEnd(beta, 179.0, 0.5)
406
        * phase_Venus_2(beta)
407
        + transitionStart(beta, 179.0, 0.5) * phi_lambert(beta * np.pi / 180.0)
408
        + 2.766e-04
409
    )
410
    # 2.666e-04 ensures the phase function is entirely positive
411
    # (near 180 deg phase, there is a small region
412
    # where phase goes negative) This small addition fixes this
413
    return phase
×
414

415

416
def phase_Earth(beta):
1✔
417
    """Earth phase function
418
    Valid from 0 to 180 deg
419

420
    Args:
421
        beta (numpy.ndarray):
422
            beta, phase angle in degrees
423

424
    Returns:
425
        numpy.ndarray:
426
            phase function values
427
    """
428
    phase = 10.0 ** (-0.4 * (-1.060e-3 * beta + 2.054e-4 * beta**2.0))
×
429
    return phase
×
430

431

432
def phase_Mars_1(beta):
1✔
433
    """Mars phase function
434
    Valid from 0 to 50 deg
435

436
    Args:
437
        beta (numpy.ndarray):
438
            beta, phase angle in degrees
439

440
    Returns:
441
        numpy.ndarray:
442
            phase function values
443
    """
444
    phase = 10.0 ** (
×
445
        -0.4 * (0.02267 * beta - 0.0001302 * beta**2.0 + 0.0 + 0.0)
446
    )  # L(λe) + L(LS)
447
    return phase
×
448

449

450
def phase_Mars_2(beta):
1✔
451
    """Mars phase function
452
    Valid from 50 to 180 deg
453

454
    Args:
455
        beta (numpy.ndarray):
456
            beta, phase angle in degrees
457

458
    Returns:
459
        numpy.ndarray:
460
            phase function values
461
    """
462
    phase = (
×
463
        phase_Mars_1(50.0)
464
        / 10.0 ** (-0.4 * (-0.02573 * 50.0 + 0.0003445 * 50.0**2.0))
465
        * 10.0 ** (-0.4 * (-0.02573 * beta + 0.0003445 * beta**2.0 + 0.0 + 0.0))
466
    )  # L(λe) + L(Ls)
467
    return phase
×
468

469

470
def phase_Mars_melded(beta):
1✔
471
    """Mars phase function
472
    Valid from 0 to 180 degrees
473

474
    Args:
475
        beta (numpy.ndarray):
476
            beta, phase angle in degrees
477

478
    Returns:
479
        numpy.ndarray:
480
            phase function values
481
    """
482
    phase = transitionEnd(beta, 50.0, 5.0) * phase_Mars_1(beta) + transitionStart(
×
483
        beta, 50.0, 5.0
484
    ) * phase_Mars_2(beta)
485
    return phase
×
486

487

488
def phase_Jupiter_1(beta):
1✔
489
    """Jupiter phase function
490
    Valid from 0 to 12 deg
491

492
    Args:
493
        beta (numpy.ndarray):
494
            beta, phase angle in degrees
495

496
    Returns:
497
        numpy.ndarray:
498
            phase function values
499
    """
500
    phase = 10.0 ** (-0.4 * (-3.7e-04 * beta + 6.16e-04 * beta**2.0))
×
501
    return phase
×
502

503

504
def phase_Jupiter_2(beta):
1✔
505
    """Jupiter phase function
506
    Valid from 12 to 130 deg
507

508
    Args:
509
        beta (numpy.ndarray):
510
            beta, phase angle in degrees
511

512
    Returns:
513
        numpy.ndarray:
514
            phase function values
515
    """
516
    # inds = np.where(beta > 180.0)[0]
517
    # beta[inds] = [180.0] * len(inds)
518
    # assert np.all(
519
    #     (
520
    #         1.0
521
    #         - 1.507 * (beta / 180.0)
522
    #         - 0.363 * (beta / 180.0) ** 2.0
523
    #         - 0.062 * (beta / 180.0) ** 3.0
524
    #         + 2.809 * (beta / 180.0) ** 4.0
525
    #         - 1.876 * (beta / 180.0) ** 5.0
526
    #     )
527
    #     >= 0.0
528
    # ), "error in beta input"
529

530
    difference = phase_Jupiter_1(12.0) - 10.0 ** (
×
531
        -0.4
532
        * (
533
            -2.5
534
            * np.log10(
535
                1.0
536
                - 1.507 * (12.0 / 180.0)
537
                - 0.363 * (12.0 / 180.0) ** 2.0
538
                - 0.062 * (12.0 / 180.0) ** 3.0
539
                + 2.809 * (12.0 / 180.0) ** 4.0
540
                - 1.876 * (12.0 / 180.0) ** 5.0
541
            )
542
        )
543
    )
544
    phase = difference + 10.0 ** (
×
545
        -0.4
546
        * (
547
            -2.5
548
            * np.log10(
549
                1.0
550
                - 1.507 * (beta / 180.0)
551
                - 0.363 * (beta / 180.0) ** 2.0
552
                - 0.062 * (beta / 180.0) ** 3.0
553
                + 2.809 * (beta / 180.0) ** 4.0
554
                - 1.876 * (beta / 180.0) ** 5.0
555
            )
556
        )
557
    )
558
    return phase
×
559

560

561
def phase_Jupiter_melded(beta):
1✔
562
    """Jupiter phase function
563
    Valid from 0 to 130 degrees
564

565
    Args:
566
        beta (numpy.ndarray):
567
            beta, phase angle in degrees
568

569
    Returns:
570
        numpy.ndarray:
571
            phase function values
572
    """
573
    phase = (
×
574
        transitionEnd(beta, 12.0, 5.0) * phase_Jupiter_1(beta)
575
        + transitionStart(beta, 12.0, 5.0)
576
        * transitionEnd(beta, 130.0, 5.0)
577
        * phase_Jupiter_2(beta)
578
        + transitionStart(beta, 130.0, 5.0) * phi_lambert(beta * np.pi / 180.0)
579
    )
580
    return phase
×
581

582

583
def phase_Saturn_2(beta):
1✔
584
    """Saturn phase function (Globe Only Earth Observations)
585
    Valid beta from 0 to 6.5 deg
586

587
    Args:
588
        beta (numpy.ndarray):
589
            beta, phase angle in degrees
590

591
    Returns:
592
        numpy.ndarray:
593
            phase function values
594
    """
595
    phase = 10.0 ** (-0.4 * (-3.7e-04 * beta + 6.16e-04 * beta**2.0))
×
596
    return phase
×
597

598

599
def phase_Saturn_3(beta):
1✔
600
    """Saturn phase function (Globe Only Pioneer Observations)
601
    Valid beta from 6 to 150. deg
602

603
    Args:
604
        beta (numpy.ndarray):
605
            beta, phase angle in degrees
606

607
    Returns:
608
        numpy.ndarray:
609
            phase function values
610
    """
611
    difference = phase_Saturn_2(6.5) - 10.0 ** (
×
612
        -0.4
613
        * (
614
            2.446e-4 * 6.5
615
            + 2.672e-4 * 6.5**2.0
616
            - 1.505e-6 * 6.5**3.0
617
            + 4.767e-9 * 6.5**4.0
618
        )
619
    )
620
    phase = difference + 10.0 ** (
×
621
        -0.4
622
        * (
623
            2.446e-4 * beta
624
            + 2.672e-4 * beta**2.0
625
            - 1.505e-6 * beta**3.0
626
            + 4.767e-9 * beta**4.0
627
        )
628
    )
629
    return phase
×
630

631

632
def phase_Saturn_melded(beta):
1✔
633
    """
634
    Saturn phase function
635

636
    Args:
637
        beta (numpy.ndarray):
638
            beta, phase angle in degrees
639

640
    Returns:
641
        numpy.ndarray:
642
            phase function values
643
    """
644
    phase = (
×
645
        transitionEnd(beta, 6.5, 5.0) * phase_Saturn_2(beta)
646
        + transitionStart(beta, 6.5, 5.0)
647
        * transitionEnd(beta, 150.0, 5.0)
648
        * phase_Saturn_3(beta)
649
        + transitionStart(beta, 150.0, 5.0) * phi_lambert(beta * np.pi / 180.0)
650
    )
651
    return phase
×
652

653

654
def phiprime_phi(phi):
1✔
655
    """Helper method for Uranus phase function
656
    Valid for phi from -82 to 82 deg
657

658
    Args:
659
        phi (numpy.ndarray):
660
            phi, planet rotation axis offset in degrees, floats
661

662
    Returns:
663
        numpy.ndarray:
664
            phiprime, in deg, floats
665
    """
666
    f = 0.0022927  # flattening of the planet
×
667
    phiprime = np.arctan2(np.tan(phi * np.pi / 180.0), (1.0 - f) ** 2.0) * 180.0 / np.pi
×
668
    return phiprime
×
669

670

671
def phase_Uranus(beta, phi=-82.0):
1✔
672
    """Uranus phase function
673
    Valid for beta 0 to 154 deg
674

675
    Args:
676
        beta (numpy.ndarray):
677
            beta, phase angle in degrees
678
        phi (float or numpy.ndarray):
679
            phi, planet rotation axis offset in degrees, floats
680

681
    Returns:
682
        numpy.ndarray:
683
            phase function values
684
    """
685

686
    phase = 10.0 ** (
×
687
        -0.4 * (-8.4e-04 * phiprime_phi(phi) + 6.587e-3 * beta + 1.045e-4 * beta**2.0)
688
    )
689
    return phase
×
690

691

692
def phase_Uranus_melded(beta):
1✔
693
    """Uranus phase function
694

695
    Args:
696
        beta (numpy.ndarray):
697
            beta, phase angle in degrees
698

699
    Returns:
700
        numpy.ndarray:
701
            phase function values
702
    """
703
    phase = transitionEnd(beta, 154.0, 5.0) * phase_Uranus(beta) + transitionStart(
×
704
        beta, 154.0, 5.0
705
    ) * phi_lambert(beta * np.pi / 180.0)
706
    return phase
×
707

708

709
def phase_Neptune(beta):
1✔
710
    """Neptune phase function
711
    Valid for beta 0 to 133.14 deg
712

713
    Args:
714
        beta (numpy.ndarray):
715
            beta, phase angle in degrees
716

717
    Returns:
718
        numpy.ndarray:
719
            phase function values
720
    """
721
    phase = 10.0 ** (-0.4 * (7.944e-3 * beta + 9.617e-5 * beta**2.0))
×
722
    return phase
×
723

724

725
def phase_Neptune_melded(beta):
1✔
726
    """Neptune phase function
727

728
    Args:
729
        beta (numpy.ndarray):
730
            beta, phase angle in degrees
731

732
    Returns:
733
        numpy.ndarray:
734
            phase function values
735
    """
736
    phase = transitionEnd(beta, 133.14, 5.0) * phase_Neptune(beta) + transitionStart(
×
737
        beta, 133.14, 5.0
738
    ) * phi_lambert(beta * np.pi / 180.0)
739
    return phase
×
740

741

742
def realSolarSystemPhaseFunc(beta, phiIndex=np.asarray([])):
1✔
743
    """Uses the phase functions from Mallama 2018 implemented in
744
    mallama2018PlanetProperties.py
745

746
    Args:
747
        beta (astropy.units.quantity.Quantity or numpy.ndarray):
748
            phase angle array in degrees
749
        phiIndex (numpy.ndarray):
750
            array of indicies of type of exoplanet phase function to use, ints 0-7
751

752
    Returns:
753
        numpy.ndarray:
754
            Phi, phase function values between 0 and 1
755
    """
756
    if len(phiIndex) == 0:  # Default behavior is to use the lambert phase function
×
757
        Phi = np.zeros(len(beta))  # instantiate initial array
×
758
        Phi = phi_lambert(beta)
×
759
    else:
760
        if hasattr(beta, "unit"):
×
761
            beta = beta.to("rad").value
×
762
        beta = beta * 180.0 / np.pi  # convert to phase angle in degrees
×
763

764
        if not len(phiIndex) == 0 and (len(beta) == 1 or len(beta) == 0):
×
765
            beta = np.ones(len(phiIndex)) * beta
×
766
        Phi = np.zeros(len(beta))
×
767

768
        # Find indicies of where to use each phase function
769
        mercuryInds = np.where(phiIndex == 0)[0]
×
770
        venusInds = np.where(phiIndex == 1)[0]
×
771
        earthInds = np.where(phiIndex == 2)[0]
×
772
        marsInds = np.where(phiIndex == 3)[0]
×
773
        jupiterInds = np.where(phiIndex == 4)[0]
×
774
        saturnInds = np.where(phiIndex == 5)[0]
×
775
        uranusInds = np.where(phiIndex == 6)[0]
×
776
        neptuneInds = np.where(phiIndex == 7)[0]
×
777

778
        if not len(mercuryInds) == 0:
×
779
            Phi[mercuryInds] = phase_Mercury(beta[mercuryInds])
×
780
        if not len(venusInds) == 0:
×
781
            Phi[venusInds] = phase_Venus_melded(beta[venusInds])
×
782
        if not len(earthInds) == 0:
×
783
            Phi[earthInds] = phase_Earth(beta[earthInds])
×
784
        if not len(marsInds) == 0:
×
785
            Phi[marsInds] = phase_Mars_melded(beta[marsInds])
×
786
        if not len(jupiterInds) == 0:
×
787
            Phi[jupiterInds] = phase_Jupiter_melded(beta[jupiterInds])
×
788
        if not len(saturnInds) == 0:
×
789
            Phi[saturnInds] = phase_Saturn_melded(beta[saturnInds])
×
790
        if not len(uranusInds) == 0:
×
791
            Phi[uranusInds] = phase_Uranus_melded(beta[uranusInds])
×
792
        if not len(neptuneInds) == 0:
×
793
            Phi[neptuneInds] = phase_Neptune_melded(beta[neptuneInds])
×
794

795
    return Phi
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc