spectractor.simulation package

Submodules

spectractor.simulation.atmosphere module

class spectractor.simulation.atmosphere.Atmosphere(airmass, pressure, temperature, lambda_min=250, lambda_max=1200, altitude=2.2)[source]

Bases: object

plot_transmission(lambdas=array([300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099]))[source]

Plot the atmospheric transmission computed with Libradtran.

Parameters:

lambdas (array_like, optional) – Array of wavelengths in nm (default: parameters.LAMBDAS).

Examples

>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM='libradtran'
>>> a = Atmosphere(airmass=1.2, pressure=800, temperature=5)
>>> transmission = a.simulate(ozone=400, pwv=5, aerosols=0.05)
>>> a.plot_transmission()
set_label()[source]

Make a label string for the simulation.

set_lambda_range(lambdas)[source]

Reset the Atmosphere wavelength range for optimized computations.

Parameters:

lambdas (array_like) – Wavelength array in nm.

Examples

>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM='libradtran'
>>> a = Atmosphere(airmass=1.2, pressure=800, temperature=5, lambda_min=350, lambda_max=1000)
>>> a.lambda_min
350
>>> a.lambda_max
1000
>>> a.set_lambda_range(np.arange(400, 810, 10))
>>> a.lambda_min
400
>>> a.lambda_max
800
set_title()[source]

Make a title string for the simulation.

simulate(aerosols, ozone, pwv, angstrom_exponent=None)[source]

Simulate the atmosphere transparency with Libradtran given atmospheric composition.

Values outside the Libradtran simulation range are set to zero.

Parameters:
  • aerosols (float) – VAOD Vertical Aerosols Optical Depth.

  • ozone (float) – Ozone quantity in Dobson.

  • pwv (float) – Precipitable Water Vapor quantity in mm.

  • angstrom_exponent (float, optional) – Angstrom exponent for aerosols. If None, the Atmosphere.angstrom_exponent_default value is used (default: None).

Returns:

transmission – The transmission function of wavelengths in nm.

Return type:

callable

Examples

>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM = "getobsatmo"
>>> a = Atmosphere(airmass=1.2, pressure=800, temperature=5, lambda_min=350, lambda_max=1000)
CTIO site name validated as CTIO observatory
>>> transmission = a.simulate(aerosols=0.05, ozone=400, pwv=5, angstrom_exponent=None)
>>> a.ozone
400
>>> a.pwv
5
>>> a.aerosols
0.05
>>> transmission([350, 550, 600, 800, 950])
array([0.49958183, 0.82905252, 0.83742397, 0.93720044, 0.71533991])
>>> a.plot_transmission()
>>> transmission_ang_exp = a.simulate(aerosols=0.05, ozone=400, pwv=5, angstrom_exponent=2)
>>> transmission_ang_exp([350, 550, 600, 800, 950])
array([0.48462457, 0.83231609, 0.84292117, 0.94728051, 0.72336351])
>>> a.plot_transmission()

Test concordance of atmospheric simualtors without emulator

>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM = "libradtran"
>>> transmission_ang_exp2 = a.simulate(aerosols=0.05, ozone=400, pwv=5, angstrom_exponent=2)
>>> assert np.isclose(transmission_ang_exp2([350, 550, 600, 800, 950]), [0.4846117, 0.8323524, 0.8426985, 0.9465884, 0.71872], 1e-5).all()

(Source code)

class spectractor.simulation.atmosphere.AtmosphereGrid(image_filename='', spectrum_filename='', atmgrid_filename='', airmass=1.0, pressure=800.0, temperature=10.0, pwv_grid=[0, 10, 10], ozone_grid=[100, 700, 7], aerosol_grid=[0, 0.1, 10], lambdas=array([300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099]), altitude=2.2)[source]

Bases: Atmosphere

compute()[source]

Compute atmospheric transmissions and fill self.atmgrid.

The wavelengths used for the computation are the ones set by self.lambdas.

Returns:

atmospheric_grid – The atmospheric grid self.atmgrid.

Return type:

array_like

Examples

>>> a = AtmosphereGrid(image_filename='tests/data/reduc_20170605_028.fits',
... pwv_grid=[5, 5, 1], ozone_grid=[400, 400, 1], aerosol_grid=[0.0, 0.1, 2])
>>> atmospheric_grid = a.compute()
>>> atmospheric_grid  
array([[0.000000e+00, ...
       ...])
>>> a.save_file(a.image_filename.replace('.fits', '_atmsim.fits'))
>>> a.plot_transmission()

(Source code)

load_file(filename)[source]

Load the atmospheric grid from a fits file and interpolate across the points using RegularGridInterpolator. Automatically called from __init__.

Parameters:

filename (str) – The input file name.

Examples

>>> a = AtmosphereGrid(image_filename='tests/data/reduc_20170605_028.fits',
... pwv_grid=[5, 5, 1], ozone_grid=[400, 400, 1], aerosol_grid=[0.0, 0.1, 2])
>>> atmospheric_grid = a.compute()
>>> a.save_file(a.image_filename.replace('.fits', '_atmsim.fits'))
>>> assert os.path.isfile('tests/data/reduc_20170605_028_atmsim.fits')
>>> a.load_file(a.image_filename.replace('.fits', '_atmsim.fits'))
>>> a.AER_Points
array([0. , 0.1])
>>> a.PWV_Points
array([5.])
>>> a.OZ_Points
array([400.])
plot_transmission(lambdas=array([300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099]))[source]

Plot the atmospheric transmission contained in the grid.

Parameters:

lambdas (array_like, optional) – Array of wavelengths in nm (default: parameters.LAMBDAS).

Examples

>>> a = AtmosphereGrid(atmgrid_filename='tests/data/reduc_20170530_134_atmsim.fits')
>>> a.plot_transmission()

(Source code)

plot_transmission_image()[source]

Plot the atmospheric transmission contained in the grid using imshow.

Examples

>>> a = AtmosphereGrid(atmgrid_filename='tests/data/reduc_20170530_134_atmsim.fits')
>>> a.plot_transmission_image()

(Source code)

save_file(filename='')[source]

Save the atmospheric grid in a fits file.

Parameters:

filename (str) – The output file name.

Examples

>>> a = AtmosphereGrid(image_filename='tests/data/reduc_20170605_028.fits',
... pwv_grid=[5, 5, 1], ozone_grid=[400, 400, 1], aerosol_grid=[0.0, 0.1, 2])
>>> atmospheric_grid = a.compute()
>>> a.save_file(a.image_filename.replace('.fits', '_atmsim.fits'))
set_grid(pwv_grid=[0, 10, 10], ozone_grid=[100, 700, 7], aerosol_grid=[0, 0.1, 10], lambdas=array([300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099]))[source]

Set the size of the simulation grid self.atmgrid before compute it.

The first column of self.atmgrid will contain the wavelengths set by lambdas argument, the other columns the future simulations.

Parameters:
  • pwv_grid (list) – List of 3 numbers for the PWV quantity: min, max, number of simulations (default: [0, 10, 10]).

  • ozone_grid (list) – List of 3 numbers for the ozone quantity: min, max, number of simulations (default: [100, 700, 7]).

  • aerosol_grid (list) – List of 3 numbers for the aerosol quantity: min, max, number of simulations (default: [0, 0.1, 10]).

  • lambdas (array_like, optional) – Array of wavelengths (default: parameters.LAMBDAS).

simulate(ozone, pwv, aerosols, angstrom_exponent=None)[source]

Interpolate from the atmospheric grid to get the atmospheric transmission.

First ozone, second pwv, last aerosols, to respect order of loops when generating the grid

Parameters:
  • ozone (float) – Ozone quantity in Dobson.

  • pwv (float) – Precipitable Water Vapor quantity in mm.

  • aerosols (float) – VAOD Vertical Aerosols Optical Depth.

  • angstrom_exponent (float, optional) – Angstrom exponent for aerosols. If None, the Atmosphere.angstrom_exponent_default value is used (default: None).

Examples

>>> from spectractor.simulation.atmosphere import AtmosphereGrid, plot_transmission_simple
>>> from spectractor import parameters
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> a = AtmosphereGrid(atmgrid_filename='tests/data/reduc_20170530_134_atmsim.fits')
>>> lambdas = np.arange(200, 1200)
>>> fig = plt.figure()
>>> for pwv in np.arange(5):
...     transmission = a.simulate(ozone=400, pwv=pwv, aerosols=0.05)
...     plot_transmission_simple(plt.gca(), lambdas, transmission(lambdas),
...     title=a.title, label=a.label)
>>> if parameters.DISPLAY: plt.show()

(Source code)

spectractor.simulation.image_simulation module

class spectractor.simulation.image_simulation.BackgroundModel(Nx, Ny, level, frame=None)[source]

Bases: object

Class to model the background of the simulated image.

Nx

Size of the background along X axis in pixels.

Type:

int

Ny

Size of the background along Y axis in pixels.

Type:

int

level

The mean level of the background in image units.

Type:

float

frame

(x, y, smooth) right and upper limits in pixels of a vignetting frame, and the smoothing gaussian width (default: None).

Type:

array_like

model()[source]

Compute the background model for the image simulation in image units.

A shadowing vignetting frame is roughly simulated if self.frame is set.

Returns:

bkgd – The array of the background model.

Return type:

array_like

plot_model()[source]

Plot the background model.

class spectractor.simulation.image_simulation.FlatModel(Nx, Ny, gains, randomness_level=0.0)[source]

Bases: object

Class to model the pixel flat of the simulated image. Flat is dimensionless and its average must be one.

Nx

Size of the background along X axis in pixels.

Type:

int

Ny

Size of the background along Y axis in pixels.

Type:

int

gains

The list of gains to apply. The average must be one.

Type:

array_like

randomness_level

Level of random quantum efficiency to apply to pixels (default: 0.).

Type:

float

model()[source]

Compute the flat model for the image simulation (no units).

Returns:

flat – The array of the flat model.

Return type:

array_like

plot_model()[source]

Plot the flat model.

class spectractor.simulation.image_simulation.ImageModel(filename, target_label=None)[source]

Bases: Image

add_poisson_and_read_out_noise()[source]
compute(star, background, spectrogram, starfield=None, flat=None)[source]
load_image(filename)[source]

Load the image and store some information from header in class attributes. Then load the target and disperser properties. Called when an Image instance is created.

Parameters:

file_name (str) – The fits file name.

save_image(output_filename, overwrite=False)[source]

Save the image in a fits file.

Parameters:
  • output_file_name (str) – The output file name.

  • overwrite (bool) – If True, overwrite the file if it exists previously (default: False).

Examples

>>> im = Image('tests/data/reduc_20170605_028.fits')
>>> im.save_image('tests/data/reduc_20170605_028_copy.fits', overwrite=True)
spectractor.simulation.image_simulation.ImageSim(image_filename, spectrum_filename, outputdir, pwv=5, ozone=300, aerosols=0.03, A1=1, A2=1, A3=1, angstrom_exponent=None, psf_poly_params=None, psf_type=None, diffraction_orders=None, with_rotation=True, with_starfield=True, with_adr=True, with_noise=True, with_flat=True)[source]

The basic use of the extractor consists first to define: - the path to the fits image from which to extract the image, - the path of the output directory to save the extracted spectrum (created automatically if does not exist yet), - the rough position of the object in the image, - the name of the target (to search for the extra-atmospheric spectrum if available). Then different parameters and systematics can be set: - pwv: the pressure water vapor (in mm) - ozone: the ozone quantity (in XX) - aerosols: the vertical aerosol optical depth - A1: a global grey absorption parameter for the spectrum - A2: the relative amplitude of second order compared with first order - with_rotation: rotate the spectrum according to the disperser characteristics (True by default) - with_stars: include stars in the image field (True by default) - with_adr: include ADR effect (True by default) - with_flat: include flat (True by default)

class spectractor.simulation.image_simulation.StarFieldModel(base_image, flux_factor=1)[source]

Bases: object

model(x, y)[source]
plot_model()[source]
set_star_list()[source]
class spectractor.simulation.image_simulation.StarModel(centroid_coords, psf, amplitude)[source]

Bases: object

Class to model a star in the image simulation process.

x0

X position of the star centroid in pixels.

Type:

float

y0

Y position of the star centroid in pixels.

Type:

float

amplitude

The amplitude of the star in image units.

Type:

amplitude

plot_model()[source]

Plot the star model.

spectractor.simulation.libradtran module

class spectractor.simulation.libradtran.Libradtran(libradtran_path='', atm_standard='afglus', absorption_model='reptran')[source]

Bases: object

run(path='')[source]

Run the Libradtran command uvspec.

Parameters:

path (str, optional) – Path to bin/uvspec if necessary, otherwise use $PATH (default: “”)

Returns:

  • lambdas (array_like) – Wavelength array.

  • atmosphere (array_like) – Atmospheric transmission array.

simulate(airmass, aerosol, ozone, pwv, pressure, angstrom_exponent=None, lambda_min=250, lambda_max=1200, altitude=2.2)[source]

Simulate the atmosphere transmission with Libratran.

Parameters:
  • airmass (float) – The airmass of the atmosphere.

  • aerosol (float) – VAOD of the aerosols.

  • ozone (float) – Ozone quantity in Dobson units.

  • pwv (float) – Precipitable Water Vapor amount in mm.

  • pressure (float) – Pressure of the atmosphere at observatory altitude in hPa.

  • angstrom_exponent (float, optional) – Angstrom exponent for aerosols. If None, the Atmosphere.angstrom_exponent_default value is used (default: None).

  • lambda_min (float) – Minimum wavelength for simulation in nm.

  • lambda_max (float) – Maximum wavelength for simulation in nm.

  • altitude (float) – Observatory altitude in km (default: parameters.OBS_ALTITUDE).

Returns:

output_file_name – The output file name relative to the current directory.

Return type:

str

Examples

>>> parameters.DEBUG = True
>>> lib = Libradtran()
>>> lambdas, atmosphere = lib.simulate(1.2, 0.07, 400, 2, 800, angstrom_exponent=None, lambda_max=1200)
>>> print(lambdas[-5:])
[1196. 1197. 1198. 1199. 1200.]
>>> print(atmosphere[-5:])
[0.9617202 0.9617202 0.9529933 0.9529933 0.9512588]
>>> lambdas2, atmosphere2 = lib.simulate(1.2, 0.07, 400, 2, 800, angstrom_exponent=-0.02, lambda_max=1200)
>>> print(lambdas2[-5:])
[1196. 1197. 1198. 1199. 1200.]
>>> assert np.isclose(atmosphere2[-5:], [0.9659722, 0.9659722, 0.9571998, 0.9571998, 0.9554523], 1e-2).all()
spectractor.simulation.libradtran.clean_simulation_directory()[source]

Remove the libradtran directory.

Examples

>>> ensure_dir('libradtran')
>>> clean_simulation_directory()
>>> assert not os.path.isfile('libradtran')

spectractor.simulation.simulator module

class spectractor.simulation.simulator.SpectrogramModel(spectrum, target=None, disperser=None, throughput=None, atmosphere=None, diffraction_orders=None, fast_sim=True, full_image=False, with_adr=True)[source]

Bases: Spectrum

set_true_spectrum(lambdas, aerosols, ozone, pwv, shift_t=0.0)[source]
simulate(A1=1.0, A2=0.0, A3=0.0, aerosols=0.05, angstrom_exponent=None, ozone=300, pwv=5, D=55.45, shift_x=0.0, shift_y=0.0, angle=0.0, psf_poly_params=None)[source]
Parameters:
  • A1 (float) – Global amplitude of the spectrum (default: 1).

  • A2 (float) – Relative amplitude of the order 2 spectrum contamination (default: 0).

  • A3 (float) – Relative amplitude of the order 3 spectrum contamination (default: 0).

  • aerosols (float) – VAOD Vertical Aerosols Optical Depth.

  • angstrom_exponent (float, optional) – Angstrom exponent for aerosols. If None, the Atmosphere.angstrom_exponent_default value is used (default: None).

  • ozone (float) – Ozone quantity in Dobson.

  • pwv (float) – Precipitable Water Vapor quantity in mm.

  • D (float) – Distance between the CCD and the disperser in mm (default: parameters.DISTANCE2CCD)

  • shift_x (float) – Shift in pixels along x axis of the order 0 position estimate (default: 0).

  • shift_y (float) – Shift in pixels along y axis of the order 0 position estimate (default: 0).

  • angle (float) – Angle of the dispersion axis in degree (default: 0).

  • psf_poly_params (array_like) – Polynomial parameters describing the PSF dependence in wavelength (default: None).

Returns:

  • lambdas (array_like) – The wavelength array in nm used for the interpolation.

  • spectrogram (array_like) – The spectrogram array in ADU/s units.

  • spectrogram_err (array_like) – The spectrogram uncertainty array in ADU/s units.

Example

>>> spec = Spectrum("./tests/data/reduc_20170530_134_spectrum.fits")
>>> spec.disperser.ratio_ratio_order_3over2 = lambda lbda: 0.1
>>> psf_poly_params = list(spec.chromatic_psf.from_table_to_poly_params()) * 3
>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM='libradtran'
>>> atmosphere = Atmosphere(airmass=1.2, pressure=800, temperature=10)
>>> sim = SpectrogramModel(spec, atmosphere=atmosphere, fast_sim=True)
>>> lambdas, model, model_err = sim.simulate(A2=1, angle=-1.5, psf_poly_params=psf_poly_params)
>>> sim.plot_spectrogram()
simulate_spectrum(lambdas, atmosphere, shift_t=0.0)[source]

Simulate the spectrum of the object and return the result in Target units.

Parameters:
  • lambdas (array_like) – The wavelength array in nm.

  • atmosphere (callable) – A callable function of the atmospheric transmission.

  • shift_t (float) – Shift of the transmission in nm (default: 0).

Returns:

  • spectrum (array_like) – The spectrum array in ADU/s units.

  • spectrum_err (array_like) – The spectrum uncertainty array in ADU/s units.

class spectractor.simulation.simulator.SpectrumSimulation(spectrum, target=None, disperser=None, throughput=None, atmosphere=None, fast_sim=True, with_adr=True)[source]

Bases: Spectrum

simulate(A1=1.0, A2=0.0, aerosols=0.05, angstrom_exponent=None, ozone=300, pwv=5, reso=0.0, D=55.45, shift_x=0.0)[source]

Simulate the cross spectrum of an object and its uncertainties after its transmission throught the instrument and the atmosphere.

Parameters:
  • A1 (float) – Global amplitude of the spectrum (default: 1).

  • A2 (float) – Relative amplitude of the order 2 spectrum contamination (default: 0).

  • aerosols (float) – VAOD Vertical Aerosols Optical Depth

  • angstrom_exponent (float, optional) – Angstrom exponent for aerosols. If None, the Atmosphere.angstrom_exponent_default value is used (default: None).

  • ozone (float) – Ozone quantity in Dobson

  • pwv (float) – Precipitable Water Vapor quantity in mm

  • reso (float) – Gaussian kernel size for the convolution (default: 0).

  • D (float) – Distance between the CCD and the disperser in mm (default: parameters.DISTANCE2CCD)

  • shift_x (float) – Shift in pixels of the order 0 position estimate (default: 0).

Returns:

  • lambdas (array_like) – The wavelength array in nm used for the interpolation.

  • spectrum (array_like) – The spectrum interpolated function in Target units.

  • spectrum_err (array_like) – The spectrum uncertainties interpolated function in Target units.

Examples

>>> spectrum = Spectrum("./tests/data/reduc_20170530_134_spectrum.fits")
>>> parameters.SPECTRACTOR_ATMOSPHERE_SIM='libradtran'
>>> atmosphere = AtmosphereGrid(atmgrid_filename="./tests/data/reduc_20170530_134_atmsim.fits")
>>> sim = SpectrumSimulation(spectrum, atmosphere=atmosphere, fast_sim=True)
>>> lambdas, model, model_err = sim.simulate(A1=1, A2=1, ozone=300, pwv=5, aerosols=0.05, reso=0.,
... D=parameters.DISTANCE2CCD, shift_x=0.)
>>> sim.plot_spectrum()
simulate_without_atmosphere(lambdas)[source]

Compute the spectrum of an object and its uncertainties after its transmission throught the instrument except the atmosphere. The units remain the ones of the Target instance.

Parameters:

lambdas (array_like) – The wavelength array in nm

Returns:

  • spectrum (array_like) – The spectrum in Target units.

  • spectrum_err (array_like) – The spectrum uncertainties in Target units.

spectractor.simulation.throughput module

class spectractor.simulation.throughput.TelescopeTransmission(filter_label='')[source]

Bases: object

load_transmission()[source]

Load the transmission files and make a function.

Returns:

transmission – The transmission function using wavelengths in nm.

Return type:

callable

Examples

>>> t = TelescopeTransmission()
>>> t.plot_transmission()
>>> t2 = TelescopeTransmission(filter_label="RG715")
>>> t2.plot_transmission()
plot_transmission()[source]

Plot the transmission function and the associated uncertainties.

Examples

>>> t = TelescopeTransmission()
>>> t.plot_transmission()
reset_lambda_range(transmission_threshold=0.0001)[source]
spectractor.simulation.throughput.load_transmission_file(file_name)[source]

Load the transmission files and crop in wavelength using LAMBDA_MIN and LAMBDA_MAX.

The input file must have two or three columns:
  1. wavelengths in nm

  2. transmissions between 0 and 1.

  3. uncertainties on the transmissions (optional)

Returns:

  • lambdas (array_like) – The wavelengths array in nm.

  • transmissions (array_like) – The transmission array, values are between 0 and 1.

  • uncertainties (array_like) – The uncertainty on the transmission array (0 if file does not contain the info).

Examples

>>> parameters.LAMBDA_MIN = 500
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, "qecurve.txt"))
>>> print(lambdas[:3])
[500.81855389 508.18553888 519.23601637]
>>> print(transmissions[:3])
[0.74355972 0.75526932 0.76932084]
>>> print(errors[:3])
[0. 0. 0.]
spectractor.simulation.throughput.plot_transmission_simple(ax, lambdas, transmissions, uncertainties=None, label='', title='', lw=2)[source]

Plot the transmission with respect to the wavelength.

Parameters:
  • ax (Axes) – An Axes instance.

  • lambdas (array_like) – The wavelengths array in nm.

  • transmissions (array_like) – The transmission array, values are between 0 and 1.

  • uncertainties (array_like, optional) – The uncertainty on the transmission array (default: None).

  • label (str, optional) – The label of the curve for the legend (default: “”)

  • title (str, optional) – The title of the plot (default: “”)

  • lw (int) – Line width (default: 2).

Examples

>>> from spectractor.simulation.atmosphere import plot_transmission_simple
>>> from spectractor import parameters
>>> fig = plt.figure()
>>> ax = plt.gca()
>>> parameters.LAMBDA_MIN = 500
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, "qecurve.txt"))
>>> plot_transmission_simple(ax, lambdas, transmissions, errors, title="CTIO", label="Quantum efficiency")
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, "lsst_mirrorthroughput.txt"))
>>> plot_transmission_simple(ax, lambdas, transmissions, errors, title="CTIO", label="Mirror 1")
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, "FGB37.txt"))
>>> plot_transmission_simple(ax, lambdas, transmissions, errors, title="CTIO", label="FGB37")
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, "RG715.txt"))
>>> plot_transmission_simple(ax, lambdas, transmissions, errors, title="CTIO", label="RG715")
>>> lambdas, transmissions, errors = load_transmission_file(os.path.join(parameters.THROUGHPUT_DIR, parameters.OBS_FULL_INSTRUMENT_TRANSMISSON))
>>> plot_transmission_simple(ax, lambdas, transmissions, errors, title="CTIO", label="Full instrument")
>>> if parameters.DISPLAY: plt.show()

(Source code)

Module contents