RTModel 2.3__tar.gz → 3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {rtmodel-2.3 → rtmodel-3.0}/.github/workflows/build_wheels.yml +12 -4
  2. {rtmodel-2.3 → rtmodel-3.0}/CMakeLists.txt +16 -3
  3. {rtmodel-2.3 → rtmodel-3.0}/PKG-INFO +9 -8
  4. {rtmodel-2.3 → rtmodel-3.0}/README.md +5 -5
  5. {rtmodel-2.3 → rtmodel-3.0}/RTModel/RTModel.py +179 -46
  6. {rtmodel-2.3 → rtmodel-3.0}/RTModel/__init__.py +1 -1
  7. {rtmodel-2.3/RTModel/lib → rtmodel-3.0/RTModel/include}/LevMarFit.h +16 -30
  8. {rtmodel-2.3 → rtmodel-3.0}/RTModel/include/bumper.h +5 -1
  9. {rtmodel-2.3 → rtmodel-3.0}/RTModel/lib/Finalizer.cpp +52 -85
  10. {rtmodel-2.3 → rtmodel-3.0}/RTModel/lib/InitCond.cpp +172 -88
  11. {rtmodel-2.3 → rtmodel-3.0}/RTModel/lib/LevMar.cpp +4 -4
  12. rtmodel-3.0/RTModel/lib/LevMarFit.cpp +1762 -0
  13. {rtmodel-2.3 → rtmodel-3.0}/RTModel/lib/ModelSelector.cpp +234 -178
  14. rtmodel-3.0/RTModel/lib/Reader.cpp +700 -0
  15. {rtmodel-2.3 → rtmodel-3.0}/RTModel/lib/bumper.cpp +14 -1
  16. {rtmodel-2.3 → rtmodel-3.0}/RTModel/plotmodel/__init__.py +1 -1
  17. rtmodel-3.0/RTModel/plotmodel/plotmodel.py +857 -0
  18. {rtmodel-2.3 → rtmodel-3.0}/RTModel/templates/__init__.py +1 -1
  19. {rtmodel-2.3 → rtmodel-3.0}/changelog.md +4 -0
  20. {rtmodel-2.3 → rtmodel-3.0}/docs/Animation.md +7 -8
  21. {rtmodel-2.3 → rtmodel-3.0}/docs/Archive.md +3 -8
  22. rtmodel-3.0/docs/AstrometricPlots.md +57 -0
  23. rtmodel-3.0/docs/Astrophotometric.md +68 -0
  24. {rtmodel-2.3 → rtmodel-3.0}/docs/Constraints.md +5 -1
  25. {rtmodel-2.3 → rtmodel-3.0}/docs/DataPreparation.md +1 -1
  26. {rtmodel-2.3 → rtmodel-3.0}/docs/DataPreprocessing.md +4 -4
  27. {rtmodel-2.3 → rtmodel-3.0}/docs/FinalAssessment.md +1 -1
  28. {rtmodel-2.3 → rtmodel-3.0}/docs/Fitting.md +39 -8
  29. rtmodel-3.0/docs/HighResolutionImaging.md +84 -0
  30. {rtmodel-2.3 → rtmodel-3.0}/docs/InitCond.md +3 -2
  31. {rtmodel-2.3 → rtmodel-3.0}/docs/ModelCategories.md +22 -16
  32. {rtmodel-2.3 → rtmodel-3.0}/docs/ModelSelection.md +1 -1
  33. {rtmodel-2.3 → rtmodel-3.0}/docs/ModelingRun.md +4 -14
  34. {rtmodel-2.3 → rtmodel-3.0}/docs/PlotModel.md +38 -2
  35. rtmodel-3.0/docs/PreliminaryModels.md +26 -0
  36. {rtmodel-2.3 → rtmodel-3.0}/docs/README.md +20 -9
  37. {rtmodel-2.3 → rtmodel-3.0}/docs/Satellite.md +2 -2
  38. {rtmodel-2.3 → rtmodel-3.0}/docs/TemplateLibraries.md +2 -2
  39. rtmodel-3.0/docs/figs/fig.md +1 -0
  40. rtmodel-3.0/docs/figs/fig_HRimaging.png +0 -0
  41. rtmodel-3.0/docs/figs/fig_astro.png +0 -0
  42. rtmodel-3.0/docs/figs/fig_astro_Dec.png +0 -0
  43. rtmodel-3.0/docs/figs/fig_astro_RA.png +0 -0
  44. rtmodel-3.0/docs/figs/fig_astrophot.png +0 -0
  45. rtmodel-3.0/docs/figs/plotmodel_fig1.png +0 -0
  46. rtmodel-3.0/events/HRevent.zip +0 -0
  47. rtmodel-3.0/events/astroevent001.zip +0 -0
  48. rtmodel-3.0/events/event001done.zip +0 -0
  49. {rtmodel-2.3 → rtmodel-3.0}/events/readme.md +7 -1
  50. rtmodel-3.0/fVBM.py +16 -0
  51. {rtmodel-2.3 → rtmodel-3.0}/pyproject.toml +5 -4
  52. rtmodel-2.3/RTModel/include/LevMarFit.h +0 -91
  53. rtmodel-2.3/RTModel/include/VBMicrolensingLibrary.h +0 -483
  54. rtmodel-2.3/RTModel/lib/LevMarFit.cpp +0 -1596
  55. rtmodel-2.3/RTModel/lib/Reader.cpp +0 -670
  56. rtmodel-2.3/RTModel/lib/VBMicrolensingLibrary.cpp +0 -8007
  57. rtmodel-2.3/RTModel/plotmodel/plotmodel.py +0 -501
  58. rtmodel-2.3/docs/plotmodel_fig1.png +0 -0
  59. rtmodel-2.3/events/event001done.zip +0 -0
  60. {rtmodel-2.3 → rtmodel-3.0}/.github/workflows/run_tests.yml +0 -0
  61. {rtmodel-2.3 → rtmodel-3.0}/.gitignore +0 -0
  62. {rtmodel-2.3 → rtmodel-3.0}/LICENSE +0 -0
  63. {rtmodel-2.3 → rtmodel-3.0}/MANIFEST.in +0 -0
  64. {rtmodel-2.3 → rtmodel-3.0}/RTModel/data/ESPL.tbl +0 -0
  65. {rtmodel-2.3 → rtmodel-3.0}/RTModel/data/TemplateLibrary.txt +0 -0
  66. {rtmodel-2.3 → rtmodel-3.0}/RTModel/templates/templates.py +0 -0
  67. {rtmodel-2.3 → rtmodel-3.0}/docs/LimbDarkening.md +0 -0
  68. {rtmodel-2.3/docs → rtmodel-3.0/docs/figs}/Template.png +0 -0
  69. {rtmodel-2.3/docs → rtmodel-3.0/docs/figs}/ani.gif +0 -0
  70. {rtmodel-2.3/docs → rtmodel-3.0/docs/figs}/plotchain.png +0 -0
  71. {rtmodel-2.3/docs → rtmodel-3.0/docs/figs}/plotmodel_fig2.png +0 -0
  72. {rtmodel-2.3 → rtmodel-3.0}/events/OB190033.zip +0 -0
  73. {rtmodel-2.3 → rtmodel-3.0}/events/event001.zip +0 -0
  74. {rtmodel-2.3 → rtmodel-3.0}/events/event002.zip +0 -0
  75. {rtmodel-2.3 → rtmodel-3.0}/events/satellite1.txt +0 -0
  76. {rtmodel-2.3 → rtmodel-3.0}/jupyter/Model_event001.ipynb +0 -0
  77. {rtmodel-2.3 → rtmodel-3.0}/tests/build_tests/test_built_executables_exist.py +0 -0
  78. {rtmodel-2.3 → rtmodel-3.0}/tests/end_to_end_tests/test_ps_run.py +0 -0
  79. {rtmodel-2.3 → rtmodel-3.0}/tests/end_to_end_tests/test_ps_run_resources/example_event.zip +0 -0
@@ -1,6 +1,13 @@
1
1
  name: Build
2
2
 
3
- on: [push]
3
+ on:
4
+ push:
5
+ paths:
6
+ - '**.cpp'
7
+ - '**.h'
8
+ - '**.py'
9
+ - '**.toml'
10
+ - '**.yml'
4
11
 
5
12
  jobs:
6
13
  build_wheels:
@@ -8,15 +15,16 @@ jobs:
8
15
  runs-on: ${{ matrix.os }}
9
16
  strategy:
10
17
  matrix:
11
- # macos-13 is an intel runner, macos-14 is apple silicon
12
- os: [ubuntu-latest, windows-latest, macos-latest]
18
+ os: [ubuntu-latest, windows-latest, macos-13,macos-14] # was macos-latest
13
19
 
14
20
  steps:
15
21
  - uses: actions/checkout@v4
16
22
 
17
23
  - name: Build wheels
18
24
  uses: pypa/cibuildwheel@v2.22.0
19
- # env:
25
+ env: #
26
+ MACOSX_DEPLOYMENT_TARGET: "10.15" #
27
+ CIBW_SKIP: pp*
20
28
  # CIBW_SOME_OPTION: value
21
29
  # ...
22
30
  #with:
@@ -11,6 +11,20 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
11
11
  endif()
12
12
  endif()
13
13
 
14
+ # Find directory of VBMicrolensing
15
+
16
+ find_package(Python3 COMPONENTS Interpreter Development)
17
+ set(Python3_EXECUTABLE "./python")
18
+
19
+ execute_process(
20
+ COMMAND ${PYTHON_EXECUTABLE} fVBM.py
21
+ #-c "import sys, os, inspect; sys.path.extend(os.environ['PYTHONPATH'].split(os.pathsep)); mod = __import__('VBMicrolensing'); dir1=os.path.dirname(inspect.getfile(mod)); print(dir1.replace(\"\\\",\"/\"))"
22
+ OUTPUT_VARIABLE VBMICROLENSING_DIR
23
+ OUTPUT_STRIP_TRAILING_WHITESPACE
24
+ )
25
+ message(STATUS "Installation directory of VBMicrolensing: ${VBMICROLENSING_DIR}")
26
+
27
+
14
28
  # Build executables
15
29
  # =================
16
30
 
@@ -20,9 +34,8 @@ target_include_directories(Reader PRIVATE RTModel/include)
20
34
  add_executable(InitCond RTModel/lib/InitCond.cpp)
21
35
  target_include_directories(InitCond PRIVATE RTModel/include)
22
36
 
23
- add_executable(LevMar RTModel/lib/bumper.cpp RTModel/lib/LevMar.cpp RTModel/lib/LevMarFit.cpp
24
- RTModel/lib/VBMicrolensingLibrary.cpp)
25
- target_include_directories(LevMar PRIVATE RTModel/include)
37
+ add_executable(LevMar RTModel/lib/bumper.cpp RTModel/lib/LevMar.cpp RTModel/lib/LevMarFit.cpp ${VBMICROLENSING_DIR}/lib/VBMicrolensingLibrary.cpp)
38
+ target_include_directories(LevMar PRIVATE RTModel/include ${VBMICROLENSING_DIR}/lib)
26
39
 
27
40
  add_executable(ModelSelector RTModel/lib/bumper.cpp RTModel/lib/ModelSelector.cpp)
28
41
  target_include_directories(ModelSelector PRIVATE RTModel/include)
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: RTModel
3
- Version: 2.3
3
+ Version: 3.0
4
4
  Summary: RTModel is a tool for microlensing event interpretation.
5
5
  Keywords: Microlensing analysis and fitting
6
6
  Author-Email: Valerio Bozza <valboz@sa.infn.it>
7
7
  License: GPL-3.0
8
8
  Classifier: Development Status :: 5 - Production/Stable
9
9
  Classifier: Intended Audience :: Science/Research
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
10
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Project-URL: Homepage, https://github.com/valboz/RTModel
13
13
  Requires-Python: <4,>=3.7
@@ -15,11 +15,12 @@ Requires-Dist: numpy
15
15
  Requires-Dist: pytest
16
16
  Requires-Dist: matplotlib
17
17
  Requires-Dist: tqdm
18
- Requires-Dist: VBMicrolensing>=4.1.0
18
+ Requires-Dist: tabulate
19
+ Requires-Dist: VBMicrolensing>=5.0
19
20
  Description-Content-Type: text/markdown
20
21
 
21
22
  # RTModel
22
- `RTModel` is a package for modeling and interpretation of microlensing events. It uses photometric time series collected from ground and/or space telescopes to propose one or more possible models among the following:
23
+ `RTModel` is a package for modeling and interpretation of microlensing events. It uses photometric and/or astrometric time series collected from ground and/or space telescopes to propose one or more possible models among the following:
23
24
  - Single-lens-single-source microlensing (i.e. Paczynski)
24
25
  - Single-lens-binary-source microlensing (with or without xallarap)
25
26
  - Binary-lens-single-source microlensing (including planetary microlensing, parallax and orbital motion)
@@ -36,11 +37,11 @@ A second subpackage **`RTModel.templates`** helps the user in the visualization
36
37
 
37
38
  ## Attribution
38
39
 
39
- `RTModel` has been created by Valerio Bozza (University of Salerno) as a product of many years of direct experience on microlensing modeling (see [RTModel webpage](http://www.fisica.unisa.it/GravitationAstrophysics/RTModel.htm)).
40
+ `RTModel` has been created by Valerio Bozza (University of Salerno) as a product of many years of direct experience on microlensing modeling (see [RTModel webpage](https://projects.phys.unisa.it/GravitationAstrophysics/RTModel.htm)).
40
41
 
41
42
  Any scientific use of `RTModel` should be acknowledged by citing the paper [V.Bozza, A&A 688 (2024) 83](https://ui.adsabs.harvard.edu/abs/2024A%26A...688A..83B/abstract), describing all the algorithms behind the code.
42
43
 
43
- We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible. We also thank all the users who are providing suggestions, reporting bugs or failures: Etienne Bachelet, David Bennett, Jonathan Brashear, Stela Ishitani Silva, Yiannis Tsapras, Keto Zhang.
44
+ We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible. We also thank all the users who are providing suggestions, reporting bugs or failures: Etienne Bachelet, David Bennett, Jonathan Brashear, Laura Salmeri, Stela Ishitani Silva, Yiannis Tsapras, Sigfried Vanaverbeke, Keto Zhang.
44
45
 
45
46
  ## Installation
46
47
 
@@ -60,9 +61,9 @@ In alternative, you may directly install it from PyPI without cloning this repos
60
61
  pip install RTModel
61
62
  ```
62
63
 
63
- Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.6.
64
+ Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.7.
64
65
  A C++ compiler compatible with C++17 standard is needed for installation.
65
- `RTModel` also incorporates version 4.1 of [`VBMicrolensing`](https://github.com/valboz/VBMicrolensing). You are encouraged to cite the relevant papers listed in that repository as well.
66
+ `RTModel` uses [`VBMicrolensing`](https://github.com/valboz/VBMicrolensing) for all calculations. You are encouraged to cite the relevant papers listed in that repository as well.
66
67
 
67
68
  ## Documentation
68
69
  Full [documentation for the use of RTModel](docs/README.md) is available.
@@ -1,5 +1,5 @@
1
1
  # RTModel
2
- `RTModel` is a package for modeling and interpretation of microlensing events. It uses photometric time series collected from ground and/or space telescopes to propose one or more possible models among the following:
2
+ `RTModel` is a package for modeling and interpretation of microlensing events. It uses photometric and/or astrometric time series collected from ground and/or space telescopes to propose one or more possible models among the following:
3
3
  - Single-lens-single-source microlensing (i.e. Paczynski)
4
4
  - Single-lens-binary-source microlensing (with or without xallarap)
5
5
  - Binary-lens-single-source microlensing (including planetary microlensing, parallax and orbital motion)
@@ -16,11 +16,11 @@ A second subpackage **`RTModel.templates`** helps the user in the visualization
16
16
 
17
17
  ## Attribution
18
18
 
19
- `RTModel` has been created by Valerio Bozza (University of Salerno) as a product of many years of direct experience on microlensing modeling (see [RTModel webpage](http://www.fisica.unisa.it/GravitationAstrophysics/RTModel.htm)).
19
+ `RTModel` has been created by Valerio Bozza (University of Salerno) as a product of many years of direct experience on microlensing modeling (see [RTModel webpage](https://projects.phys.unisa.it/GravitationAstrophysics/RTModel.htm)).
20
20
 
21
21
  Any scientific use of `RTModel` should be acknowledged by citing the paper [V.Bozza, A&A 688 (2024) 83](https://ui.adsabs.harvard.edu/abs/2024A%26A...688A..83B/abstract), describing all the algorithms behind the code.
22
22
 
23
- We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible. We also thank all the users who are providing suggestions, reporting bugs or failures: Etienne Bachelet, David Bennett, Jonathan Brashear, Stela Ishitani Silva, Yiannis Tsapras, Keto Zhang.
23
+ We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible. We also thank all the users who are providing suggestions, reporting bugs or failures: Etienne Bachelet, David Bennett, Jonathan Brashear, Laura Salmeri, Stela Ishitani Silva, Yiannis Tsapras, Sigfried Vanaverbeke, Keto Zhang.
24
24
 
25
25
  ## Installation
26
26
 
@@ -40,9 +40,9 @@ In alternative, you may directly install it from PyPI without cloning this repos
40
40
  pip install RTModel
41
41
  ```
42
42
 
43
- Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.6.
43
+ Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.7.
44
44
  A C++ compiler compatible with C++17 standard is needed for installation.
45
- `RTModel` also incorporates version 4.1 of [`VBMicrolensing`](https://github.com/valboz/VBMicrolensing). You are encouraged to cite the relevant papers listed in that repository as well.
45
+ `RTModel` uses [`VBMicrolensing`](https://github.com/valboz/VBMicrolensing) for all calculations. You are encouraged to cite the relevant papers listed in that repository as well.
46
46
 
47
47
  ## Documentation
48
48
  Full [documentation for the use of RTModel](docs/README.md) is available.
@@ -32,7 +32,10 @@ class RTModel:
32
32
  self.eventname = os.getcwd()
33
33
  else:
34
34
  self.eventname = os.path.realpath(event)
35
- print("Event name: " + self.eventname)
35
+ if(os.path.exists(self.eventname)):
36
+ print("Event name: " + self.eventname)
37
+ else:
38
+ print("! Invalid path for event: " + self.eventname)
36
39
  self.inidir = "ini"
37
40
  self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO', 'LK', 'TS', 'TX']
38
41
  self.endphase = len(self.modelcodes)*2+3
@@ -44,15 +47,40 @@ class RTModel:
44
47
  self.config_LevMar()
45
48
  self.config_ModelSelector()
46
49
  self.satellitedir = '.'
47
-
50
+ self.astrometric = False
51
+ self.parameters_ranges = {'PS': [[-11.,1.0, 1.0],[-4.6, 7.6, 1.0],[-300,300,5.0],[-11.5,2.3,2.3]],
52
+ 'PX': [[-3.0,3.0, 0.5],[-4.6, 7.6, 1.0],[-300,300,5.0],[-11.5,2.3,2.3],[-3.0,3.0,0.1],[-3.0,3.0,0.1]],
53
+ 'BS': [[-4.6,7.6,1.0],[-11.5,0.0,0.5],[0,3.0,0.5],[0,3.0,0.5],[-300,300,1.0],[-300,300,1.0],[-11.5,2.3,2.3]],
54
+ 'BO': [[-4.6,7.6,1.0],[-11.5,0.0,0.5],[0,3.0,0.5],[0,3.0,0.5],[-300,300,1.0],[-300,300,1.0],[-11.5,2.3,2.3],
55
+ [-3.0,3.0,0.03],[-3.0,3.0,0.03],[-1.0,1.0,0.01],[-1.0,1.0,0.01],[1.e-7,1.0,0.01]],
56
+ 'LS': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
57
+ [-300,300,5.0]],
58
+ 'LX': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
59
+ [-300,300,5.0],[-3.0,3.0,0.03],[-3.0,3.0,0.03]],
60
+ 'LO': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
61
+ [-300,300,5.0],[-3.0,3.0,0.03],[-3.0,3.0,0.03],[-1.0,1.0,0.01],[-1.0,1.0,0.01],[1.e-7,1.0,0.01]],
62
+ 'LK': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
63
+ [-300,300,5.0],[-3.0,3.0,0.03],[-3.0,3.0,0.03],[-1.0,1.0,0.01],[-1.0,1.0,0.01],[1.e-7,1.0,0.01],
64
+ [-10,10,0.1],[0.5001,10,0.1]],
65
+ 'TS': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
66
+ [-300,300,5.0],[-4.0,3.0,0.3],[-11.5,11.5,0.5], [-12.56,12.56,0.3]],
67
+ 'TX': [[-4.0,3.0,.1],[-16.1,16.1,0.5],[-3.0,3.0,0.1], [-12.56,12.56,0.1],[-11.5,-2.5,0.3],[-4.6,7.6,0.6],
68
+ [-300,300,5.0],[-4.0,3.0,0.3],[-11.5,11.5,0.5], [-12.56,12.56,0.3],[-3.0,3.0,0.03],[-3.0,3.0,0.03]],
69
+ 'astrometry': [[-30.0,30.0,1.0],[-30.0,30.0,1.0],[0.05,1.0,0.1],[0.001,30.0,0.2]]
70
+ }
71
+
48
72
  def set_processors(self, nprocessors):
49
73
  self.nprocessors = nprocessors
50
74
 
51
75
  def set_event(self, event):
52
76
  self.eventname = os.path.realpath(event)
77
+ if(not os.path.exists(self.eventname)):
78
+ print("! Invalid path for event: " + self.eventname)
53
79
 
54
80
  def set_satellite_dir(self, satellitedir):
55
- self.satellitedir = satellitedir
81
+ self.satellitedir = os.path.realpath(satellitedir)
82
+ if(not os.path.exists(self.satellitedir)):
83
+ print("! Invalid path for satellite directory: " + self.satellitedir)
56
84
 
57
85
  def set_constraints(self, constraints = None):
58
86
  self.constraints = constraints
@@ -62,7 +90,21 @@ class RTModel:
62
90
  for cons in constraints:
63
91
  f.write(cons[0] + ' = '+ str(cons[1]) + ' '+ str(cons[2]) + ' '+ str(cons[3]) + ' ' + '\n')
64
92
 
65
- def config_Reader(self, tau = 0.1, binning = 4000, otherseasons = 1, renormalize = 1, thresholdoutliers = 10):
93
+ def set_parameter_ranges(self):
94
+ if(not os.path.exists(self.eventname + '/' + self.inidir)):
95
+ os.makedirs(self.eventname + '/' + self.inidir)
96
+ with open(self.eventname + '/' + self.inidir + '/Parameters_Ranges.ini','w') as f:
97
+ for modelcode in self.modelcodes:
98
+ f.write(modelcode + '\n')
99
+ for par in self.parameters_ranges[modelcode]:
100
+ f.write(str(par[0]) + ' ' + str(par[1]) + ' ' + str(par[2]) + '\n')
101
+ modelcode = 'astrometry'
102
+ f.write(modelcode + '\n')
103
+ for par in self.parameters_ranges[modelcode]:
104
+ f.write(str(par[0]) + ' ' + str(par[1]) + ' ' + str(par[2]) + '\n')
105
+
106
+
107
+ def config_Reader(self, tau = 0.1, binning = 4000, otherseasons = 100, renormalize = 1, thresholdoutliers = 10):
66
108
  self.Reader_tau= tau # conventional correlation time for consecutive points
67
109
  self.Reader_binning = binning # maximum number of points left after re-binning
68
110
  self.Reader_otherseasons = otherseasons # How to use other seasons (0 = Yes, 1 = decrease significance, 2 = remove)
@@ -80,13 +122,25 @@ class RTModel:
80
122
  f.write('thresholdoutliers = ' + str(self.Reader_thresholdoutliers) + '\n')
81
123
  print('- Launching: Reader')
82
124
  print(' Pre-processing data...')
83
- completedprocess = subprocess.run([self.bindir+self.readerexe,self.eventname], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
84
- if(completedprocess.returncode != 0):
85
- print('! Error in pre-processing. Please check your data!')
86
- self.done = True
87
- else:
125
+ try:
126
+ completedprocess=subprocess.run([self.bindir+self.readerexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
127
+ with open(self.eventname + '/LCToFit.txt') as f:
128
+ lines = f.readlines()
129
+ del(lines[0])
130
+ self.astrometric = False
131
+ for line in lines:
132
+ if(float(line.split()[6])>0):
133
+ self.astrometric = True
134
+ print(' Astrometric data found: static models will be skipped')
135
+ break
88
136
  print(' OK')
89
-
137
+ except subprocess.CalledProcessError as e:
138
+ print('\033[30;41m! Error in pre-processing. Please check your data!\033[m')
139
+ print('\033[30;43m'+e.stdout+'\033[m')
140
+ print('\033[30;43m'+e.stderr+'\033[m')
141
+ print('\033[30;41m! Program stopped here!\033[m')
142
+ self.done = True
143
+
90
144
  def config_InitCond(self, npeaks = 2, peakthreshold = 10.0, oldmodels = 4, override = None, nostatic = False, onlyorbital = False, usesatellite = 0
91
145
  , templatelibrary = None, modelcategories = ['PS','PX','BS','BO','LS','LX','LO'], onlyupdate =False):
92
146
  self.InitCond_npeaks = npeaks # Number of peaks in the observed light curve to be considered for setting initial conditions.
@@ -124,15 +178,12 @@ class RTModel:
124
178
  f.write('onlyupdate = 1\n')
125
179
  print('- Launching: InitCond')
126
180
  print(' Setting initial conditions...')
127
- completedprocess = subprocess.run([self.bindir+self.initcondexe,self.eventname], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
128
- if(completedprocess.returncode != 0):
129
- print('! Error in setting initial conditions!')
130
- self.done = True
131
- else:
181
+ try:
182
+ completedprocess=subprocess.run([self.bindir+self.initcondexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
132
183
  peaksearch = True
133
- i=0
184
+ imod=0
134
185
  while(peaksearch):
135
- initfils=glob.glob(self.eventname + '/InitCond/InitCond'+ self.modelcodes[i] + '*')
186
+ initfils=glob.glob(self.eventname + '/InitCond/InitCond'+ self.modelcodes[imod] + '*')
136
187
  if(len(initfils)!=0):
137
188
  peaksearch = False
138
189
  with open(initfils[0], 'r') as f:
@@ -140,14 +191,29 @@ class RTModel:
140
191
  print('Peaks: ',end ='')
141
192
  for i in range(0,npeaks):
142
193
  print(f'{float(f.readline().split()[0]):.4f}',end = ' ')
194
+ imod+=1
143
195
  print('\n OK')
196
+ except subprocess.CalledProcessError as e:
197
+ print('\033[30;41m! Error in setting initial conditions!\033[m')
198
+ print('\033[30;43m'+e.stdout+'\033[m')
199
+ print('\033[30;43m'+e.stderr+'\033[m')
200
+ print('\033[30;41m! Program stopped here!\033[m')
201
+ self.done = True
144
202
 
145
- def config_LevMar(self, nfits = 6, offsetdegeneracy = 3, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0):
203
+ def config_LevMar(self, nfits = 6, offsetdegeneracy = 3, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0, \
204
+ mass_luminosity_exponent = None, mass_radius_exponent = None, lens_mass_luminosity_exponent = None, \
205
+ turn_off_secondary_source = False, turn_off_secondary_lens = False):
146
206
  self.LevMar_nfits = nfits # Number of models to be calculated from the same initial condition using the bumper method
147
207
  self.LevMar_offsetdegeneracy = offsetdegeneracy # Number of models to be fit after applying offset degeneracy to best model found so far
148
208
  self.LevMar_maxsteps = maxsteps # Maximum number of steps in each fit
149
209
  self.LevMar_timelimit = timelimit # Maximum time in seconds for total execution
150
210
  self.LevMar_bumperpower = bumperpower # Repulsion factor of bumpers
211
+ self.LevMar_mass_luminosity_exponent = mass_luminosity_exponent # mass-luminosity exponent for binary sources
212
+ self.LevMar_mass_radius_exponent = mass_radius_exponent # mass-radius exponent for binary sources
213
+ self.LevMar_lens_mass_luminosity_exponent = lens_mass_luminosity_exponent # mass-luminosity exponent for binary lenses
214
+ self.LevMar_turn_off_secondary_lens = turn_off_secondary_lens # Option for dark secondary lenses
215
+ self.LevMar_turn_off_secondary_source = turn_off_secondary_source # Option for dark secondary sources
216
+ self.LevMar_stepchainsave = False # If True, step chains are saved
151
217
 
152
218
  def LevMar(self,strmodel, parameters_file = None, parameters = None):
153
219
  if(not os.path.exists(self.eventname + '/' + self.inidir)):
@@ -159,22 +225,38 @@ class RTModel:
159
225
  for fl in parameters:
160
226
  line = line + str(fl) + ' '
161
227
  f.write(line)
228
+ self.set_parameter_ranges()
162
229
  with open(self.eventname + '/' + self.inidir + '/LevMar.ini','w') as f:
163
230
  f.write('nfits = ' + str(self.LevMar_nfits) + '\n')
164
231
  f.write('offsetdegeneracy = ' + str(self.LevMar_offsetdegeneracy) + '\n')
165
232
  f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
166
233
  f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
167
234
  f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
235
+ if(self.LevMar_mass_luminosity_exponent != None):
236
+ f.write('mass_luminosity_exponent = ' + str(self.LevMar_mass_luminosity_exponent) + '\n')
237
+ if(self.LevMar_mass_radius_exponent != None):
238
+ f.write('mass_radius_exponent = ' + str(self.LevMar_mass_radius_exponent) + '\n')
239
+ if(self.LevMar_mass_luminosity_exponent != None):
240
+ f.write('lens_mass_luminosity_exponent = ' + str(self.LevMar_lens_mass_luminosity_exponent) + '\n')
241
+ if(self.LevMar_turn_off_secondary_lens):
242
+ f.write('turn_off_secondary_lens = True\n')
243
+ if(self.LevMar_turn_off_secondary_source):
244
+ f.write('turn_off_secondary_source = True\n')
168
245
  if(parameters_file != None):
169
246
  f.write('parametersfile = ' + parameters_file)
247
+ if(self.LevMar_stepchainsave):
248
+ f.write('stepchainsave = True\n')
170
249
  print('- Launching: LevMar')
171
250
  print(' Fitting ' + strmodel + ' ...')
172
- completedprocess = subprocess.run([self.bindir+self.levmarexe,self.eventname, strmodel,self.satellitedir], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
173
- if(completedprocess.returncode != 0):
174
- print('! Error in fit!')
175
- self.done = True
176
- else:
251
+ try:
252
+ completedprocess=subprocess.run([self.bindir+self.levmarexe,self.eventname, strmodel,self.satellitedir], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
177
253
  print(' OK')
254
+ except subprocess.CalledProcessError as e:
255
+ print('\033[30;41m! Error in fit!\033[m')
256
+ print('\033[30;43m'+e.stdout+'\033[m')
257
+ print('\033[30;43m'+e.stderr+'\033[m')
258
+ print('\033[30;41m! Program stopped here!\033[m')
259
+ self.done = True
178
260
 
179
261
  def launch_fits(self,modelcode):
180
262
  if(not os.path.exists(self.eventname + '/' + self.inidir)):
@@ -185,6 +267,18 @@ class RTModel:
185
267
  f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
186
268
  f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
187
269
  f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
270
+ if(self.LevMar_mass_luminosity_exponent != None):
271
+ f.write('mass_luminosity_exponent = ' + str(self.LevMar_mass_luminosity_exponent) + '\n')
272
+ if(self.LevMar_mass_radius_exponent != None):
273
+ f.write('mass_radius_exponent = ' + str(self.LevMar_mass_radius_exponent) + '\n')
274
+ if(self.LevMar_lens_mass_luminosity_exponent != None):
275
+ f.write('lens_mass_luminosity_exponent = ' + str(self.LevMar_lens_mass_luminosity_exponent) + '\n')
276
+ if(self.LevMar_turn_off_secondary_lens):
277
+ f.write('turn_off_secondary_lens = True\n')
278
+ if(self.LevMar_turn_off_secondary_source):
279
+ f.write('turn_off_secondary_source = True\n')
280
+ if(self.LevMar_stepchainsave):
281
+ f.write('stepchainsave = True\n')
188
282
  stringfits = {'PS' : '- Single-lens-Single-source fits',
189
283
  'PX' : '- Single-lens-Single-source fits with parallax',
190
284
  'BS' : '- Single-lens-Binary-source fits',
@@ -195,6 +289,7 @@ class RTModel:
195
289
  'LK' : '- Binary-lens-Single-source fits with eccentric orbital motion',
196
290
  'TS' : '- Triple-lens-Single-source fits',
197
291
  'TX' : '- Triple-lens-Single-source fits with parallax'}
292
+ self.set_parameter_ranges()
198
293
  print(stringfits[modelcode])
199
294
  initcondfile = self.eventname + '/InitCond/' + 'InitCond'+ modelcode + '.txt'
200
295
  if(os.path.exists(initcondfile)):
@@ -207,18 +302,33 @@ class RTModel:
207
302
  procepochs = []
208
303
  iinitcond = 0
209
304
  finitcond = 0
210
- finitcondold = -1
305
+ finitcondold = -1
306
+ timeouts = 0
307
+ crashes = 0
211
308
  pbar = tqdm(total = ninitconds,desc = 'Fits completed',file=sys.stdout, colour='GREEN', smoothing = 0)
212
309
  while(finitcond < ninitconds):
213
310
  i=0
214
311
  while i < len(processes):
215
312
  if(time.time() - procepochs[i] > self.LevMar_timelimit):
216
313
  processes[i].kill()
217
- premodfiles = glob.glob(self.eventname +'/PreModels/*.txt')
218
- strmodel = modelcode + '{:0>4}'.format(str(procnumbers[i]))
219
- with open(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat','w') as f:
220
- f.write(f'{len(premodfiles)} {self.LevMar_nfits}')
314
+ timeouts += 1
315
+ crashes -= 1
316
+ #premodfiles = glob.glob(self.eventname +'/PreModels/*.txt')
317
+ #strmodel = modelcode + '{:0>4}'.format(str(procnumbers[i]))
318
+ #with open(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat','w') as f:
319
+ # f.write(f'{len(premodfiles)} {self.LevMar_nfits}')
221
320
  if(processes[i].poll() != None):
321
+ if(processes[i].returncode!=0):
322
+ crashes +=1
323
+ # Here we have to append results to main model file
324
+ if(not self.LevMar_stepchainsave):
325
+ strmodel = modelcode + '{:0>4}'.format(str(procnumbers[i])) + ".txt"
326
+ if(os.path.exists(self.eventname +'/PreModels/' + strmodel)):
327
+ with open(self.eventname +'/PreModels/' + strmodel) as f:
328
+ content = f.read()
329
+ with open(self.eventname +'/PreModels/'+ modelcode + ".txt","a") as f:
330
+ f.write(content)
331
+ os.remove(self.eventname +'/PreModels/' + strmodel)
222
332
  processes.pop(i)
223
333
  procnumbers.pop(i)
224
334
  procepochs.pop(i)
@@ -227,12 +337,12 @@ class RTModel:
227
337
  i += 1
228
338
  while(iinitcond < ninitconds and len(processes) < self.nprocessors):
229
339
  strmodel = modelcode + '{:0>4}'.format(str(iinitcond))
230
- if(glob.glob(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat')==[]):
231
- processes.append(subprocess.Popen([self.bindir+self.levmarexe,self.eventname, strmodel,self.satellitedir], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL))
232
- procnumbers.append(iinitcond)
233
- procepochs.append(time.time())
234
- else:
235
- finitcond += 1
340
+ #if(glob.glob(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat')==[]):
341
+ processes.append(subprocess.Popen([self.bindir+self.levmarexe,self.eventname, strmodel,self.satellitedir], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL))
342
+ procnumbers.append(iinitcond)
343
+ procepochs.append(time.time())
344
+ #else:
345
+ # finitcond += 1
236
346
  iinitcond += 1
237
347
  if(finitcond != finitcondold):
238
348
  #print(' Fits launched: {}; completed: {}/{}'.format(iinitcond, finitcond, ninitconds))
@@ -240,6 +350,11 @@ class RTModel:
240
350
  finitcondold =finitcond
241
351
  time.sleep(0.1)
242
352
  pbar.close()
353
+ if(crashes>0):
354
+ print('crashed fits: ' + str(crashes))
355
+ if(timeouts>0):
356
+ print('timed out fits: ' + str(timeouts))
357
+ print(' OK')
243
358
  else:
244
359
  print('- No initial conditions for this category')
245
360
 
@@ -266,27 +381,35 @@ class RTModel:
266
381
  'TS' : '- Selecting models for Triple-lens-Single-source fits',
267
382
  'TX' : '- Selecting models for Triple-lens-Single-source fits with parallax'}
268
383
  print(stringmodels[modelcode])
269
- completedprocess = subprocess.run([self.bindir+self.modelselectorexe,self.eventname, modelcode], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
270
- if(completedprocess.returncode != 0):
271
- print('! Error in model selection!')
272
- self.done = True
273
- else:
384
+ try:
385
+ completedprocess=subprocess.run([self.bindir+self.modelselectorexe,self.eventname, modelcode], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
274
386
  print(' OK')
387
+ except subprocess.CalledProcessError as e:
388
+ print('\033[30;41m! Error in model selection!\033[m')
389
+ print('\033[30;43m'+e.stdout+'\033[m')
390
+ print('\033[30;43m'+e.stderr+'\033[m')
391
+ print('\033[30;41m! Program stopped here!\033[m')
392
+ self.done = True
275
393
 
276
394
  def Finalizer(self):
277
395
  print('- Launching: Finalizer')
278
396
  print(' Making final assessment for this event')
279
- completedprocess = subprocess.run([self.bindir+self.finalizerexe,self.eventname], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
280
- if(completedprocess.returncode != 0):
281
- print('! Error in finalization. Maybe there are problems with models')
282
- self.done = True
283
- else:
397
+ try:
398
+ completedprocess=subprocess.run([self.bindir+self.finalizerexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
284
399
  with open(self.eventname + '/Nature.txt') as f:
285
400
  for line in f.readlines():
286
401
  print(" " + line,end='')
287
402
  print(" OK")
403
+ except subprocess.CalledProcessError as e:
404
+ print('\033[30;41m! Error in finalization!\033[m')
405
+ print('\033[30;43m'+e.stdout+'\033[m')
406
+ print('\033[30;43m'+e.stderr+'\033[m')
407
+ print('\033[30;41m! Program stopped here!\033[m')
408
+ self.done = True
288
409
 
289
- def run(self, event = None, cleanup = False):
410
+ def run(self, event = None, cleanup = True):
411
+ if(not cleanup):
412
+ self.LevMar_stepchainsave = True
290
413
  phase =0
291
414
  if(event!= None):
292
415
  self.eventname = os.path.realpath(event)
@@ -320,7 +443,7 @@ class RTModel:
320
443
  elif phase > self.endphase:
321
444
  if(cleanup):
322
445
  print('- Cleaning up preliminary models')
323
- cleanup_preliminary_models()
446
+ self.cleanup_preliminary_models()
324
447
  print("- Analysis of " + self.eventname + " successfully completed!")
325
448
  print("o " + time.asctime())
326
449
  self.done = True
@@ -446,6 +569,16 @@ class RTModel:
446
569
  self.LevMar_timelimit = float(chunks[2])
447
570
  elif(chunks[0]=='bumperpower'):
448
571
  self.LevMar_bumperpower = float(chunks[2])
572
+ elif(chunks[0] == 'turn_off_secondary_source' and chunks[2] == 'True'):
573
+ self.LevMar_turn_off_secondary_source = True
574
+ elif(chunks[0] == 'turn_off_secondary_lens' and chunks[2] == 'True'):
575
+ self.LevMar_turn_off_secondary_lens = True
576
+ elif(chunks[0] == 'mass_luminosity_exponent'):
577
+ self.LevMar_mass_luminosity_exponent = float(chunks[2])
578
+ elif(chunks[0] == 'mass_radius_exponent'):
579
+ self.LevMar_mass_radius_exponent = float(chunks[2])
580
+ elif(chunks[0] == 'lens_mass_luminosity_exponent'):
581
+ self.LevMar_lens_mass_luminosity_exponent = float(chunks[2])
449
582
  if(os.path.exists(pathname + '/' + self.inidir + '/ModelSelector.ini')):
450
583
  with open(pathname + '/' + self.inidir + '/ModelSelector.ini','r') as f:
451
584
  lines = f.read().splitlines()
@@ -1,4 +1,4 @@
1
- __version__ = "2.2"
1
+ __version__ = "3.0"
2
2
  __author__ = 'Valerio Bozza'
3
3
  __credits__ = 'University of Salerno, Italy'
4
4
 
@@ -24,16 +24,20 @@ class LevMar {
24
24
  int error;
25
25
  int flagblending;
26
26
  path exedir;
27
+ bool astrometric;
28
+ int nlinpar;
27
29
 
28
30
  double tim0, tm;
29
31
 
30
- double (VBMicrolensing::* model)(double*, double);
31
32
  int nps;
32
33
  double* sigmapr, * leftlim, * rightlim;
33
34
 
34
- int* filter, * satel, nfil, np, OGLE;
35
- double* t, * y, * w, * delta, * maxdelta, * Curv, * A, * B, * B0, * Cov, * fb, ** Gr, * dFdp, * errs;
35
+ int* filter, * satel, nfil, np, OGLE, it0, it02;
36
+ double* t, * y, * w, *y1a, *y2a, * delta, * maxdelta, * Curv, * A, * B, * B0, * Cov, * fb, ** Gr, * dFdp, * errs;
37
+ double* cN, * cE, * wcN, * wcE, *c1s, *c2s, *c1l, *c2l;
36
38
  double* pr, * prn, * sumy, * sumy2, * sumsigma, * sumfy, * sumf, * sumf2, * limbdarks;
39
+ double* sumsigmaN, * sumsigmaE, * sumcN, * sumcE, * sumc1, * sumc2;
40
+ int* sizes, * starts;
37
41
 
38
42
  int consnumber, *consindex;
39
43
  double* constraints, * consleft, * consright, *consvars;
@@ -41,8 +45,10 @@ class LevMar {
41
45
 
42
46
  double Tol;
43
47
 
44
- void (LevMar::* PrintOut)(double*);
45
- void (LevMar::* PrintFile)(FILE*, double, bool);
48
+ // void (LevMar::* PrintOut)(double*);
49
+ // void (LevMar::* PrintFile)(FILE*, double, bool);
50
+ void PrintOut(double*);
51
+ void PrintFile(char *filename, int, double, bool);
46
52
 
47
53
  bumper* stepchain, * bumperlist, * laststep;
48
54
 
@@ -54,38 +60,18 @@ public:
54
60
  void ReadFiles(int, char**);
55
61
  int InitCond(double* presigmapr, double* preleftlim, double* prerightlim);
56
62
  void ReadCurve();
57
- void ReadOptions();
58
- void Run();
63
+ void ReadAncillary();
64
+ void ReadOptions(double *,double *, double *);
65
+ int Run();
59
66
  double ChiSquared(double*);
60
67
  void Grad();
68
+ void EvaluateModel(double *pr, int filter, int ips);
61
69
  void Covariance();
62
70
  double ComputeConstraint(double *pr, int i);
63
71
 
64
- void PrintOutPS(double*);
65
- void PrintOutPX(double*);
66
- void PrintOutBS(double*);
67
- void PrintOutBO(double*);
68
- void PrintOutLS(double*);
69
- void PrintOutLX(double*);
70
- void PrintOutLO(double*);
71
- void PrintOutLK(double*);
72
- void PrintOutTS(double*);
73
- void PrintOutTX(double*);
74
-
75
- void PrintFilePS(FILE*, double, bool);
76
- void PrintFilePX(FILE*, double, bool);
77
- void PrintFileBS(FILE*, double, bool);
78
- void PrintFileBO(FILE*, double, bool);
79
- void PrintFileLS(FILE*, double, bool);
80
- void PrintFileLX(FILE*, double, bool);
81
- void PrintFileLO(FILE*, double, bool);
82
- void PrintFileLK(FILE*, double, bool);
83
- void PrintFileTS(FILE*, double, bool);
84
- void PrintFileTX(FILE*, double, bool);
85
-
86
72
  };
87
73
 
88
74
  double Determinant(double*, int);
89
75
  void Inverse(double*, double*, int);
90
76
 
91
- #endif
77
+ #endif
@@ -4,6 +4,8 @@
4
4
  #ifndef _bumper
5
5
  #define _bumper
6
6
 
7
+ #include<stdio.h>
8
+
7
9
  // Bumper class is the penalty function to be used to fill minima in chi square
8
10
  class bumper{
9
11
  public:
@@ -13,6 +15,7 @@ public:
13
15
  double Amp;
14
16
  int nps;
15
17
  char modelcode[16];
18
+ char *buffer;
16
19
  int il;
17
20
  bool duplicate;
18
21
  bumper(double *,int);
@@ -23,6 +26,7 @@ public:
23
26
  void signCovariance(int);
24
27
  void flipCovariance(int, int);
25
28
  double distance(double *);
29
+ void SetBuffer(FILE*, int, int);
26
30
  bumper *next;
27
31
  };
28
32
 
@@ -30,4 +34,4 @@ double Determinant(double *,int);
30
34
  void Inverse(double*, double*, int);
31
35
  void CombineCovariances(bumper*, bumper*, double *Cov, double * Curv, int);
32
36
 
33
- #endif
37
+ #endif