diff --git a/ctamclib/telescope_model.py b/ctamclib/telescope_model.py index 0dee81510..d6ed6d469 100644 --- a/ctamclib/telescope_model.py +++ b/ctamclib/telescope_model.py @@ -2,8 +2,8 @@ """ This module contains the TelescopeModel class -Todo: - * fromConfigFile - deal with ifdef's in simtel cfg files + Todo: + * fromConfigFile - deal with ifdef's in simtel cfg files """ import logging @@ -88,13 +88,13 @@ def __init__(self, telescopeType, site, yamlDBPath=None, version='default', labe self.filesLocation = Path.cwd() if filesLocation is None else Path(filesLocation) if readFromDB: - self.loadParametersFromDB() + self._loadParametersFromDB() self._isFileExported = False @property def version(self): - """str: model version after validation.""" + """ str: model version after validation. """ return self._version @version.setter @@ -103,7 +103,7 @@ def version(self, value): @property def telescopeType(self): - """str: telescope type after validation.""" + """str: telescope type after validation. """ return self._telescopeType @telescopeType.setter @@ -112,7 +112,7 @@ def telescopeType(self, value): @property def site(self): - """str: site after validation.""" + """str: site after validation. """ return self._site @site.setter @@ -164,22 +164,20 @@ def processLine(words): continue elif '#' not in line and len(words) > 0: par, value = processLine(words) - par, value = tel.validateParameter(par, value) + par, value = tel._validateParameter(par, value) parameters[par] = value tel.addParameters(**parameters) return tel - def loadParametersFromDB(self): - """ Read parameters from DB and store it in _parameters (dict). + def _loadParametersFromDB(self): + """ Read parameters from DB and store it in _parameters (dict). """ - """ - - def readParsFromOneType(yamlDBPath, telescopeType, parametersDB): - ''' Read parameters as a dict and concatenate it to parametersDB + def _readParsFromOneType(yamlDBPath, telescopeType, parametersDB): + """ Read parameters as a dict and concatenate it to parametersDB Implementation was needed to concatenate the optics parameters - to the MST models - ''' + to the MST models. + """ fileNameDB = '{}/parValues-{}.yml'.format(yamlDBPath, telescopeType) logging.info('Reading DB file {}'.format(fileNameDB)) with open(fileNameDB, 'r') as stream: @@ -187,13 +185,13 @@ def readParsFromOneType(yamlDBPath, telescopeType, parametersDB): parametersDB.update(pars) parametersDB = dict() - readParsFromOneType(self.yamlDBPath, self.telescopeType, parametersDB) + _readParsFromOneType(self.yamlDBPath, self.telescopeType, parametersDB) if whichTelescopeSize(self.telescopeType) == 'MST': - readParsFromOneType(self.yamlDBPath, 'MST-optics', parametersDB) + _readParsFromOneType(self.yamlDBPath, 'MST-optics', parametersDB) for parNameIn in parametersDB: if parametersDB[parNameIn]['Applicable']: - parName, parValue = self.validateParameter( + parName, parValue = self._validateParameter( parNameIn, parametersDB[parNameIn][self._version] ) @@ -204,8 +202,8 @@ def readParsFromOneType(yamlDBPath, telescopeType, parametersDB): # atmospheric_transmission and altitude logging.debug('Reading site parameters from DB') - def getSiteParameter(yamlDBPath, site, parName): - ''' Get the value of parName for a given site ''' + def _getSiteParameter(yamlDBPath, site, parName): + """ Get the value of parName for a given site """ fileNameDB = '{}/parValues-Sites.yml'.format(yamlDBPath) logging.info('Reading DB file {}'.format(fileNameDB)) with open(fileNameDB, 'r') as stream: @@ -215,13 +213,23 @@ def getSiteParameter(yamlDBPath, site, parName): return allPars[par][self._version] for siteParName in ['atmospheric_transmission', 'altitude']: - siteParValue = getSiteParameter(self.yamlDBPath, self.site, siteParName) - parName, parValue = self.validateParameter(siteParName, siteParValue) + siteParValue = _getSiteParameter(self.yamlDBPath, self.site, siteParName) + parName, parValue = self._validateParameter(siteParName, siteParValue) self._parameters[parName] = parValue - # end loadParametersFromDB + # end _loadParametersFromDB + + def _validateParameter(self, parNameIn, parValueIn): + """ Validate model parameter based on the dict MODEL_PARS. + + Args: + parNameIn (str): name of the parameters + parValueIn (str): value of parameter - def validateParameter(self, parNameIn, parValueIn): + Return: + parNameIn, parValueIn after validated. parValueIn is converted to the proper + type if that information is available in MODEL_PARS + """ logging.debug('Validating parameter {}'.format(parNameIn)) for parNameModel in MODEL_PARS.keys(): if parNameIn == parNameModel or parNameIn in MODEL_PARS[parNameModel]['names']: @@ -230,21 +238,35 @@ def validateParameter(self, parNameIn, parValueIn): return parNameIn, parValueIn def getParameter(self, parName): - ''' Return an EXISTING parameter of the model ''' + """ Get an EXISTING parameter of the model. + + Args: + parName (str): name of the parameters + + Return: + Value of the parameter + + Raises: + ValueError: if parName does not match any parameter in the model. + """ + if parName in self._parameters: return self._parameters[parName] else: - logging.error('Parameter {} was not found in the model'.format(parName)) - return '' + raise ValueError('Parameter {} was not found in the model'.format(parName)) def addParameters(self, **kwargs): - ''' Add a NEW parameters to the model. - kwargs are used, parameters should be passed as - parameterName=value - ''' + """ Add a NEW parameters to the model. + + Args: + kwargs: parameters should be passed as parameterName=value. + + Raises: + ValueError: if an existing parameter is tried to be set added. + """ for par in kwargs.keys(): if par in self._parameters.keys(): - logging.error( + raise ValueError( 'Parameter {} already in the model, use changeParameter instead'.format(par) ) else: @@ -252,31 +274,42 @@ def addParameters(self, **kwargs): self._parameters[par] = str(kwargs[par]) def changeParameters(self, **kwargs): - ''' Change the value of EXISTING parameters to the model ''' + """ Change the value of EXISTING parameters to the model. + + Args: + kwargs: parameters should be passed as parameterName=value. + + Raises: + ValueError: if the parameter to be changed does not exist. + """ for par in kwargs.keys(): if par not in self._parameters.keys(): - logging.error( + raise ValueError( 'Parameter {} not in the model, use addParameters instead'.format(par) ) else: self._parameters[par] = kwargs[par] def removeParameters(self, *args): - ''' Remove a parameter from the model ''' + """ Remove a parameter from the model. + + Args: + args: each parameter to be removed has to be passed as args. + + Raises: + ValueError: if the parameter to be removed is not on the model. + """ for par in args: if par in self._parameters.keys(): logging.info('Removing parameter {}'.format(par)) del self._parameters[par] else: - logging.error( + raise ValueError( 'Could not remove parameter {} because it does not exist'.format(par) ) def exportConfigFile(self): - ''' Export the config file used by sim_telarray. - loc gives the location that the file should be created. - If loc is not given, a directory $pwd/SimtelFiles/cfg is created and used - ''' + """ Export the config file used by sim_telarray. """ # Setting file name and the location configFileName = 'CTA-{}-{}-{}'.format(self._version, self.site, self.telescopeType) @@ -311,9 +344,12 @@ def exportConfigFile(self): # end exportConfigFile def getConfigFile(self): - ''' Return config file - Export it first if it was not exported yet - ''' + """ Return the full path of the config file for sim_telarray. + The config file is produced if the file still does not exist. + + Return: + Path of the config file for sim_telarray. + """ if not self._isFileExported: self.exportConfigFile() return self._configFilePath diff --git a/ctamclib/tests/test_ray_tracing.py b/ctamclib/tests/test_ray_tracing.py index a7dc97416..77e7b5c8e 100644 --- a/ctamclib/tests/test_ray_tracing.py +++ b/ctamclib/tests/test_ray_tracing.py @@ -19,113 +19,145 @@ '/afs/ifh.de/group/cta/scratch/prado/corsika_simtelarray/corsika6.9_simtelarray_19-03-08' ) - sourceDistance = 10 - site = 'south' - version = 'prod4' - label = 'test-astri' - zenithAngle = 20 - # offAxisAngle = [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5] - # offAxisAngle = [0, 1.0, 2.0, 3.0, 4.0, 5.0] - offAxisAngle = [0, 2.5, 5.0] - - # Test with MST - tel = TelescopeModel( - yamlDBPath=yamlDBPath, - telescopeType='astri', - site=site, - version=version, - label=label - ) - - ray = RayTracing( - simtelSourcePath=simtelPath, - telescopeModel=tel, - sourceDistance=sourceDistance, - zenithAngle=zenithAngle, - offAxisAngle=offAxisAngle - ) - - ray.simulate(test=True, force=False) - # ray_rx = copy(ray) - - ray.analyze(force=True) - # ray_rx.analyze(force=True, useRX=True) - # Plotting PSF images + # sourceDistance = 10 + # site = 'south' + # version = 'prod4' + # label = 'test-astri' + # zenithAngle = 20 + # # offAxisAngle = [0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5] + # # offAxisAngle = [0, 1.0, 2.0, 3.0, 4.0, 5.0] + # offAxisAngle = [0, 2.5, 5.0] + + # # Test with MST + # tel = TelescopeModel( + # yamlDBPath=yamlDBPath, + # telescopeType='astri', + # site=site, + # version=version, + # label=label + # ) + + # ray = RayTracing( + # simtelSourcePath=simtelPath, + # telescopeModel=tel, + # sourceDistance=sourceDistance, + # zenithAngle=zenithAngle, + # offAxisAngle=offAxisAngle + # ) + + # ray.simulate(test=True, force=False) + # # ray_rx = copy(ray) + + # ray.analyze(force=True) + # # ray_rx.analyze(force=True, useRX=True) + # # Plotting PSF images + + # for im in ray.images(): + # print(im) + # plt.figure(figsize=(8, 6), tight_layout=True) + # ax = plt.gca() + # ax.set_xlabel('X') + # ax.set_ylabel('Y') + + # # psf_* for PSF circle + # # image_* for histogram + # im.plot(psf_color='b') + + # ax.set_aspect('equal', adjustable='datalim') + # plt.show() + + # # Plotting d80 + # plt.figure(figsize=(8, 6), tight_layout=True) + # ax = plt.gca() + # ax.set_xlabel('off-axis') + # ax.set_ylabel('d80') - for im in ray.images(): - print(im) - plt.figure(figsize=(8, 6), tight_layout=True) - ax = plt.gca() - ax.set_xlabel('X') - ax.set_ylabel('Y') + # # ratio = [r / s for (r, s) in zip(ray_rx._results['d80_deg'], ray._results['d80_deg'])] - # psf_* for PSF circle - # image_* for histogram - im.plot(psf_color='b') + # ray.plot('d80_deg', marker='o', linestyle=':') + # # ray_rx.plot('d80_deg', marker='s', linestyle='--') - ax.set_aspect('equal', adjustable='datalim') - plt.show() + # plt.show() - # Plotting d80 - plt.figure(figsize=(8, 6), tight_layout=True) - ax = plt.gca() - ax.set_xlabel('off-axis') - ax.set_ylabel('d80') + # # Plotting effArea + # plt.figure(figsize=(8, 6), tight_layout=True) + # ax = plt.gca() + # ax.set_xlabel('off-axis') + # ax.set_ylabel('eff. area') - # ratio = [r / s for (r, s) in zip(ray_rx._results['d80_deg'], ray._results['d80_deg'])] + # ray.plot('eff_area', marker='o', linestyle=':') + # # ray_rx.plot('d80_deg', marker='s', linestyle='--') - ray.plot('d80_deg', marker='o', linestyle=':') - # ray_rx.plot('d80_deg', marker='s', linestyle='--') + # plt.show() - plt.show() + # Test with 3 SSTs + sourceDistance = 10 + site = 'south' + version = 'prod4' + zenithAngle = 20 + offAxisAngle = [0, 1.0, 2.0, 3.0, 4.0, 5.0] + + telTypes = ['sst-1m', 'sst-astri', 'sst-gct'] + telModels = list() + rayTracing = list() + for t in telTypes: + tel = TelescopeModel( + yamlDBPath=yamlDBPath, + telescopeType=t, + site=site, + version=version, + label='test-sst' + ) + telModels.append(t) + + ray = RayTracing( + simtelSourcePath=simtelPath, + telescopeModel=tel, + sourceDistance=sourceDistance, + zenithAngle=zenithAngle, + offAxisAngle=offAxisAngle + ) + ray.simulate(test=False, force=False) + ray.analyze(force=False) + + rayTracing.append(ray) + + # tel = TelescopeModel( + # yamlDBPath=yamlDBPath, + # telescopeType='sst-astri', + # site=site, + # version=version, + # label='test-sst' + # ) + # rnd = tel.getParameter('mirror_reflection_random_angle') + # rnd = rnd.split() + # rnd = 1.2 * float(rnd[0]) + # tel.changeParameters(mirror_reflection_random_angle='{} 0 0 '.format(rnd)) + + # telModels.append(t) + + # ray = RayTracing( + # simtelSourcePath=simtelPath, + # telescopeModel=tel, + # sourceDistance=sourceDistance, + # zenithAngle=zenithAngle, + # offAxisAngle=offAxisAngle + # ) + # ray.simulate(test=False, force=False) + # ray.analyze(force=False) + + # rayTracing.append(ray) + + # Plotting - # Plotting effArea plt.figure(figsize=(8, 6), tight_layout=True) ax = plt.gca() ax.set_xlabel('off-axis') - ax.set_ylabel('eff. area') + ax.set_ylabel('d80') - ray.plot('eff_area', marker='o', linestyle=':') - # ray_rx.plot('d80_deg', marker='s', linestyle='--') + for ray in rayTracing: + ray.plot('d80_deg', marker='o', linestyle=':') plt.show() - # Test with 3 SSTs - # telTypes = ['sst-1m', 'sst-astri', 'sst-gct'] - # telModels = list() - # rayTracing = list() - # for t in telTypes: - # tel = TelescopeModel( - # yamlDBPath=yamlDBPath, - # telescopeType=t, - # site=site, - # version=version, - # label=label - # ) - # telModels.append(t) - - # ray = RayTracing( - # simtelSourcePath=simtelPath, - # telescopeModel=tel, - # sourceDistance=sourceDistance, - # zenithAngle=zenithAngle, - # offAxisAngle=offAxisAngle - # ) - # ray.simulate(test=False, force=True) - # ray.analyze(force=True) - - # rayTracing.append(ray) - - # # Plotting - - # plt.figure(figsize=(8, 6), tight_layout=True) - # ax = plt.gca() - # ax.set_xlabel('off-axis') - # ax.set_ylabel('d80') - - # for ray in rayTracing: - # ray.plot('d80_deg', marker='o', linestyle=':') - - # plt.show() - - # # script = simtel.getRunBashScript() + # script = simtel.getRunBashScript() diff --git a/docs/source/conf.py b/docs/source/conf.py index 015f00e29..f72c7876b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -167,4 +167,16 @@ # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} \ No newline at end of file +intersphinx_mapping = {'https://docs.python.org/': None} + + +# -- Raul: making sphinx add classes' __init__ always + +def skip(app, what, name, obj, would_skip, options): + if name == "__init__": + return False + return would_skip + + +def setup(app): + app.connect("autodoc-skip-member", skip) diff --git a/docs/source/index.rst b/docs/source/index.rst index a9abd6d7d..2ccb0d7a3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -37,7 +37,6 @@ sim_telarray .. toctree:: - Ray Tracing ============