RTModel 3.3__cp314-cp314-win_amd64.whl
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.
- RTModel/RTModel.py +640 -0
- RTModel/__init__.py +8 -0
- RTModel/bin/Finalizer.exe +0 -0
- RTModel/bin/InitCond.exe +0 -0
- RTModel/bin/LevMar.exe +0 -0
- RTModel/bin/ModelSelector.exe +0 -0
- RTModel/bin/Reader.exe +0 -0
- RTModel/data/ESPL.tbl +0 -0
- RTModel/data/SunEphemeris.txt +22130 -0
- RTModel/data/TemplateLibrary.txt +59 -0
- RTModel/include/LevMarFit.h +84 -0
- RTModel/include/bumper.h +42 -0
- RTModel/lib/Finalizer.cpp +442 -0
- RTModel/lib/InitCond.cpp +1991 -0
- RTModel/lib/LevMar.cpp +12 -0
- RTModel/lib/LevMarFit.cpp +2053 -0
- RTModel/lib/ModelSelector.cpp +1707 -0
- RTModel/lib/Reader.cpp +736 -0
- RTModel/lib/bumper.cpp +183 -0
- RTModel/plotmodel/__init__.py +5 -0
- RTModel/plotmodel/plotmodel.py +900 -0
- RTModel/templates/__init__.py +5 -0
- RTModel/templates/templates.py +82 -0
- rtmodel-3.3.dist-info/METADATA +76 -0
- rtmodel-3.3.dist-info/RECORD +27 -0
- rtmodel-3.3.dist-info/WHEEL +5 -0
- rtmodel-3.3.dist-info/licenses/LICENSE +166 -0
RTModel/RTModel.py
ADDED
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
import site
|
|
2
|
+
import subprocess
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import glob
|
|
6
|
+
import time
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
import shutil
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RTModel:
|
|
13
|
+
def __init__(self, event = None):
|
|
14
|
+
# Directory preliminaries
|
|
15
|
+
print('*********************')
|
|
16
|
+
print('**** RTModel ****')
|
|
17
|
+
print('*********************')
|
|
18
|
+
self.bindir = self.find_bin_directory()
|
|
19
|
+
if(os.path.exists(self.bindir + 'Reader.exe')):
|
|
20
|
+
self.readerexe = 'Reader.exe'
|
|
21
|
+
self.initcondexe = 'InitCond.exe'
|
|
22
|
+
self.levmarexe = 'LevMar.exe'
|
|
23
|
+
self.modelselectorexe = 'ModelSelector.exe'
|
|
24
|
+
self.finalizerexe = 'Finalizer.exe'
|
|
25
|
+
else:
|
|
26
|
+
self.readerexe = 'Reader'
|
|
27
|
+
self.initcondexe = 'InitCond'
|
|
28
|
+
self.levmarexe = 'LevMar'
|
|
29
|
+
self.modelselectorexe = 'ModelSelector'
|
|
30
|
+
self.finalizerexe = 'Finalizer'
|
|
31
|
+
if(event == None):
|
|
32
|
+
self.eventname = os.getcwd()
|
|
33
|
+
else:
|
|
34
|
+
self.eventname = os.path.realpath(event)
|
|
35
|
+
if(os.path.exists(self.eventname)):
|
|
36
|
+
print("Event name: " + self.eventname)
|
|
37
|
+
else:
|
|
38
|
+
print("! Invalid path for event: " + self.eventname)
|
|
39
|
+
self.inidir = "ini"
|
|
40
|
+
self.modelcodes = ['PS', 'PX', 'BS', 'BO', 'LS', 'LX', 'LO', 'LK', 'TS', 'TX', 'TO']
|
|
41
|
+
self.endphase = len(self.modelcodes)*2+3
|
|
42
|
+
self.eventinifile = 'event.ini'
|
|
43
|
+
self.nprocessors = os.cpu_count()
|
|
44
|
+
print('Number of processors: {}'.format(self.nprocessors))
|
|
45
|
+
self.config_Reader()
|
|
46
|
+
self.config_InitCond()
|
|
47
|
+
self.config_LevMar()
|
|
48
|
+
self.config_ModelSelector()
|
|
49
|
+
self.satellitedir = '.'
|
|
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
|
+
'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]],
|
|
72
|
+
'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]]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
def set_processors(self, nprocessors):
|
|
76
|
+
self.nprocessors = nprocessors
|
|
77
|
+
|
|
78
|
+
def set_event(self, event):
|
|
79
|
+
self.eventname = os.path.realpath(event)
|
|
80
|
+
if(not os.path.exists(self.eventname)):
|
|
81
|
+
print("! Invalid path for event: " + self.eventname)
|
|
82
|
+
|
|
83
|
+
def set_satellite_dir(self, satellitedir):
|
|
84
|
+
self.satellitedir = os.path.realpath(satellitedir)
|
|
85
|
+
if(not os.path.exists(self.satellitedir)):
|
|
86
|
+
print("! Invalid path for satellite directory: " + self.satellitedir)
|
|
87
|
+
|
|
88
|
+
def set_constraints(self, constraints = None):
|
|
89
|
+
self.constraints = constraints
|
|
90
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
91
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
92
|
+
with open(self.eventname + '/' + self.inidir + '/Constraints.ini','w') as f:
|
|
93
|
+
for cons in constraints:
|
|
94
|
+
f.write(cons[0] + ' = '+ str(cons[1]) + ' '+ str(cons[2]) + ' '+ str(cons[3]) + ' ' + '\n')
|
|
95
|
+
|
|
96
|
+
def set_parameter_ranges(self):
|
|
97
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
98
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
99
|
+
with open(self.eventname + '/' + self.inidir + '/Parameters_Ranges.ini','w') as f:
|
|
100
|
+
for modelcode in self.modelcodes:
|
|
101
|
+
f.write(modelcode + '\n')
|
|
102
|
+
for par in self.parameters_ranges[modelcode]:
|
|
103
|
+
f.write(str(par[0]) + ' ' + str(par[1]) + ' ' + str(par[2]) + '\n')
|
|
104
|
+
modelcode = 'astrometry'
|
|
105
|
+
f.write(modelcode + '\n')
|
|
106
|
+
for par in self.parameters_ranges[modelcode]:
|
|
107
|
+
f.write(str(par[0]) + ' ' + str(par[1]) + ' ' + str(par[2]) + '\n')
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def config_Reader(self, tau = 1, binning = 4000, otherseasons = 1, renormalize = 1, thresholdoutliers = 10):
|
|
111
|
+
self.Reader_tau= tau # conventional correlation time for consecutive points
|
|
112
|
+
self.Reader_binning = binning # maximum number of points left after re-binning
|
|
113
|
+
self.Reader_otherseasons = otherseasons # How to use other seasons (0: Yes, >=1 decrease significance)
|
|
114
|
+
self.Reader_renormalize = renormalize # Re-normalize error bars if non-zero
|
|
115
|
+
self.Reader_thresholdoutliers = thresholdoutliers # Threshold in sigmas for removing outliers
|
|
116
|
+
|
|
117
|
+
def Reader(self):
|
|
118
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
119
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
120
|
+
with open(self.eventname + '/' + self.inidir + '/Reader.ini','w') as f:
|
|
121
|
+
f.write('tau = ' + str(self.Reader_tau) + '\n')
|
|
122
|
+
f.write('binning = ' + str(self.Reader_binning) + '\n')
|
|
123
|
+
f.write('otherseasons = ' + str(self.Reader_otherseasons) + '\n')
|
|
124
|
+
f.write('renormalize = ' + str(self.Reader_renormalize) + '\n')
|
|
125
|
+
f.write('thresholdoutliers = ' + str(self.Reader_thresholdoutliers) + '\n')
|
|
126
|
+
print('- Launching: Reader')
|
|
127
|
+
print(' Pre-processing data...')
|
|
128
|
+
try:
|
|
129
|
+
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])
|
|
144
|
+
with open(self.eventname + '/LCToFit.txt') as f:
|
|
145
|
+
lines = f.readlines()
|
|
146
|
+
del(lines[0])
|
|
147
|
+
self.astrometric = False
|
|
148
|
+
for line in lines:
|
|
149
|
+
if(float(line.split()[6])>0):
|
|
150
|
+
self.astrometric = True
|
|
151
|
+
print(' Astrometric data found: static models will be skipped')
|
|
152
|
+
break
|
|
153
|
+
print(' OK')
|
|
154
|
+
except subprocess.CalledProcessError as e:
|
|
155
|
+
print('\033[30;41m! Error in pre-processing. Please check your data!\033[m')
|
|
156
|
+
print('\033[30;43m'+e.stdout+'\033[m')
|
|
157
|
+
print('\033[30;43m'+e.stderr+'\033[m')
|
|
158
|
+
print('\033[30;41m! Program stopped here!\033[m')
|
|
159
|
+
self.done = True
|
|
160
|
+
|
|
161
|
+
def config_InitCond(self, npeaks = 2, peakthreshold = 10.0, oldmodels = 4, override = None, nostatic = False, onlyorbital = False, usesatellite = 0
|
|
162
|
+
, templatelibrary = None, modelcategories = ['PS','PX','BS','BO','LS','LX','LO'], onlyupdate =False):
|
|
163
|
+
self.InitCond_npeaks = npeaks # Number of peaks in the observed light curve to be considered for setting initial conditions.
|
|
164
|
+
self.InitCond_peakthreshold = peakthreshold # Number of sigmas necessary for a deviation to be identified as a maximum or a minimum.
|
|
165
|
+
self.InitCond_oldmodels = oldmodels # Maximum number of old models to include in new run as initial conditions
|
|
166
|
+
self.InitCond_override = override # Override peak identification and manually set peak times
|
|
167
|
+
self.InitCond_nostatic = nostatic or onlyorbital # No static models will be calculated.
|
|
168
|
+
self.InitCond_onlyorbital = onlyorbital # Only orbital motion models will be calculated.
|
|
169
|
+
self.InitCond_usesatellite = usesatellite # Satellite to be used for initial conditions. Ground telescopes by default.
|
|
170
|
+
self.InitCond_templatelibrary = templatelibrary # Template library to be used in place of the default one.
|
|
171
|
+
self.InitCond_modelcategories = modelcategories # Model categories to be fit
|
|
172
|
+
self.InitCond_onlyupdate = onlyupdate # No search but only update of previously found best models
|
|
173
|
+
|
|
174
|
+
def InitCond(self):
|
|
175
|
+
''' Establishes initial conditions for fitting by executing the InitCond external module.
|
|
176
|
+
Options can be assigned through the config_InitCond() method. '''
|
|
177
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
178
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
179
|
+
with open(self.eventname + '/' + self.inidir + '/InitCond.ini','w') as f:
|
|
180
|
+
f.write('npeaks = ' + str(self.InitCond_npeaks) + '\n')
|
|
181
|
+
f.write('peakthreshold = ' + str(self.InitCond_peakthreshold) + '\n')
|
|
182
|
+
f.write('oldmodels = ' + str(self.InitCond_oldmodels) + '\n')
|
|
183
|
+
f.write('usesatellite = ' + str(self.InitCond_usesatellite) + '\n')
|
|
184
|
+
if(self.InitCond_nostatic):
|
|
185
|
+
f.write('nostatic = 1\n')
|
|
186
|
+
if(self.InitCond_onlyorbital):
|
|
187
|
+
f.write('onlyorbital = 1\n')
|
|
188
|
+
if(self.InitCond_override != None):
|
|
189
|
+
f.write('override = ' + str(self.InitCond_override[0])+ ' ' + str(self.InitCond_override[1]) + '\n')
|
|
190
|
+
if(self.InitCond_templatelibrary != None):
|
|
191
|
+
f.write('templatelibrary = ' + self.InitCond_templatelibrary + '\n')
|
|
192
|
+
if(self.InitCond_modelcategories != None):
|
|
193
|
+
f.write('modelcategories = '+ ''.join(self.InitCond_modelcategories) + '\n')
|
|
194
|
+
if(self.InitCond_onlyupdate):
|
|
195
|
+
f.write('onlyupdate = 1\n')
|
|
196
|
+
print('- Launching: InitCond')
|
|
197
|
+
print(' Setting initial conditions...')
|
|
198
|
+
try:
|
|
199
|
+
completedprocess=subprocess.run([self.bindir+self.initcondexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
|
|
200
|
+
peaksearch = True
|
|
201
|
+
imod=0
|
|
202
|
+
while(peaksearch):
|
|
203
|
+
initfils=glob.glob(self.eventname + '/InitCond/InitCond'+ self.modelcodes[imod] + '*')
|
|
204
|
+
if(len(initfils)!=0):
|
|
205
|
+
peaksearch = False
|
|
206
|
+
with open(initfils[0], 'r') as f:
|
|
207
|
+
npeaks = int(f.readline().split()[0])
|
|
208
|
+
print('Peaks: ')
|
|
209
|
+
for i in range(0,npeaks):
|
|
210
|
+
chs=f.readline().split()
|
|
211
|
+
print(f'{float(chs[0]):.4f} [{float(chs[4]):.4f}]')
|
|
212
|
+
imod+=1
|
|
213
|
+
print('\n OK')
|
|
214
|
+
except subprocess.CalledProcessError as e:
|
|
215
|
+
print('\033[30;41m! Error in setting initial conditions!\033[m')
|
|
216
|
+
print('\033[30;43m'+e.stdout+'\033[m')
|
|
217
|
+
print('\033[30;43m'+e.stderr+'\033[m')
|
|
218
|
+
print('\033[30;41m! Program stopped here!\033[m')
|
|
219
|
+
self.done = True
|
|
220
|
+
|
|
221
|
+
def config_LevMar(self, nfits = 6, offsetdegeneracy = 2, timelimit = 600.0, maxsteps = 50, bumperpower = 2.0, \
|
|
222
|
+
mass_luminosity_exponent = None, mass_radius_exponent = None, lens_mass_luminosity_exponent = None, \
|
|
223
|
+
turn_off_secondary_source = False, turn_off_secondary_lens = False, block_tertiary_lens = False, stepchainsave=False):
|
|
224
|
+
self.LevMar_nfits = nfits # Number of models to be calculated from the same initial condition using the bumper method
|
|
225
|
+
self.LevMar_offsetdegeneracy = offsetdegeneracy # Number of models to be fit after applying offset degeneracy to best model found so far
|
|
226
|
+
self.LevMar_maxsteps = maxsteps # Maximum number of steps in each fit
|
|
227
|
+
self.LevMar_timelimit = timelimit # Maximum time in seconds for total execution
|
|
228
|
+
self.LevMar_bumperpower = bumperpower # Repulsion factor of bumpers
|
|
229
|
+
self.LevMar_mass_luminosity_exponent = mass_luminosity_exponent # mass-luminosity exponent for binary sources
|
|
230
|
+
self.LevMar_mass_radius_exponent = mass_radius_exponent # mass-radius exponent for binary sources
|
|
231
|
+
self.LevMar_lens_mass_luminosity_exponent = lens_mass_luminosity_exponent # mass-luminosity exponent for binary lenses
|
|
232
|
+
self.LevMar_turn_off_secondary_lens = turn_off_secondary_lens # Option for dark secondary lenses
|
|
233
|
+
self.LevMar_turn_off_secondary_source = turn_off_secondary_source # Option for dark secondary sources
|
|
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
|
|
236
|
+
|
|
237
|
+
def LevMar(self,strmodel, parameters_file = None, parameters = None):
|
|
238
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
239
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
240
|
+
if(parameters != None):
|
|
241
|
+
parameters_file = self.eventname + '/' + self.inidir + '/parameters.ini'
|
|
242
|
+
with open(parameters_file,'w') as f:
|
|
243
|
+
line =''
|
|
244
|
+
for fl in parameters:
|
|
245
|
+
line = line + str(fl) + ' '
|
|
246
|
+
f.write(line)
|
|
247
|
+
self.set_parameter_ranges()
|
|
248
|
+
with open(self.eventname + '/' + self.inidir + '/LevMar.ini','w') as f:
|
|
249
|
+
f.write('nfits = ' + str(self.LevMar_nfits) + '\n')
|
|
250
|
+
f.write('offsetdegeneracy = ' + str(self.LevMar_offsetdegeneracy) + '\n')
|
|
251
|
+
f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
|
|
252
|
+
f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
|
|
253
|
+
f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
|
|
254
|
+
if(self.LevMar_mass_luminosity_exponent != None):
|
|
255
|
+
f.write('mass_luminosity_exponent = ' + str(self.LevMar_mass_luminosity_exponent) + '\n')
|
|
256
|
+
if(self.LevMar_mass_radius_exponent != None):
|
|
257
|
+
f.write('mass_radius_exponent = ' + str(self.LevMar_mass_radius_exponent) + '\n')
|
|
258
|
+
if(self.LevMar_mass_luminosity_exponent != None):
|
|
259
|
+
f.write('lens_mass_luminosity_exponent = ' + str(self.LevMar_lens_mass_luminosity_exponent) + '\n')
|
|
260
|
+
if(self.LevMar_turn_off_secondary_lens):
|
|
261
|
+
f.write('turn_off_secondary_lens = True\n')
|
|
262
|
+
if(self.LevMar_turn_off_secondary_source):
|
|
263
|
+
f.write('turn_off_secondary_source = True\n')
|
|
264
|
+
if(self.LevMar_block_tertiary_lens):
|
|
265
|
+
f.write('block_tertiary_lens = True\n')
|
|
266
|
+
if(parameters_file != None):
|
|
267
|
+
f.write('parametersfile = ' + parameters_file)
|
|
268
|
+
if(self.LevMar_stepchainsave):
|
|
269
|
+
f.write('stepchainsave = True\n')
|
|
270
|
+
print('- Launching: LevMar')
|
|
271
|
+
print(' Fitting ' + strmodel + ' ...')
|
|
272
|
+
try:
|
|
273
|
+
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)
|
|
274
|
+
print(' OK')
|
|
275
|
+
except subprocess.CalledProcessError as e:
|
|
276
|
+
print('\033[30;41m! Error in fit!\033[m')
|
|
277
|
+
print('\033[30;43m'+e.stdout+'\033[m')
|
|
278
|
+
print('\033[30;43m'+e.stderr+'\033[m')
|
|
279
|
+
print('\033[30;41m! Program stopped here!\033[m')
|
|
280
|
+
self.done = True
|
|
281
|
+
|
|
282
|
+
def launch_fits(self,modelcode):
|
|
283
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
284
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
285
|
+
with open(self.eventname + '/' + self.inidir + '/LevMar.ini','w') as f:
|
|
286
|
+
f.write('nfits = ' + str(self.LevMar_nfits) + '\n')
|
|
287
|
+
f.write('offsetdegeneracy = ' + str(self.LevMar_offsetdegeneracy) + '\n')
|
|
288
|
+
f.write('maxsteps = ' + str(self.LevMar_maxsteps) + '\n')
|
|
289
|
+
f.write('timelimit = ' + str(self.LevMar_timelimit) + '\n')
|
|
290
|
+
f.write('bumperpower = ' + str(self.LevMar_bumperpower) + '\n')
|
|
291
|
+
if(self.LevMar_mass_luminosity_exponent != None):
|
|
292
|
+
f.write('mass_luminosity_exponent = ' + str(self.LevMar_mass_luminosity_exponent) + '\n')
|
|
293
|
+
if(self.LevMar_mass_radius_exponent != None):
|
|
294
|
+
f.write('mass_radius_exponent = ' + str(self.LevMar_mass_radius_exponent) + '\n')
|
|
295
|
+
if(self.LevMar_lens_mass_luminosity_exponent != None):
|
|
296
|
+
f.write('lens_mass_luminosity_exponent = ' + str(self.LevMar_lens_mass_luminosity_exponent) + '\n')
|
|
297
|
+
if(self.LevMar_turn_off_secondary_lens):
|
|
298
|
+
f.write('turn_off_secondary_lens = True\n')
|
|
299
|
+
if(self.LevMar_turn_off_secondary_source):
|
|
300
|
+
f.write('turn_off_secondary_source = True\n')
|
|
301
|
+
if(self.LevMar_block_tertiary_lens):
|
|
302
|
+
f.write('block_tertiary_lens = True\n')
|
|
303
|
+
if(self.LevMar_stepchainsave):
|
|
304
|
+
f.write('stepchainsave = True\n')
|
|
305
|
+
stringfits = {'PS' : '- Single-lens-Single-source fits',
|
|
306
|
+
'PX' : '- Single-lens-Single-source fits with parallax',
|
|
307
|
+
'BS' : '- Single-lens-Binary-source fits',
|
|
308
|
+
'BO' : '- Single-lens-Binary-source fits with xallarap',
|
|
309
|
+
'LS' : '- Binary-lens-Single-source fits',
|
|
310
|
+
'LX' : '- Binary-lens-Single-source fits with parallax',
|
|
311
|
+
'LO' : '- Binary-lens-Single-source fits with orbital motion',
|
|
312
|
+
'LK' : '- Binary-lens-Single-source fits with eccentric orbital motion',
|
|
313
|
+
'TS' : '- Triple-lens-Single-source fits',
|
|
314
|
+
'TX' : '- Triple-lens-Single-source fits with parallax',
|
|
315
|
+
'TO' : '- Triple-lens-Single-source fits with orbital motion'}
|
|
316
|
+
self.set_parameter_ranges()
|
|
317
|
+
print(stringfits[modelcode])
|
|
318
|
+
initcondfile = self.eventname + '/InitCond/' + 'InitCond'+ modelcode + '.txt'
|
|
319
|
+
if(os.path.exists(initcondfile)):
|
|
320
|
+
with open(self.eventname + '/InitCond/' + 'InitCond'+ modelcode + '.txt') as f:
|
|
321
|
+
line = f.readline().split()
|
|
322
|
+
npeaks = int(line[0])
|
|
323
|
+
ninitconds = int(line[1])
|
|
324
|
+
processes = []
|
|
325
|
+
procnumbers = []
|
|
326
|
+
procepochs = []
|
|
327
|
+
iinitcond = 0
|
|
328
|
+
finitcond = 0
|
|
329
|
+
finitcondold = -1
|
|
330
|
+
timeouts = 0
|
|
331
|
+
crashes = 0
|
|
332
|
+
pbar = tqdm(total = ninitconds,desc = 'Fits completed',file=sys.stdout, colour='GREEN', smoothing = 0)
|
|
333
|
+
while(finitcond < ninitconds):
|
|
334
|
+
i=0
|
|
335
|
+
while i < len(processes):
|
|
336
|
+
if(time.time() - procepochs[i] > self.LevMar_timelimit):
|
|
337
|
+
processes[i].kill()
|
|
338
|
+
timeouts += 1
|
|
339
|
+
crashes -= 1
|
|
340
|
+
#premodfiles = glob.glob(self.eventname +'/PreModels/*.txt')
|
|
341
|
+
#strmodel = modelcode + '{:0>4}'.format(str(procnumbers[i]))
|
|
342
|
+
#with open(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat','w') as f:
|
|
343
|
+
# f.write(f'{len(premodfiles)} {self.LevMar_nfits}')
|
|
344
|
+
if(processes[i].poll() != None):
|
|
345
|
+
if(processes[i].returncode!=0):
|
|
346
|
+
crashes +=1
|
|
347
|
+
# Here we have to append results to main model file
|
|
348
|
+
if(not self.LevMar_stepchainsave):
|
|
349
|
+
strmodel = modelcode + '{:0>4}'.format(str(procnumbers[i])) + ".txt"
|
|
350
|
+
if(os.path.exists(self.eventname +'/PreModels/' + strmodel)):
|
|
351
|
+
with open(self.eventname +'/PreModels/' + strmodel) as f:
|
|
352
|
+
content = f.read()
|
|
353
|
+
with open(self.eventname +'/PreModels/'+ modelcode + ".txt","a") as f:
|
|
354
|
+
f.write(content)
|
|
355
|
+
os.remove(self.eventname +'/PreModels/' + strmodel)
|
|
356
|
+
processes.pop(i)
|
|
357
|
+
procnumbers.pop(i)
|
|
358
|
+
procepochs.pop(i)
|
|
359
|
+
finitcond += 1
|
|
360
|
+
else:
|
|
361
|
+
i += 1
|
|
362
|
+
while(iinitcond < ninitconds and len(processes) < self.nprocessors):
|
|
363
|
+
strmodel = modelcode + '{:0>4}'.format(str(iinitcond))
|
|
364
|
+
#if(glob.glob(self.eventname +'/PreModels/' + strmodel + '/t' + strmodel + '.dat')==[]):
|
|
365
|
+
processes.append(subprocess.Popen([self.bindir+self.levmarexe,self.eventname, strmodel,self.satellitedir], cwd = self.bindir, shell = False, stdout=subprocess.DEVNULL))
|
|
366
|
+
procnumbers.append(iinitcond)
|
|
367
|
+
procepochs.append(time.time())
|
|
368
|
+
#else:
|
|
369
|
+
# finitcond += 1
|
|
370
|
+
iinitcond += 1
|
|
371
|
+
if(finitcond != finitcondold):
|
|
372
|
+
#print(' Fits launched: {}; completed: {}/{}'.format(iinitcond, finitcond, ninitconds))
|
|
373
|
+
pbar.update(finitcond - max(finitcondold,0))
|
|
374
|
+
finitcondold =finitcond
|
|
375
|
+
time.sleep(0.1)
|
|
376
|
+
pbar.close()
|
|
377
|
+
if(crashes>0):
|
|
378
|
+
print('crashed fits: ' + str(crashes))
|
|
379
|
+
if(timeouts>0):
|
|
380
|
+
print('timed out fits: ' + str(timeouts))
|
|
381
|
+
print(' OK')
|
|
382
|
+
else:
|
|
383
|
+
print('- No initial conditions for this category')
|
|
384
|
+
|
|
385
|
+
def config_ModelSelector(self, sigmasoverlap = 3.0, sigmachisquare = 1.0, maxmodels = 10):
|
|
386
|
+
self.ModelSelector_sigmasoverlap = sigmasoverlap # factor multiplying the inverse covariance in search for superpositions (models are incompatible if farther than sigmasoverlap*sigma)
|
|
387
|
+
self.ModelSelector_sigmachisquare = sigmachisquare # number of sigmas in the chi square distribution for accepting alternative models after the best one
|
|
388
|
+
self.ModelSelector_maxmodels = maxmodels # maximum number of models returned
|
|
389
|
+
|
|
390
|
+
def ModelSelector(self, modelcode):
|
|
391
|
+
if(not os.path.exists(self.eventname + '/' + self.inidir)):
|
|
392
|
+
os.makedirs(self.eventname + '/' + self.inidir)
|
|
393
|
+
with open(self.eventname + '/' + self.inidir + '/ModelSelector.ini','w') as f:
|
|
394
|
+
f.write('sigmasoverlap = ' + str(self.ModelSelector_sigmasoverlap) + '\n')
|
|
395
|
+
f.write('sigmachisquare = ' + str(self.ModelSelector_sigmachisquare) + '\n')
|
|
396
|
+
f.write('maxmodels = ' + str(self.ModelSelector_maxmodels) + '\n')
|
|
397
|
+
stringmodels = {'PS' : '- Selecting models for Single-lens-Single-source fits',
|
|
398
|
+
'PX' : '- Selecting models for Single-lens-Single-source fits with parallax',
|
|
399
|
+
'BS' : '- Selecting models for Single-lens-Binary-source fits',
|
|
400
|
+
'BO' : '- Selecting models for Single-lens-Binary-source fits with xallarap',
|
|
401
|
+
'LS' : '- Selecting models for Binary-lens-Single-source fits',
|
|
402
|
+
'LX' : '- Selecting models for Binary-lens-Single-source fits with parallax',
|
|
403
|
+
'LO' : '- Selecting models for Binary-lens-Single-source fits with orbital motion',
|
|
404
|
+
'LK' : '- Selecting models for Binary-lens-Single-source fits with eccentric orbital motion',
|
|
405
|
+
'TS' : '- Selecting models for Triple-lens-Single-source fits',
|
|
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'}
|
|
408
|
+
print(stringmodels[modelcode])
|
|
409
|
+
try:
|
|
410
|
+
completedprocess=subprocess.run([self.bindir+self.modelselectorexe,self.eventname, modelcode], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
|
|
411
|
+
print(' OK')
|
|
412
|
+
except subprocess.CalledProcessError as e:
|
|
413
|
+
print('\033[30;41m! Error in model selection!\033[m')
|
|
414
|
+
print('\033[30;43m'+e.stdout+'\033[m')
|
|
415
|
+
print('\033[30;43m'+e.stderr+'\033[m')
|
|
416
|
+
print('\033[30;41m! Program stopped here!\033[m')
|
|
417
|
+
self.done = True
|
|
418
|
+
|
|
419
|
+
def Finalizer(self):
|
|
420
|
+
print('- Launching: Finalizer')
|
|
421
|
+
print(' Making final assessment for this event')
|
|
422
|
+
try:
|
|
423
|
+
completedprocess=subprocess.run([self.bindir+self.finalizerexe,self.eventname], cwd = self.bindir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, text = True)
|
|
424
|
+
with open(self.eventname + '/Nature.txt') as f:
|
|
425
|
+
for line in f.readlines():
|
|
426
|
+
print(" " + line,end='')
|
|
427
|
+
print(" OK")
|
|
428
|
+
except subprocess.CalledProcessError as e:
|
|
429
|
+
print('\033[30;41m! Error in finalization!\033[m')
|
|
430
|
+
print('\033[30;43m'+e.stdout+'\033[m')
|
|
431
|
+
print('\033[30;43m'+e.stderr+'\033[m')
|
|
432
|
+
print('\033[30;41m! Program stopped here!\033[m')
|
|
433
|
+
self.done = True
|
|
434
|
+
|
|
435
|
+
def run(self, event = None, cleanup = True):
|
|
436
|
+
if(not cleanup):
|
|
437
|
+
self.LevMar_stepchainsave = True
|
|
438
|
+
phase =0
|
|
439
|
+
if(event!= None):
|
|
440
|
+
self.eventname = os.path.realpath(event)
|
|
441
|
+
self.done = False
|
|
442
|
+
print("o " + time.asctime())
|
|
443
|
+
while not(self.done):
|
|
444
|
+
# Check that event directory exists
|
|
445
|
+
if phase == 0:
|
|
446
|
+
if(os.path.exists(self.eventname + '/Data')):
|
|
447
|
+
print('- Analyzing event: ',self.eventname)
|
|
448
|
+
phase = 1
|
|
449
|
+
else:
|
|
450
|
+
print('! Event data for ' + self.eventname + ' not found !')
|
|
451
|
+
self.done = True
|
|
452
|
+
# Launch Reader
|
|
453
|
+
elif phase == 1:
|
|
454
|
+
self.Reader()
|
|
455
|
+
print("o " + time.asctime())
|
|
456
|
+
phase = 2
|
|
457
|
+
# Launch InitCond
|
|
458
|
+
elif phase == 2:
|
|
459
|
+
self.InitCond()
|
|
460
|
+
print("o " + time.asctime())
|
|
461
|
+
phase = 3
|
|
462
|
+
# Launch Finalizer
|
|
463
|
+
elif phase == self.endphase:
|
|
464
|
+
self.Finalizer()
|
|
465
|
+
print("o " + time.asctime())
|
|
466
|
+
phase += 1
|
|
467
|
+
# Conclude analysis
|
|
468
|
+
elif phase > self.endphase:
|
|
469
|
+
if(cleanup):
|
|
470
|
+
print('- Cleaning up preliminary models')
|
|
471
|
+
self.cleanup_preliminary_models()
|
|
472
|
+
print("- Analysis of " + self.eventname + " successfully completed!")
|
|
473
|
+
print("o " + time.asctime())
|
|
474
|
+
self.done = True
|
|
475
|
+
# Launch LevMar for next class
|
|
476
|
+
elif phase%2 == 1:
|
|
477
|
+
if(self.InitCond_modelcategories == None or self.modelcodes[phase//2-1] in self.InitCond_modelcategories):
|
|
478
|
+
self.launch_fits(self.modelcodes[phase//2-1])
|
|
479
|
+
print("o " + time.asctime())
|
|
480
|
+
phase += 1
|
|
481
|
+
# Launch ModelSelector for this class
|
|
482
|
+
else:
|
|
483
|
+
if(self.InitCond_modelcategories == None or self.modelcodes[phase//2-2] in self.InitCond_modelcategories):
|
|
484
|
+
self.ModelSelector(self.modelcodes[phase//2-2])
|
|
485
|
+
print("o " + time.asctime())
|
|
486
|
+
phase += 1
|
|
487
|
+
|
|
488
|
+
def cleanup_preliminary_models(self):
|
|
489
|
+
os.chdir(self.eventname)
|
|
490
|
+
if(os.path.exists('PreModels')):
|
|
491
|
+
shutil.rmtree('PreModels')
|
|
492
|
+
|
|
493
|
+
def archive_run(self, destination = None):
|
|
494
|
+
olddir = os.getcwd()
|
|
495
|
+
os.chdir(self.eventname)
|
|
496
|
+
if(os.path.exists('LCToFit.txt')):
|
|
497
|
+
previousrunslist = glob.glob('run-*')
|
|
498
|
+
previousrunslist.sort()
|
|
499
|
+
if(destination == None):
|
|
500
|
+
if(len(previousrunslist)>0):
|
|
501
|
+
lastrun = int(previousrunslist[-1].split('-')[-1])
|
|
502
|
+
else:
|
|
503
|
+
lastrun = 0
|
|
504
|
+
rundir = 'run-' + str(lastrun+1). zfill(4)
|
|
505
|
+
else:
|
|
506
|
+
rundir = destination
|
|
507
|
+
alllist = glob.glob('*')
|
|
508
|
+
alllist.remove('Data')
|
|
509
|
+
filelist = list(set(alllist) - set(previousrunslist))
|
|
510
|
+
os.mkdir(rundir)
|
|
511
|
+
shutil.copytree('Data',rundir+'/Data')
|
|
512
|
+
for nam in filelist:
|
|
513
|
+
shutil.move(nam,rundir)
|
|
514
|
+
os.chdir(olddir)
|
|
515
|
+
|
|
516
|
+
def recover_options(self,run = None):
|
|
517
|
+
if(self.eventname == None):
|
|
518
|
+
print('! No event chosen')
|
|
519
|
+
if(run!=None):
|
|
520
|
+
pathname = run
|
|
521
|
+
else:
|
|
522
|
+
pathname = self.eventname
|
|
523
|
+
if(not(os.path.exists(pathname))):
|
|
524
|
+
print("Invalid path!")
|
|
525
|
+
return
|
|
526
|
+
if(os.path.exists(pathname + '/' + self.inidir + '/Constraints.ini')):
|
|
527
|
+
with open(pathname + '/' + self.inidir + '/Constraints.ini','r') as f:
|
|
528
|
+
lines = f.read().splitlines()
|
|
529
|
+
print('Constraints --- ',lines)
|
|
530
|
+
self.constraints =[]
|
|
531
|
+
for line in lines:
|
|
532
|
+
chunks =line.split()
|
|
533
|
+
self.constraints.append([chunks[0], float(chunks[2]), float(chunks[3]), float(chunks[4])])
|
|
534
|
+
self.set_constraints(self.constraints)
|
|
535
|
+
if(os.path.exists(pathname + '/' + self.inidir + '/Reader.ini')):
|
|
536
|
+
with open(pathname + '/' + self.inidir + '/Reader.ini','r') as f:
|
|
537
|
+
lines = f.read().splitlines()
|
|
538
|
+
print('Reader --- ',lines)
|
|
539
|
+
for line in lines:
|
|
540
|
+
chunks = line.split()
|
|
541
|
+
if(chunks[0]=='tau'):
|
|
542
|
+
self.Reader_tau = float(chunks[2])
|
|
543
|
+
elif(chunks[0]=='binning'):
|
|
544
|
+
self.Reader_binning = int(chunks[2])
|
|
545
|
+
elif(chunks[0]=='otherseasons'):
|
|
546
|
+
self.Reader_otherseasons = int(chunks[2])
|
|
547
|
+
elif(chunks[0]=='renormalize'):
|
|
548
|
+
self.Reader_renormalize = int(chunks[2])
|
|
549
|
+
elif(chunks[0]=='thresholdoutliers'):
|
|
550
|
+
self.Reader_thresholdoutliers = float(chunks[2])
|
|
551
|
+
if(os.path.exists(pathname + '/' + self.inidir + '/InitCond.ini')):
|
|
552
|
+
with open(pathname + '/' + self.inidir + '/InitCond.ini','r') as f:
|
|
553
|
+
lines = f.read().splitlines()
|
|
554
|
+
print('InitCond --- ',lines)
|
|
555
|
+
self.InitCond_nostatic = False
|
|
556
|
+
self.InitCond_onlyorbital = False
|
|
557
|
+
self.InitCond_override = None
|
|
558
|
+
self.InitCond_onlyupdate = False
|
|
559
|
+
for line in lines:
|
|
560
|
+
chunks = line.split()
|
|
561
|
+
if(chunks[0]=='npeaks'):
|
|
562
|
+
self.InitCond_npeaks = int(chunks[2])
|
|
563
|
+
elif(chunks[0]=='peakthreshold'):
|
|
564
|
+
self.InitCond_peakthreshold = float(chunks[2])
|
|
565
|
+
elif(chunks[0]=='oldmodels'):
|
|
566
|
+
self.InitCond_oldmodels = int(chunks[2])
|
|
567
|
+
elif(chunks[0]=='usesatellite'):
|
|
568
|
+
self.InitCond_usesatellite = int(chunks[2])
|
|
569
|
+
elif(chunks[0]=='nostatic'):
|
|
570
|
+
self.InitCond_nostatic = (int(chunks[2])!=0)
|
|
571
|
+
elif(chunks[0]=='onlyorbital'):
|
|
572
|
+
self.InitCond_onlyorbital = (int(chunks[2])!=0)
|
|
573
|
+
elif(chunks[0]=='onlyupdate'):
|
|
574
|
+
self.InitCond_onlyupdate = (int(chunks[2])!=0)
|
|
575
|
+
elif(chunks[0]=='override'):
|
|
576
|
+
self.InitCond_override = (float(chunks[2]),float(chunks[3]))
|
|
577
|
+
elif(chunks[0]=='templatelibrary'):
|
|
578
|
+
self.InitCond_templatelibrary = chunks[2]
|
|
579
|
+
elif(chunks[0]=='modelcategories'):
|
|
580
|
+
self.InitCond_modelcategories = [chunks[2][i:i+2] for i in range(0, len(chunks[2]), 2)]
|
|
581
|
+
if(os.path.exists(pathname + '/' + self.inidir + '/LevMar.ini')):
|
|
582
|
+
with open(pathname + '/' + self.inidir + '/LevMar.ini','r') as f:
|
|
583
|
+
lines = f.read().splitlines()
|
|
584
|
+
print('LevMar --- ',lines)
|
|
585
|
+
for line in lines:
|
|
586
|
+
chunks = line.split()
|
|
587
|
+
if(chunks[0]=='nfits'):
|
|
588
|
+
self.LevMar_nfits = int(chunks[2])
|
|
589
|
+
if(chunks[0]=='offsetdegeneracy'):
|
|
590
|
+
self.LevMar_offsetdegeneracy = int(chunks[2])
|
|
591
|
+
elif(chunks[0]=='maxsteps'):
|
|
592
|
+
self.LevMar_maxsteps = int(chunks[2])
|
|
593
|
+
elif(chunks[0]=='timelimit'):
|
|
594
|
+
self.LevMar_timelimit = float(chunks[2])
|
|
595
|
+
elif(chunks[0]=='bumperpower'):
|
|
596
|
+
self.LevMar_bumperpower = float(chunks[2])
|
|
597
|
+
elif(chunks[0] == 'turn_off_secondary_source' and chunks[2] == 'True'):
|
|
598
|
+
self.LevMar_turn_off_secondary_source = True
|
|
599
|
+
elif(chunks[0] == 'turn_off_secondary_lens' and chunks[2] == 'True'):
|
|
600
|
+
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
|
|
603
|
+
elif(chunks[0] == 'mass_luminosity_exponent'):
|
|
604
|
+
self.LevMar_mass_luminosity_exponent = float(chunks[2])
|
|
605
|
+
elif(chunks[0] == 'mass_radius_exponent'):
|
|
606
|
+
self.LevMar_mass_radius_exponent = float(chunks[2])
|
|
607
|
+
elif(chunks[0] == 'lens_mass_luminosity_exponent'):
|
|
608
|
+
self.LevMar_lens_mass_luminosity_exponent = float(chunks[2])
|
|
609
|
+
if(os.path.exists(pathname + '/' + self.inidir + '/ModelSelector.ini')):
|
|
610
|
+
with open(pathname + '/' + self.inidir + '/ModelSelector.ini','r') as f:
|
|
611
|
+
lines = f.read().splitlines()
|
|
612
|
+
print('ModelSelector --- ',lines)
|
|
613
|
+
for line in lines:
|
|
614
|
+
chunks = line.split()
|
|
615
|
+
if(chunks[0]=='sigmasoverlap'):
|
|
616
|
+
self.ModelSelector_sigmasoverlap = float(chunks[2])
|
|
617
|
+
elif(chunks[0]=='sigmachisquare'):
|
|
618
|
+
self.ModelSelector_sigmachisquare = float(chunks[2])
|
|
619
|
+
elif(chunks[0]=='maxmodels'):
|
|
620
|
+
self.ModelSelector_maxmodels = int(chunks[2])
|
|
621
|
+
|
|
622
|
+
@staticmethod
|
|
623
|
+
def find_bin_directory() -> str:
|
|
624
|
+
"""
|
|
625
|
+
Searches for the RTModel/bin directory in the available site-packages directories.
|
|
626
|
+
|
|
627
|
+
:return: The string of the parth to the bin directory.
|
|
628
|
+
"""
|
|
629
|
+
bin_directory_string = None
|
|
630
|
+
site_packages_directories = site.getsitepackages()
|
|
631
|
+
site_packages_directories.append(site.getusersitepackages())
|
|
632
|
+
for site_packages_directory in site_packages_directories:
|
|
633
|
+
bin_directory_path = Path(site_packages_directory).joinpath('RTModel/bin')
|
|
634
|
+
if bin_directory_path.exists():
|
|
635
|
+
bin_directory_string = str(bin_directory_path) + '/'
|
|
636
|
+
break
|
|
637
|
+
if bin_directory_string is None:
|
|
638
|
+
raise FileNotFoundError(f'RTModel binary directory not found. Searched {site_packages_directories} '
|
|
639
|
+
f'site-packages directories.')
|
|
640
|
+
return bin_directory_string
|
RTModel/__init__.py
ADDED
|
Binary file
|
RTModel/bin/InitCond.exe
ADDED
|
Binary file
|
RTModel/bin/LevMar.exe
ADDED
|
Binary file
|
|
Binary file
|