Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

relative filepath handling #114

Draft
wants to merge 7 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions canflood/build/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,8 @@ def upd_lfield(): #updating the field box
#===========================================================================
# HELPERS----------
#===========================================================================
def set_setup(self, set_cf_fp=True, set_finv=True, #attach parameters from setup tab
logger=None,):
def set_setup(self, set_cf_fp=True, set_finv=True, logger=None,):
"""attach parameters from setup tab"""
if logger is None: logger=self.logger
log = logger.getChild('set_setup')
#=======================================================================
Expand Down Expand Up @@ -625,8 +625,7 @@ def build_scenario(self): # Generate a CanFlood project from scratch
#=======================================================================
# prechecks
#=======================================================================
if self.radioButton_SS_fpRel.isChecked():
raise Error('Relative filepaths not implemented')


self.feedback.upd_prog(10)

Expand Down
14 changes: 11 additions & 3 deletions canflood/build/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,20 @@ def config_cf(self, #helper to initilaize the configParser
return cpars


def cf_check(self, #check the control file against a passed model's expectation handles
modObj #model object to run check against
def cf_check(self, #
modObj
):
"""check the control file against a passed model's expectation handles

Params
----------
modObj: class object
an uninitalized child of the model.modcom.Model() class
must have a `validate` method
"""


wrkr = modObj(cf_fp = self.cf_fp, logger=self.logger) #initilize it
wrkr = modObj(cf_fp = self.cf_fp, logger=self.logger, absolute_fp=self.absolute_fp) #initilize it
#=======================================================================
# check against expectations
#=======================================================================
Expand Down
11 changes: 8 additions & 3 deletions canflood/hlpr/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,19 @@ def set_cf_pars(self, #update the control file w/ the passed parameters

return

def _get_from_cpar(self, #special parameter extraction recognizing object's t ype
def _get_from_cpar(self, #
cpars,
sectName,
varName,
logger = None):

"""each parameter should exist on teh class instance.
we use this to set the type"""
"""special parameter extraction recognizing object's type

each parameter should exist on teh class instance.
we use this to set the type


"""

if logger is None: logger=self.logger
log = logger.getChild('_get_from_cpar')
Expand Down
7 changes: 6 additions & 1 deletion canflood/hlpr/logr.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,16 @@ def basic_logger(root_lvl = logging.DEBUG,
#===========================================================================
logger = logging.getLogger() #get the root logger
logging.config.fileConfig(logcfg_file) #load the configuration file
logger.info('root logger initiated and configured from file: %s'%(logcfg_file))
logger.info('root logger initiated and configured from file:\n %s'%(logcfg_file))

#override default level in the config file
logger.setLevel(root_lvl)

# Retrieve filename and path of the file handler
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
print(f"log file location: {handler.baseFilename}") # Prints the file path




Expand Down
48 changes: 23 additions & 25 deletions canflood/model/modcom.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ def init_model(self, #load and attach control file parameters
if 'absolute_fp' in self.pars['parameters']:
absolute_fp = self.pars['parameters'].getboolean('absolute_fp')
if not self.absolute_fp==absolute_fp:
log.warning(f'overwriting \'aboslute_fp\' with value from control file ({absolute_fp})')
log.warning(f'overwriting \'absolute_fp\' with value from control file ({absolute_fp})')
self.absolute_fp=absolute_fp


Expand Down Expand Up @@ -710,13 +710,7 @@ def _get_cf_miss(self, #collect mismatch between expectations and control file p
cpars):

assert isinstance(cpars, configparser.ConfigParser)
#===============================================================================
# errors = []
#
# for chk_d, opt_f in ((self.exp_pars_md,False), (self.exp_pars_op,True)):
# _, l = self.cf_chk_pars(cpars, copy.copy(chk_d), optional=opt_f)
# errors = errors + l
#===============================================================================


#=======================================================================
# mandatory
Expand Down Expand Up @@ -2082,7 +2076,9 @@ def _par_hndl_chk(self,
"""

if logger is None: logger=self.logger
if absolute_fp= None: absolute_fp=self.aboslute_fp
if not hasattr(self, 'absolute_fp'):
raise AttributeError(f'object {self.__name__} missing attribute \'absolute_fp\'')
if absolute_fp is None: absolute_fp=self.absolute_fp
log = logger.getChild('par_hndl_chk')

#=======================================================================
Expand All @@ -2108,6 +2104,9 @@ def _par_hndl_chk(self,
assert isinstance(hvals, tuple), '%s.%s got bad type on hvals: %s'%(sect, varnm, type(hvals))
assert pval in hvals, '%s.%s unexpected value: \'%s\''%(sect, varnm, pval)

#===================================================================
# filepaths
#===================================================================
elif chk_hndl == 'ext':

#basic checks
Expand All @@ -2118,11 +2117,9 @@ def _par_hndl_chk(self,

#handl relative filepaths
if not absolute_fp:
pval = os.path.join(self.cf_dir, pval)


pval = os.path.join(self.cf_dir, pval)

assert os.path.exists(pval), '%s.%s passed invalid filepath: \'%s\''%(sect, varnm, pval)
assert os.path.exists(pval), f'%s.%s passed invalid filepath (absolute_fp={absolute_fp}):\n %s'%(sect, varnm, pval)

ext = os.path.splitext(os.path.split(pval)[1])[1]

Expand All @@ -2143,22 +2140,23 @@ def _par_hndl_chk(self,



def validate(self, #validate this model object
cpars, #initilzied config parser
#so a session can pass a control file... rather than usin gthe workers init
logger=None,
):
#if logger is None: logger=self.logger
def validate(self, cpars, logger=None,):

"""only 1 check for now"""
#=======================================================================
# check the control file expectations
#=======================================================================
errors = self._get_cf_miss(cpars)
"""run all validation checks on this model
only 1 check for now. check the control file expectations

children could over-write this method with custom validations

Params
---------
cpars: config parser
so a session can pass a control file... rather than usin gthe workers init

"""
#if logger is None: logger=self.logger


return errors
return self._get_cf_miss(cpars) #check the control file expectations

def check_attrimat(self, #check the logic of the attrimat
atr_dxcol=None,
Expand Down
81 changes: 43 additions & 38 deletions tests2/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ def __init__(self, crs=None,logger=None,**kwargs):

super().__init__(crsid = crs.authid(), logger=logger,
#feedbac=MyFeedBackQ(logger=logger),
**kwargs)


**kwargs)

self.logger.info('finished Session_pytest.__init__')

Expand Down Expand Up @@ -101,6 +99,11 @@ def __exit__(self, exc_type, exc_value, traceback):
#sys.exit() #wrap
print('exiting DialTester')


#===============================================================================
# FIXTURES.FUNCTIONS-------
#===============================================================================

@pytest.fixture(scope='function')
def dialogClass(request): #always passing this as an indirect
return request.param
Expand Down Expand Up @@ -128,6 +131,7 @@ def session(tmp_path,
"""TODO: fix logger"""

np.random.seed(100)
print(f'tmp_path\n {tmp_path}')

#configure output
out_dir=tmp_path
Expand Down Expand Up @@ -157,29 +161,50 @@ def session(tmp_path,

yield ses

@pytest.fixture(scope='session')
def write():

write=False


if write:
print('WARNING!!! runnig in write mode')
return write

#===============================================================================
# function.fixtures-------
#===============================================================================


@pytest.fixture(scope='function')
def out_dir(tmp_path):
return tmp_path

@pytest.fixture(scope='function')
def test_name(request):
return request.node.name.replace('[','_').replace(']', '_')


@pytest.fixture(scope='function')
def true_dir(write, tmp_path, test_dir):
true_dir = os.path.join(test_dir, os.path.basename(tmp_path))
if write:
if os.path.exists(true_dir):
try:
shutil.rmtree(true_dir)
os.makedirs(true_dir) #add back an empty folder
#os.makedirs(os.path.join(true_dir, 'working')) #and the working folder
except Exception as e:
print('failed to cleanup the true_dir: %s w/ \n %s'%(true_dir, e))

"""no... this is controlled with the out_dir on the session
#not found.. create a fresh one
if not os.path.exists(true_dir):
os.makedirs(true_dir)"""

#assert os.path.exists(true_dir)
return true_dir

#===============================================================================
# session.fixtures----------
# FIXTURES.SESSIOn----------
#===============================================================================
@pytest.fixture(scope='session')
def write():

write=False


if write:
print('WARNING!!! runnig in write mode')
return write

#===============================================================================
# logger
Expand Down Expand Up @@ -232,9 +257,7 @@ def logger():
"""simple backend loggers"""
return mod_logger

#===============================================================================
# directories----------
#===============================================================================

@pytest.fixture(scope='session')
def base_dir():
from definitions import base_dir
Expand All @@ -248,25 +271,7 @@ def test_dir(base_dir):



@pytest.fixture
def true_dir(write, tmp_path, test_dir):
true_dir = os.path.join(test_dir, os.path.basename(tmp_path))
if write:
if os.path.exists(true_dir):
try:
shutil.rmtree(true_dir)
os.makedirs(true_dir) #add back an empty folder
#os.makedirs(os.path.join(true_dir, 'working')) #and the working folder
except Exception as e:
print('failed to cleanup the true_dir: %s w/ \n %s'%(true_dir, e))

"""no... this is controlled with the out_dir on the session
#not found.. create a fresh one
if not os.path.exists(true_dir):
os.makedirs(true_dir)"""

#assert os.path.exists(true_dir)
return true_dir


#===============================================================================
Expand All @@ -280,7 +285,7 @@ def _build_dialog_validate_handler(dial):
but in a test environment, we want to raise these
"""
QTest.mouseClick(dial.pushButton_Validate, Qt.LeftButton)
# Loop through errors generated by Model.cf_chk_pars() and raise them
# Loop through errors generated by Model.cf_chk_pars() and raise them
for vtag, error_l in dial.validation_result_d.items():
for error in error_l:
if isinstance(error, Exception):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ apply_miti = False #whether to apply mitigation algorthihims

[dmg_fps]
curves = #damage curve library filepath
finv = finv_test_02_32_tut2.csv
finv = tests2\data\test_02_build_inv_tests2__data0\finv_test_02_32_tut2.csv
expos = #exposure data filepath
gels = #ground elevation data filepath
#'finv' file path set from prepr.py at 2022-06-26 14.30.12

[risk_fps]
dmgs = #damage data results filepath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ gels = #ground elevation data filepath
[risk_fps]
dmgs = #damage data results filepath
exlikes = #secondary exposure likelihood data filepath
evals = C:\LS\09_REPOS\03_TOOLS\CanFlood\_git\tests2\data\test_05_build_evals_tests2__da0\evals_4_test_05.csv
#evals file path set from build.dialog.py at 2022-06-26 18.06.20
evals = tests2\data\test_05_build_evals_tests2__da0\evals_4_test_05.csv


[validation]
risk1 = False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ curves = tests2\data\test_03_build_inv_curves_tests0\cLib_test_03_2022-06-26_180
finv = tests2\data\test_02_build_inv_tests2__data0\finv_test_02_32_tut2.csv
expos = tests2\data\test_04_build_hsamp_tutorials_0\expos_test_04_4_32.csv
gels = tests2\data\test_06_build_dtm_tutorials__20\gels_test_06_1_32.csv
#'gels' file path set from rsamp.py at 2022-06-26 18.06.21

[risk_fps]
dmgs = #damage data results filepath
exlikes = #secondary exposure likelihood data filepath
evals = C:\LS\09_REPOS\03_TOOLS\CanFlood\_git\tests2\data\test_05_build_evals_tests2__da0\evals_4_test_05.csv
evals = tests2\data\test_05_build_evals_tests2__da0\evals_4_test_05.csv

[validation]
risk1 = False
dmg2 = False
risk2 = False
risk3 = False
# 'dmg2' validated by validator.py at 2025-01-24 16.59.58

[results_fps]
attrimat02 = #lvl2 attribution matrix fp (post dmg model)
Expand Down
Loading