Skip to content

Commit 6677307

Browse files
authored
Merge pull request #40 from valboz/dev
Update to v3.3
2 parents 0882ae1 + 4581024 commit 6677307

31 files changed

Lines changed: 1535 additions & 390 deletions

.github/workflows/build_wheels.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ jobs:
1515
runs-on: ${{ matrix.os }}
1616
strategy:
1717
matrix:
18-
os: [ubuntu-latest, windows-latest, macos-13,macos-14] # was macos-latest
18+
os: [ubuntu-latest, windows-latest, macos-14,macos-15] # was macos-latest
1919

2020
steps:
2121
- uses: actions/checkout@v4
2222

2323
- name: Build wheels
24-
uses: pypa/cibuildwheel@v2.22.0
24+
uses: pypa/cibuildwheel@v3.4.0
2525
env: #
2626
MACOSX_DEPLOYMENT_TARGET: "10.15" #
2727
CIBW_SKIP: pp*

.github/workflows/run_tests.yml

Lines changed: 0 additions & 41 deletions
This file was deleted.

README.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
- Single-lens-single-source microlensing (i.e. Paczynski)
44
- Single-lens-binary-source microlensing (with or without xallarap)
55
- Binary-lens-single-source microlensing (including planetary microlensing, parallax and orbital motion)
6+
- Triple-lens-single-source microlensing (including parallax and circular orbital motion)
67

78
All models include the finite-size of the source(s).
89

9-
The modeling strategy is based on a grid search in the parameter space for single-lens models, whereas a **template library** for binary-lens models is used including all possible geometries of the source trajectory with respect to the caustics. In addition to this global search, planets are searched where maximal deviations from a Paczynski model occurs.
10+
The modeling strategy is based on a grid search in the parameter space for single-lens models, whereas a **template library** for binary-lens models is used including all possible geometries of the source trajectory with respect to the caustics. In addition to this global search, planets are searched where maximal deviations from a Paczynski model occurs. Triple-lens models are searched as small perturbations to binary-lens models.
1011

1112
The library is in the form of a standard Python package that launches specific subprocesses for different tasks. Model fitting is executed in **parallel** exploiting available processors in the machine. The full modeling may take from one to three hours depending on the event and on the machine speed. The results of modeling are given in the form of a text **assessment file**; in addition, **final models** are made available with their parameters and covariance matrices.
1213

@@ -20,27 +21,23 @@ A second subpackage **`RTModel.templates`** helps the user in the visualization
2021

2122
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.
2223

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+
We are grateful to Greg Olmschenk, who revised the package installation in order to make it as cross-platform as possible. Antonio Consiglio collaborated to the development of the anomaly detection code. We also thank all the users who are providing suggestions, reporting bugs or failures: Etienne Bachelet, David Bennett, Jonathan Brashear, Sophie Budzik, Paolo Rota, Laura Salmeri, Stela Ishitani Silva, Yiannis Tsapras, Sigfried Vanaverbeke, Keto Zhang.
2425

2526
## Installation
2627

27-
The easiest way to install `RTModel` is through `pip`.
28-
29-
First clone this repository.
30-
31-
Then go to the repository directory and type
28+
The easiest way to install `RTModel` is through `pip install`.
3229

3330
```
34-
pip install .
31+
pip install RTModel
3532
```
3633

37-
In alternative, you may directly install it from PyPI without cloning this repository:
34+
In alternative, you may clone this repository. Then go to the repository directory and type
3835

3936
```
40-
pip install RTModel
37+
pip install .
4138
```
4239

43-
Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.7.
40+
Currently, `RTModel` works on Linux, Windows and MacOS, requiring Python >= 3.8.
4441
A C++ compiler compatible with C++17 standard is needed for installation.
4542
`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.
4643

RTModel/RTModel.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def __init__(self, event = None):
3737
else:
3838
print("! Invalid path for event: " + self.eventname)
3939
self.inidir = "ini"
40-
self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO', 'LK', 'TS', 'TX']
40+
self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO', 'LK', 'TS', 'TX', 'TO']
4141
self.endphase = len(self.modelcodes)*2+3
4242
self.eventinifile = 'event.ini'
4343
self.nprocessors = os.cpu_count()
@@ -66,6 +66,9 @@ def __init__(self, event = None):
6666
[-300,300,5.0],[-4.0,3.0,0.3],[-11.5,11.5,0.5], [-12.56,12.56,0.3]],
6767
'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],
6868
[-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+
'TO': [[-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],
70+
[-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],
71+
[-1.0,1.0,0.01],[-1.0,1.0,0.01],[1.e-7,1.0,0.01]],
6972
'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]]
7073
}
7174

@@ -104,10 +107,10 @@ def set_parameter_ranges(self):
104107
f.write(str(par[0]) + ' ' + str(par[1]) + ' ' + str(par[2]) + '\n')
105108

106109

107-
def config_Reader(self, tau = 0.1, binning = 4000, otherseasons = 100, renormalize = 1, thresholdoutliers = 10):
110+
def config_Reader(self, tau = 1, binning = 4000, otherseasons = 1, renormalize = 1, thresholdoutliers = 10):
108111
self.Reader_tau= tau # conventional correlation time for consecutive points
109112
self.Reader_binning = binning # maximum number of points left after re-binning
110-
self.Reader_otherseasons = otherseasons # How to use other seasons (0 = Yes, 1 = decrease significance, 2 = remove)
113+
self.Reader_otherseasons = otherseasons # How to use other seasons (0: Yes, >=1 decrease significance)
111114
self.Reader_renormalize = renormalize # Re-normalize error bars if non-zero
112115
self.Reader_thresholdoutliers = thresholdoutliers # Threshold in sigmas for removing outliers
113116

@@ -124,6 +127,20 @@ def Reader(self):
124127
print(' Pre-processing data...')
125128
try:
126129
completedprocess=subprocess.run([self.bindir+self.readerexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
130+
with open(self.eventname + '/FilterToData.txt') as f:
131+
lines = f.readlines()
132+
lines = [line.split('.dat')[0] for line in lines]
133+
sats = [[] for i in range(10)]
134+
ground = []
135+
for line in lines:
136+
if(line[-1].isdigit()):
137+
sats[int(line[-1])].append(line)
138+
else:
139+
ground.append(line)
140+
print(" Found ground telescopes: ",ground)
141+
for i in range(10):
142+
if(len(sats[i])>0):
143+
print(f" Found satellite {i}: ",sats[i])
127144
with open(self.eventname + '/LCToFit.txt') as f:
128145
lines = f.readlines()
129146
del(lines[0])
@@ -188,9 +205,10 @@ def InitCond(self):
188205
peaksearch = False
189206
with open(initfils[0], 'r') as f:
190207
npeaks = int(f.readline().split()[0])
191-
print('Peaks: ',end ='')
208+
print('Peaks: ')
192209
for i in range(0,npeaks):
193-
print(f'{float(f.readline().split()[0]):.4f}',end = ' ')
210+
chs=f.readline().split()
211+
print(f'{float(chs[0]):.4f} [{float(chs[4]):.4f}]')
194212
imod+=1
195213
print('\n OK')
196214
except subprocess.CalledProcessError as e:
@@ -200,9 +218,9 @@ def InitCond(self):
200218
print('\033[30;41m! Program stopped here!\033[m')
201219
self.done = True
202220

203-
def config_LevMar(self, nfits = 6, offsetdegeneracy = 3, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0, \
221+
def config_LevMar(self, nfits = 6, offsetdegeneracy = 2, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0, \
204222
mass_luminosity_exponent = None, mass_radius_exponent = None, lens_mass_luminosity_exponent = None, \
205-
turn_off_secondary_source = False, turn_off_secondary_lens = False):
223+
turn_off_secondary_source = False, turn_off_secondary_lens = False, block_tertiary_lens = False, stepchainsave=False):
206224
self.LevMar_nfits = nfits # Number of models to be calculated from the same initial condition using the bumper method
207225
self.LevMar_offsetdegeneracy = offsetdegeneracy # Number of models to be fit after applying offset degeneracy to best model found so far
208226
self.LevMar_maxsteps = maxsteps # Maximum number of steps in each fit
@@ -213,7 +231,8 @@ def config_LevMar(self, nfits = 6, offsetdegeneracy = 3, timelimit = 600.0, maxs
213231
self.LevMar_lens_mass_luminosity_exponent = lens_mass_luminosity_exponent # mass-luminosity exponent for binary lenses
214232
self.LevMar_turn_off_secondary_lens = turn_off_secondary_lens # Option for dark secondary lenses
215233
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
234+
self.LevMar_block_tertiary_lens = block_tertiary_lens # Option for blocked tertiary lens
235+
self.LevMar_stepchainsave = stepchainsave # If True, step chains are saved
217236

218237
def LevMar(self,strmodel, parameters_file = None, parameters = None):
219238
if(not os.path.exists(self.eventname + '/' + self.inidir)):
@@ -242,6 +261,8 @@ def LevMar(self,strmodel, parameters_file = None, parameters = None):
242261
f.write('turn_off_secondary_lens = True\n')
243262
if(self.LevMar_turn_off_secondary_source):
244263
f.write('turn_off_secondary_source = True\n')
264+
if(self.LevMar_block_tertiary_lens):
265+
f.write('block_tertiary_lens = True\n')
245266
if(parameters_file != None):
246267
f.write('parametersfile = ' + parameters_file)
247268
if(self.LevMar_stepchainsave):
@@ -277,6 +298,8 @@ def launch_fits(self,modelcode):
277298
f.write('turn_off_secondary_lens = True\n')
278299
if(self.LevMar_turn_off_secondary_source):
279300
f.write('turn_off_secondary_source = True\n')
301+
if(self.LevMar_block_tertiary_lens):
302+
f.write('block_tertiary_lens = True\n')
280303
if(self.LevMar_stepchainsave):
281304
f.write('stepchainsave = True\n')
282305
stringfits = {'PS' : '- Single-lens-Single-source fits',
@@ -288,7 +311,8 @@ def launch_fits(self,modelcode):
288311
'LO' : '- Binary-lens-Single-source fits with orbital motion',
289312
'LK' : '- Binary-lens-Single-source fits with eccentric orbital motion',
290313
'TS' : '- Triple-lens-Single-source fits',
291-
'TX' : '- Triple-lens-Single-source fits with parallax'}
314+
'TX' : '- Triple-lens-Single-source fits with parallax',
315+
'TO' : '- Triple-lens-Single-source fits with orbital motion'}
292316
self.set_parameter_ranges()
293317
print(stringfits[modelcode])
294318
initcondfile = self.eventname + '/InitCond/' + 'InitCond'+ modelcode + '.txt'
@@ -379,7 +403,8 @@ def ModelSelector(self, modelcode):
379403
'LO' : '- Selecting models for Binary-lens-Single-source fits with orbital motion',
380404
'LK' : '- Selecting models for Binary-lens-Single-source fits with eccentric orbital motion',
381405
'TS' : '- Selecting models for Triple-lens-Single-source fits',
382-
'TX' : '- Selecting models for Triple-lens-Single-source fits with parallax'}
406+
'TX' : '- Selecting models for Triple-lens-Single-source fits with parallax',
407+
'TO' : '- Selecting models for Triple-lens-Single-source fits with orbital motion'}
383408
print(stringmodels[modelcode])
384409
try:
385410
completedprocess=subprocess.run([self.bindir+self.modelselectorexe,self.eventname, modelcode], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
@@ -573,6 +598,8 @@ def recover_options(self,run = None):
573598
self.LevMar_turn_off_secondary_source = True
574599
elif(chunks[0] == 'turn_off_secondary_lens' and chunks[2] == 'True'):
575600
self.LevMar_turn_off_secondary_lens = True
601+
elif(chunks[0] == 'block_tertiary_lens' and chunks[2] == 'True'):
602+
self.LevMar_block_tertiary_lens = True
576603
elif(chunks[0] == 'mass_luminosity_exponent'):
577604
self.LevMar_mass_luminosity_exponent = float(chunks[2])
578605
elif(chunks[0] == 'mass_radius_exponent'):

RTModel/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
__version__ = "3.0"
21
__author__ = 'Valerio Bozza'
32
__credits__ = 'University of Salerno, Italy'
43

54
from .RTModel import RTModel
5+
6+
from importlib.metadata import version
7+
8+
__version__ = version("RTModel")

RTModel/include/LevMarFit.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,18 @@ class LevMar {
3838
double* pr, * prn, * sumy, * sumy2, * sumsigma, * sumfy, * sumf, * sumf2, * limbdarks;
3939
double* sumsigmaN, * sumsigmaE, * sumcN, * sumcE, * sumc1, * sumc2;
4040
int* sizes, * starts;
41+
double* inc;
42+
double* GradVec, *Graderr;
43+
double normgrad;
4144

4245
int consnumber, * consindex;
4346
double* constraints, * consleft, * consright, * consvars;
4447
int modnumber;
4548

49+
double tmaxmax;
50+
double maxmaxsum;
51+
double y1maxmax;
52+
double y2maxmax;
4653
double Tol;
4754

4855
// void (LevMar::* PrintOut)(double*);

RTModel/include/bumper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ class bumper{
1313
double *dp;
1414
double *curv, *cov;
1515
double Amp;
16+
double tanomaly;
17+
double y1anomaly, y2anomaly;
18+
double y1maxmax, y2maxmax;
19+
double resanomaly;
20+
double maxsum, maxmaxsum, tmaxmax, tmax;
1621
int nps;
1722
char modelcode[16];
1823
char *buffer;

0 commit comments

Comments
 (0)