RTModel 2.1.0__tar.gz → 2.3__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 (68) hide show
  1. rtmodel-2.3/.github/workflows/build_wheels.yml +48 -0
  2. {rtmodel-2.1.0 → rtmodel-2.3}/.github/workflows/run_tests.yml +1 -1
  3. {rtmodel-2.1.0 → rtmodel-2.3}/CMakeLists.txt +1 -1
  4. {rtmodel-2.1.0 → rtmodel-2.3}/PKG-INFO +7 -5
  5. {rtmodel-2.1.0 → rtmodel-2.3}/README.md +4 -2
  6. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/RTModel.py +84 -28
  7. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/__init__.py +1 -1
  8. rtmodel-2.3/RTModel/include/LevMarFit.h +91 -0
  9. rtmodel-2.3/RTModel/include/VBMicrolensingLibrary.h +483 -0
  10. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/include/bumper.h +2 -1
  11. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/lib/Finalizer.cpp +102 -49
  12. rtmodel-2.3/RTModel/lib/InitCond.cpp +1737 -0
  13. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/lib/LevMarFit.cpp +483 -186
  14. rtmodel-2.3/RTModel/lib/LevMarFit.h +91 -0
  15. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/lib/ModelSelector.cpp +350 -161
  16. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/lib/Reader.cpp +2 -2
  17. rtmodel-2.3/RTModel/lib/VBMicrolensingLibrary.cpp +8007 -0
  18. rtmodel-2.3/RTModel/lib/bumper.cpp +170 -0
  19. {rtmodel-2.1.0/RTModel/templates → rtmodel-2.3/RTModel/plotmodel}/__init__.py +5 -5
  20. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/plotmodel/plotmodel.py +52 -33
  21. {rtmodel-2.1.0/RTModel/plotmodel → rtmodel-2.3/RTModel/templates}/__init__.py +5 -5
  22. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/templates/templates.py +9 -15
  23. rtmodel-2.3/changelog.md +7 -0
  24. {rtmodel-2.1.0 → rtmodel-2.3}/docs/Animation.md +2 -0
  25. {rtmodel-2.1.0 → rtmodel-2.3}/docs/Archive.md +9 -0
  26. rtmodel-2.3/docs/Constraints.md +69 -0
  27. {rtmodel-2.1.0 → rtmodel-2.3}/docs/DataPreprocessing.md +10 -3
  28. {rtmodel-2.1.0 → rtmodel-2.3}/docs/FinalAssessment.md +2 -2
  29. {rtmodel-2.1.0 → rtmodel-2.3}/docs/Fitting.md +15 -6
  30. {rtmodel-2.1.0 → rtmodel-2.3}/docs/InitCond.md +15 -7
  31. {rtmodel-2.1.0 → rtmodel-2.3}/docs/LimbDarkening.md +1 -1
  32. {rtmodel-2.1.0 → rtmodel-2.3}/docs/ModelCategories.md +42 -7
  33. {rtmodel-2.1.0 → rtmodel-2.3}/docs/ModelSelection.md +12 -3
  34. {rtmodel-2.1.0 → rtmodel-2.3}/docs/ModelingRun.md +13 -0
  35. {rtmodel-2.1.0 → rtmodel-2.3}/docs/PlotModel.md +2 -1
  36. {rtmodel-2.1.0 → rtmodel-2.3}/docs/README.md +9 -7
  37. {rtmodel-2.1.0 → rtmodel-2.3}/docs/Satellite.md +11 -3
  38. rtmodel-2.3/docs/Template.png +0 -0
  39. {rtmodel-2.1.0 → rtmodel-2.3}/docs/TemplateLibraries.md +5 -3
  40. {rtmodel-2.1.0 → rtmodel-2.3}/pyproject.toml +10 -4
  41. rtmodel-2.1.0/RTModel/include/LevMarFit.h +0 -81
  42. rtmodel-2.1.0/RTModel/include/VBBinaryLensingLibrary.h +0 -312
  43. rtmodel-2.1.0/RTModel/lib/InitCond.cpp +0 -1427
  44. rtmodel-2.1.0/RTModel/lib/VBBinaryLensingLibrary.cpp +0 -4986
  45. rtmodel-2.1.0/RTModel/lib/bumper.cpp +0 -168
  46. rtmodel-2.1.0/changelog.md +0 -4
  47. rtmodel-2.1.0/docs/Template.png +0 -0
  48. {rtmodel-2.1.0 → rtmodel-2.3}/.gitignore +0 -0
  49. {rtmodel-2.1.0 → rtmodel-2.3}/LICENSE +0 -0
  50. {rtmodel-2.1.0 → rtmodel-2.3}/MANIFEST.in +0 -0
  51. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/data/ESPL.tbl +0 -0
  52. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/data/TemplateLibrary.txt +0 -0
  53. {rtmodel-2.1.0 → rtmodel-2.3}/RTModel/lib/LevMar.cpp +0 -0
  54. {rtmodel-2.1.0 → rtmodel-2.3}/docs/DataPreparation.md +0 -0
  55. {rtmodel-2.1.0 → rtmodel-2.3}/docs/ani.gif +0 -0
  56. {rtmodel-2.1.0 → rtmodel-2.3}/docs/plotchain.png +0 -0
  57. {rtmodel-2.1.0 → rtmodel-2.3}/docs/plotmodel_fig1.png +0 -0
  58. {rtmodel-2.1.0 → rtmodel-2.3}/docs/plotmodel_fig2.png +0 -0
  59. {rtmodel-2.1.0 → rtmodel-2.3}/events/OB190033.zip +0 -0
  60. {rtmodel-2.1.0 → rtmodel-2.3}/events/event001.zip +0 -0
  61. {rtmodel-2.1.0 → rtmodel-2.3}/events/event001done.zip +0 -0
  62. {rtmodel-2.1.0 → rtmodel-2.3}/events/event002.zip +0 -0
  63. {rtmodel-2.1.0 → rtmodel-2.3}/events/readme.md +0 -0
  64. {rtmodel-2.1.0 → rtmodel-2.3}/events/satellite1.txt +0 -0
  65. {rtmodel-2.1.0 → rtmodel-2.3}/jupyter/Model_event001.ipynb +0 -0
  66. {rtmodel-2.1.0 → rtmodel-2.3}/tests/build_tests/test_built_executables_exist.py +0 -0
  67. {rtmodel-2.1.0 → rtmodel-2.3}/tests/end_to_end_tests/test_ps_run.py +0 -0
  68. {rtmodel-2.1.0 → rtmodel-2.3}/tests/end_to_end_tests/test_ps_run_resources/example_event.zip +0 -0
@@ -0,0 +1,48 @@
1
+ name: Build
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build_wheels:
7
+ name: Build wheels on ${{ matrix.os }}
8
+ runs-on: ${{ matrix.os }}
9
+ strategy:
10
+ matrix:
11
+ # macos-13 is an intel runner, macos-14 is apple silicon
12
+ os: [ubuntu-latest, windows-latest, macos-latest]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Build wheels
18
+ uses: pypa/cibuildwheel@v2.22.0
19
+ # env:
20
+ # CIBW_SOME_OPTION: value
21
+ # ...
22
+ #with:
23
+ # package-dir: .
24
+ # output-dir: wheelhouse
25
+ # config-file: "{package}/pyproject.toml
26
+ - uses: actions/upload-artifact@v4
27
+ with:
28
+ name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
29
+ path: ./wheelhouse/*.whl
30
+ build_sdist:
31
+ name: Build source distribution
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Build sdist
37
+ run: pipx run build --sdist
38
+
39
+ - uses: actions/upload-artifact@v4
40
+ with:
41
+ name: cibw-sdist
42
+ path: dist/*.tar.gz
43
+
44
+
45
+ - uses: actions/upload-artifact@v4
46
+ with:
47
+ name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
48
+ path: ./wheelhouse/*.whl
@@ -1,6 +1,6 @@
1
1
  name: run_tests
2
2
 
3
- on: [push, pull_request]
3
+ on: [push]
4
4
 
5
5
  jobs:
6
6
  run_tests:
@@ -21,7 +21,7 @@ add_executable(InitCond RTModel/lib/InitCond.cpp)
21
21
  target_include_directories(InitCond PRIVATE RTModel/include)
22
22
 
23
23
  add_executable(LevMar RTModel/lib/bumper.cpp RTModel/lib/LevMar.cpp RTModel/lib/LevMarFit.cpp
24
- RTModel/lib/VBBinaryLensingLibrary.cpp)
24
+ RTModel/lib/VBMicrolensingLibrary.cpp)
25
25
  target_include_directories(LevMar PRIVATE RTModel/include)
26
26
 
27
27
  add_executable(ModelSelector RTModel/lib/bumper.cpp RTModel/lib/ModelSelector.cpp)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: RTModel
3
- Version: 2.1.0
3
+ Version: 2.3
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>
@@ -10,12 +10,12 @@ Classifier: Intended Audience :: Science/Research
10
10
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Project-URL: Homepage, https://github.com/valboz/RTModel
13
- Requires-Python: <4,>=3.6
13
+ Requires-Python: <4,>=3.7
14
14
  Requires-Dist: numpy
15
15
  Requires-Dist: pytest
16
16
  Requires-Dist: matplotlib
17
17
  Requires-Dist: tqdm
18
- Requires-Dist: VBBinaryLensing>=3.7.0
18
+ Requires-Dist: VBMicrolensing>=4.1.0
19
19
  Description-Content-Type: text/markdown
20
20
 
21
21
  # RTModel
@@ -32,13 +32,15 @@ The library is in the form of a standard Python package that launches specific s
32
32
 
33
33
  `RTModel` also includes a subpackage **`RTModel.plotmodel`** that allows an immediate visualization of models and the possibility to review each individual fitting process as an animated gif.
34
34
 
35
+ A second subpackage **`RTModel.templates`** helps the user in the visualization and customization of the template library.
36
+
35
37
  ## Attribution
36
38
 
37
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)).
38
40
 
39
41
  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.
40
42
 
41
- We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible.
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.
42
44
 
43
45
  ## Installation
44
46
 
@@ -60,7 +62,7 @@ pip install RTModel
60
62
 
61
63
  Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.6.
62
64
  A C++ compiler compatible with C++17 standard is needed for installation.
63
- `RTModel` also incorporates version 3.7 of [`VBBinaryLensing`](https://github.com/valboz/VBBinaryLensing).
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.
64
66
 
65
67
  ## Documentation
66
68
  Full [documentation for the use of RTModel](docs/README.md) is available.
@@ -12,13 +12,15 @@ The library is in the form of a standard Python package that launches specific s
12
12
 
13
13
  `RTModel` also includes a subpackage **`RTModel.plotmodel`** that allows an immediate visualization of models and the possibility to review each individual fitting process as an animated gif.
14
14
 
15
+ A second subpackage **`RTModel.templates`** helps the user in the visualization and customization of the template library.
16
+
15
17
  ## Attribution
16
18
 
17
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)).
18
20
 
19
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.
20
22
 
21
- We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible.
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.
22
24
 
23
25
  ## Installation
24
26
 
@@ -40,7 +42,7 @@ pip install RTModel
40
42
 
41
43
  Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.6.
42
44
  A C++ compiler compatible with C++17 standard is needed for installation.
43
- `RTModel` also incorporates version 3.7 of [`VBBinaryLensing`](https://github.com/valboz/VBBinaryLensing).
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.
44
46
 
45
47
  ## Documentation
46
48
  Full [documentation for the use of RTModel](docs/README.md) is available.
@@ -34,7 +34,7 @@ class RTModel:
34
34
  self.eventname = os.path.realpath(event)
35
35
  print("Event name: " + self.eventname)
36
36
  self.inidir = "ini"
37
- self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO']
37
+ self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO', 'LK', 'TS', 'TX']
38
38
  self.endphase = len(self.modelcodes)*2+3
39
39
  self.eventinifile = 'event.ini'
40
40
  self.nprocessors = os.cpu_count()
@@ -54,6 +54,14 @@ class RTModel:
54
54
  def set_satellite_dir(self, satellitedir):
55
55
  self.satellitedir = satellitedir
56
56
 
57
+ def set_constraints(self, constraints = None):
58
+ self.constraints = constraints
59
+ if(not os.path.exists(self.eventname + '/' + self.inidir)):
60
+ os.makedirs(self.eventname + '/' + self.inidir)
61
+ with open(self.eventname + '/' + self.inidir + '/Constraints.ini','w') as f:
62
+ for cons in constraints:
63
+ f.write(cons[0] + ' = '+ str(cons[1]) + ' '+ str(cons[2]) + ' '+ str(cons[3]) + ' ' + '\n')
64
+
57
65
  def config_Reader(self, tau = 0.1, binning = 4000, otherseasons = 1, renormalize = 1, thresholdoutliers = 10):
58
66
  self.Reader_tau= tau # conventional correlation time for consecutive points
59
67
  self.Reader_binning = binning # maximum number of points left after re-binning
@@ -80,15 +88,17 @@ class RTModel:
80
88
  print(' OK')
81
89
 
82
90
  def config_InitCond(self, npeaks = 2, peakthreshold = 10.0, oldmodels = 4, override = None, nostatic = False, onlyorbital = False, usesatellite = 0
83
- , template_library = None):
91
+ , templatelibrary = None, modelcategories = ['PS','PX','BS','BO','LS','LX','LO'], onlyupdate =False):
84
92
  self.InitCond_npeaks = npeaks # Number of peaks in the observed light curve to be considered for setting initial conditions.
85
93
  self.InitCond_peakthreshold = peakthreshold # Number of sigmas necessary for a deviation to be identified as a maximum or a minimum.
86
94
  self.InitCond_oldmodels = oldmodels # Maximum number of old models to include in new run as initial conditions
87
95
  self.InitCond_override = override # Override peak identification and manually set peak times
88
96
  self.InitCond_nostatic = nostatic or onlyorbital # No static models will be calculated.
89
- self.InitCond_onlyorbital = onlyorbital; # Only orbital motion models will be calculated.
90
- self.InitCond_usesatellite = usesatellite; # Satellite to be used for initial conditions. Ground telescopes by default.
91
- self.InitCond_template_library = template_library; # Template library to be used in place of the default one.
97
+ self.InitCond_onlyorbital = onlyorbital # Only orbital motion models will be calculated.
98
+ self.InitCond_usesatellite = usesatellite # Satellite to be used for initial conditions. Ground telescopes by default.
99
+ self.InitCond_templatelibrary = templatelibrary # Template library to be used in place of the default one.
100
+ self.InitCond_modelcategories = modelcategories # Model categories to be fit
101
+ self.InitCond_onlyupdate = onlyupdate # No search but only update of previously found best models
92
102
 
93
103
  def InitCond(self):
94
104
  ''' Establishes initial conditions for fitting by executing the InitCond external module.
@@ -106,8 +116,12 @@ class RTModel:
106
116
  f.write('onlyorbital = 1\n')
107
117
  if(self.InitCond_override != None):
108
118
  f.write('override = ' + str(self.InitCond_override[0])+ ' ' + str(self.InitCond_override[1]) + '\n')
109
- if(self.InitCond_template_library != None):
110
- f.write('templatelibrary = ' + self.InitCond_template_library + '\n')
119
+ if(self.InitCond_templatelibrary != None):
120
+ f.write('templatelibrary = ' + self.InitCond_templatelibrary + '\n')
121
+ if(self.InitCond_modelcategories != None):
122
+ f.write('modelcategories = '+ ''.join(self.InitCond_modelcategories) + '\n')
123
+ if(self.InitCond_onlyupdate):
124
+ f.write('onlyupdate = 1\n')
111
125
  print('- Launching: InitCond')
112
126
  print(' Setting initial conditions...')
113
127
  completedprocess = subprocess.run([self.bindir+self.initcondexe,self.eventname], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
@@ -115,20 +129,22 @@ class RTModel:
115
129
  print('! Error in setting initial conditions!')
116
130
  self.done = True
117
131
  else:
118
- initfils=glob.glob(self.eventname + '/InitCond/*LS*')
119
- if(len(initfils)==0):
120
- initfils=glob.glob(self.eventname + '/InitCond/*LX*')
121
- if(len(initfils)==0):
122
- initfils=glob.glob(self.eventname + '/InitCond/*LO*')
123
- with open(initfils[0], 'r') as f:
124
- npeaks = int(f.readline().split()[0])
125
- print('Peaks: ',end ='')
126
- for i in range(0,npeaks):
127
- print(f'{float(f.readline().split()[0]):.4f}',end = ' ')
132
+ peaksearch = True
133
+ i=0
134
+ while(peaksearch):
135
+ initfils=glob.glob(self.eventname + '/InitCond/InitCond'+ self.modelcodes[i] + '*')
136
+ if(len(initfils)!=0):
137
+ peaksearch = False
138
+ with open(initfils[0], 'r') as f:
139
+ npeaks = int(f.readline().split()[0])
140
+ print('Peaks: ',end ='')
141
+ for i in range(0,npeaks):
142
+ print(f'{float(f.readline().split()[0]):.4f}',end = ' ')
128
143
  print('\n OK')
129
144
 
130
- def config_LevMar(self, nfits = 5, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0):
145
+ def config_LevMar(self, nfits = 6, offsetdegeneracy = 3, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0):
131
146
  self.LevMar_nfits = nfits # Number of models to be calculated from the same initial condition using the bumper method
147
+ self.LevMar_offsetdegeneracy = offsetdegeneracy # Number of models to be fit after applying offset degeneracy to best model found so far
132
148
  self.LevMar_maxsteps = maxsteps # Maximum number of steps in each fit
133
149
  self.LevMar_timelimit = timelimit # Maximum time in seconds for total execution
134
150
  self.LevMar_bumperpower = bumperpower # Repulsion factor of bumpers
@@ -145,6 +161,7 @@ class RTModel:
145
161
  f.write(line)
146
162
  with open(self.eventname + '/' + self.inidir + '/LevMar.ini','w') as f:
147
163
  f.write('nfits = ' + str(self.LevMar_nfits) + '\n')
164
+ f.write('offsetdegeneracy = ' + str(self.LevMar_offsetdegeneracy) + '\n')
148
165
  f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
149
166
  f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
150
167
  f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
@@ -164,6 +181,7 @@ class RTModel:
164
181
  os.makedirs(self.eventname + '/' + self.inidir)
165
182
  with open(self.eventname + '/' + self.inidir + '/LevMar.ini','w') as f:
166
183
  f.write('nfits = ' + str(self.LevMar_nfits) + '\n')
184
+ f.write('offsetdegeneracy = ' + str(self.LevMar_offsetdegeneracy) + '\n')
167
185
  f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
168
186
  f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
169
187
  f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
@@ -173,7 +191,10 @@ class RTModel:
173
191
  'BO' : '- Single-lens-Binary-source fits with xallarap',
174
192
  'LS' : '- Binary-lens-Single-source fits',
175
193
  'LX' : '- Binary-lens-Single-source fits with parallax',
176
- 'LO' : '- Binary-lens-Single-source fits with orbital motion'}
194
+ 'LO' : '- Binary-lens-Single-source fits with orbital motion',
195
+ 'LK' : '- Binary-lens-Single-source fits with eccentric orbital motion',
196
+ 'TS' : '- Triple-lens-Single-source fits',
197
+ 'TX' : '- Triple-lens-Single-source fits with parallax'}
177
198
  print(stringfits[modelcode])
178
199
  initcondfile = self.eventname + '/InitCond/' + 'InitCond'+ modelcode + '.txt'
179
200
  if(os.path.exists(initcondfile)):
@@ -220,7 +241,7 @@ class RTModel:
220
241
  time.sleep(0.1)
221
242
  pbar.close()
222
243
  else:
223
- print('- No initial conditions for this class')
244
+ print('- No initial conditions for this category')
224
245
 
225
246
  def config_ModelSelector(self, sigmasoverlap = 3.0, sigmachisquare = 1.0, maxmodels = 10):
226
247
  self.ModelSelector_sigmasoverlap = sigmasoverlap # factor multiplying the inverse covariance in search for superpositions (models are incompatible if farther than sigmasoverlap*sigma)
@@ -240,7 +261,10 @@ class RTModel:
240
261
  'BO' : '- Selecting models for Single-lens-Binary-source fits with xallarap',
241
262
  'LS' : '- Selecting models for Binary-lens-Single-source fits',
242
263
  'LX' : '- Selecting models for Binary-lens-Single-source fits with parallax',
243
- 'LO' : '- Selecting models for Binary-lens-Single-source fits with orbital motion'}
264
+ 'LO' : '- Selecting models for Binary-lens-Single-source fits with orbital motion',
265
+ 'LK' : '- Selecting models for Binary-lens-Single-source fits with eccentric orbital motion',
266
+ 'TS' : '- Selecting models for Triple-lens-Single-source fits',
267
+ 'TX' : '- Selecting models for Triple-lens-Single-source fits with parallax'}
244
268
  print(stringmodels[modelcode])
245
269
  completedprocess = subprocess.run([self.bindir+self.modelselectorexe,self.eventname, modelcode], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL)
246
270
  if(completedprocess.returncode != 0):
@@ -262,13 +286,13 @@ class RTModel:
262
286
  print(" " + line,end='')
263
287
  print(" OK")
264
288
 
265
- def run(self, event = None):
289
+ def run(self, event = None, cleanup = False):
266
290
  phase =0
267
291
  if(event!= None):
268
292
  self.eventname = os.path.realpath(event)
269
293
  self.done = False
294
+ print("o " + time.asctime())
270
295
  while not(self.done):
271
- print("o " + time.asctime())
272
296
  # Check that event directory exists
273
297
  if phase == 0:
274
298
  if(os.path.exists(self.eventname + '/Data')):
@@ -280,28 +304,44 @@ class RTModel:
280
304
  # Launch Reader
281
305
  elif phase == 1:
282
306
  self.Reader()
307
+ print("o " + time.asctime())
283
308
  phase = 2
284
309
  # Launch InitCond
285
310
  elif phase == 2:
286
311
  self.InitCond()
312
+ print("o " + time.asctime())
287
313
  phase = 3
288
314
  # Launch Finalizer
289
315
  elif phase == self.endphase:
290
316
  self.Finalizer()
317
+ print("o " + time.asctime())
291
318
  phase += 1
292
319
  # Conclude analysis
293
320
  elif phase > self.endphase:
321
+ if(cleanup):
322
+ print('- Cleaning up preliminary models')
323
+ cleanup_preliminary_models()
294
324
  print("- Analysis of " + self.eventname + " successfully completed!")
325
+ print("o " + time.asctime())
295
326
  self.done = True
296
327
  # Launch LevMar for next class
297
328
  elif phase%2 == 1:
298
- self.launch_fits(self.modelcodes[phase//2-1])
329
+ if(self.InitCond_modelcategories == None or self.modelcodes[phase//2-1] in self.InitCond_modelcategories):
330
+ self.launch_fits(self.modelcodes[phase//2-1])
331
+ print("o " + time.asctime())
299
332
  phase += 1
300
333
  # Launch ModelSelector for this class
301
334
  else:
302
- self.ModelSelector(self.modelcodes[phase//2-2])
303
- phase += 1
304
-
335
+ if(self.InitCond_modelcategories == None or self.modelcodes[phase//2-2] in self.InitCond_modelcategories):
336
+ self.ModelSelector(self.modelcodes[phase//2-2])
337
+ print("o " + time.asctime())
338
+ phase += 1
339
+
340
+ def cleanup_preliminary_models(self):
341
+ os.chdir(self.eventname)
342
+ if(os.path.exists('PreModels')):
343
+ shutil.rmtree('PreModels')
344
+
305
345
  def archive_run(self, destination = None):
306
346
  olddir = os.getcwd()
307
347
  os.chdir(self.eventname)
@@ -335,6 +375,15 @@ class RTModel:
335
375
  if(not(os.path.exists(pathname))):
336
376
  print("Invalid path!")
337
377
  return
378
+ if(os.path.exists(pathname + '/' + self.inidir + '/Constraints.ini')):
379
+ with open(pathname + '/' + self.inidir + '/Constraints.ini','r') as f:
380
+ lines = f.read().splitlines()
381
+ print('Constraints --- ',lines)
382
+ self.constraints =[]
383
+ for line in lines:
384
+ chunks =line.split()
385
+ self.constraints.append([chunks[0], float(chunks[2]), float(chunks[3]), float(chunks[4])])
386
+ self.set_constraints(self.constraints)
338
387
  if(os.path.exists(pathname + '/' + self.inidir + '/Reader.ini')):
339
388
  with open(pathname + '/' + self.inidir + '/Reader.ini','r') as f:
340
389
  lines = f.read().splitlines()
@@ -358,6 +407,7 @@ class RTModel:
358
407
  self.InitCond_nostatic = False
359
408
  self.InitCond_onlyorbital = False
360
409
  self.InitCond_override = None
410
+ self.InitCond_onlyupdate = False
361
411
  for line in lines:
362
412
  chunks = line.split()
363
413
  if(chunks[0]=='npeaks'):
@@ -372,10 +422,14 @@ class RTModel:
372
422
  self.InitCond_nostatic = (int(chunks[2])!=0)
373
423
  elif(chunks[0]=='onlyorbital'):
374
424
  self.InitCond_onlyorbital = (int(chunks[2])!=0)
425
+ elif(chunks[0]=='onlyupdate'):
426
+ self.InitCond_onlyupdate = (int(chunks[2])!=0)
375
427
  elif(chunks[0]=='override'):
376
428
  self.InitCond_override = (float(chunks[2]),float(chunks[3]))
377
429
  elif(chunks[0]=='templatelibrary'):
378
- self.InitCond_template_library = chunks[2]
430
+ self.InitCond_templatelibrary = chunks[2]
431
+ elif(chunks[0]=='modelcategories'):
432
+ self.InitCond_modelcategories = [chunks[2][i:i+2] for i in range(0, len(chunks[2]), 2)]
379
433
  if(os.path.exists(pathname + '/' + self.inidir + '/LevMar.ini')):
380
434
  with open(pathname + '/' + self.inidir + '/LevMar.ini','r') as f:
381
435
  lines = f.read().splitlines()
@@ -384,6 +438,8 @@ class RTModel:
384
438
  chunks = line.split()
385
439
  if(chunks[0]=='nfits'):
386
440
  self.LevMar_nfits = int(chunks[2])
441
+ if(chunks[0]=='offsetdegeneracy'):
442
+ self.LevMar_offsetdegeneracy = int(chunks[2])
387
443
  elif(chunks[0]=='maxsteps'):
388
444
  self.LevMar_maxsteps = int(chunks[2])
389
445
  elif(chunks[0]=='timelimit'):
@@ -1,4 +1,4 @@
1
- __version__ = "2.1.0"
1
+ __version__ = "2.2"
2
2
  __author__ = 'Valerio Bozza'
3
3
  __credits__ = 'University of Salerno, Italy'
4
4
 
@@ -0,0 +1,91 @@
1
+ // LevMarFit.h
2
+ // Definition of the LevMar and bumper classes for Levenberg-Marquardt fitting
3
+
4
+ #include <cstdio>
5
+ #include "bumper.h"
6
+ #include <regex>
7
+ #include <filesystem>
8
+
9
+ using namespace std;
10
+ using namespace std::filesystem;
11
+
12
+ #ifndef _LevMarFit
13
+ #define _LevMarFit
14
+ #define __unmanaged
15
+
16
+ #include <VBMicrolensingLibrary.h>
17
+
18
+ class LevMar {
19
+
20
+ VBMicrolensing* VBM;
21
+
22
+ char eventname[512], filename[30], filnum[10], outdir[30], satellitedir[256];
23
+ char modelcode[16];
24
+ int error;
25
+ int flagblending;
26
+ path exedir;
27
+
28
+ double tim0, tm;
29
+
30
+ double (VBMicrolensing::* model)(double*, double);
31
+ int nps;
32
+ double* sigmapr, * leftlim, * rightlim;
33
+
34
+ int* filter, * satel, nfil, np, OGLE;
35
+ double* t, * y, * w, * delta, * maxdelta, * Curv, * A, * B, * B0, * Cov, * fb, ** Gr, * dFdp, * errs;
36
+ double* pr, * prn, * sumy, * sumy2, * sumsigma, * sumfy, * sumf, * sumf2, * limbdarks;
37
+
38
+ int consnumber, *consindex;
39
+ double* constraints, * consleft, * consright, *consvars;
40
+ int modnumber;
41
+
42
+ double Tol;
43
+
44
+ void (LevMar::* PrintOut)(double*);
45
+ void (LevMar::* PrintFile)(FILE*, double, bool);
46
+
47
+ bumper* stepchain, * bumperlist, * laststep;
48
+
49
+
50
+ public:
51
+ LevMar(int, char**);
52
+ ~LevMar();
53
+
54
+ void ReadFiles(int, char**);
55
+ int InitCond(double* presigmapr, double* preleftlim, double* prerightlim);
56
+ void ReadCurve();
57
+ void ReadOptions();
58
+ void Run();
59
+ double ChiSquared(double*);
60
+ void Grad();
61
+ void Covariance();
62
+ double ComputeConstraint(double *pr, int i);
63
+
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
+ };
87
+
88
+ double Determinant(double*, int);
89
+ void Inverse(double*, double*, int);
90
+
91
+ #endif