Commit 98a8af39 authored by VIGNET Pierre's avatar VIGNET Pierre
Browse files

Add argparse support; full doc; clean code; better logging

parent 1e683db2
......@@ -19,7 +19,7 @@ run_gui:
unit_test:
@echo Unit tests...
$(CMD_PYTHON) script_mac.py
$(CMD_PYTHON) script_mac.py -vv debug compute_macs bio_models/mini_test_publi.bcx P --steps 10
py.test
version:
......
......@@ -2,16 +2,18 @@
from __future__ import unicode_literals
from __future__ import print_function
# Standard imports
import argparse
import re
import os
# Custom imports
from cadbiom.models.clause_constraints.mcl.MCLAnalyser import MCLAnalyser
from cadbiom.models.clause_constraints.mcl.MCLQuery import MCLSimpleQuery
import cadbiom.commons as cm
LOGGER = cm.logger()
MODEL_FOLDER="/media/DATA/Projets/dyliss_tgf/cadbiom/bio_models/"
RESULT_FOLDER="/media/DATA/Projets/dyliss_tgf/cadbiom/result/"
class ErrorRep(object):
# Cf class CompilReporter(object):
......@@ -70,102 +72,133 @@ def make_logical_formula(previous_frontier_places, start_prop):
def main2(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file,
steps, final_prop, start_prop, inv_prop):
"""
steps, final_prop, start_prop, inv_prop):
"""
.. todo: handle these QUERY PARAMETERS... from GUI program
.. todo: handle these QUERY PARAMETERS... from GUI program
# if self.possible:
# if len(inv_prop) == 0:
# inv_prop = None
# else :
# inv_prop = "not ("+inv_prop+")"
# else:
# if len(inv_prop) != 0:
# sert pas:
# final_prop = "not ("+final_prop+" and "+inv_prop+")"
# if self.possible:
# if len(inv_prop) == 0:
# inv_prop = None
# else :
# inv_prop = "not ("+inv_prop+")"
# else:
# if len(inv_prop) != 0:
# sert pas:
# final_prop = "not ("+final_prop+" and "+inv_prop+")"
"""
"""
# Build MCLA
error_reporter = ErrorRep()
mcla = MCLAnalyser(error_reporter)
# Build MCLA
error_reporter = ErrorRep()
mcla = MCLAnalyser(error_reporter)
# Load file
mcla.build_from_chart_file(chart_file)
if error_reporter.error:
raise "Error during loading of file"
# Load file
detect_model_type(mcla, chart_file)(chart_file)
if error_reporter.error:
raise "Error during loading of file"
# Frontier places asked
previous_frontier_places = set()
# Frontier places asked
previous_frontier_places = set()
while True:
while True:
frontier_places, min_steps = \
find_mac(mcla, start_prop, inv_prop, final_prop, steps)
frontier_places, min_steps = \
find_mac(mcla,
cam_file, cam_step_file, cam_complete_file,
steps, final_prop, start_prop, inv_prop)
# Add theese frontier places to set of previous ones
previous_frontier_places.update(frontier_places)
LOGGER.debug("Prev frontier places: " + \
str(previous_frontier_places))
# Add theese frontier places to set of previous ones
previous_frontier_places.update(frontier_places)
LOGGER.debug("Prev frontier places: " + \
str(previous_frontier_places))
# Compute the formula of the next start_property
start_prop = make_logical_formula(previous_frontier_places,
start_prop)
LOGGER.debug("Next start_prop formula: " + str(start_prop))
# Compute the formula of the next start_property
start_prop = make_logical_formula(previous_frontier_places,
start_prop)
LOGGER.debug("Next start_prop formula: " + str(start_prop))
def find_mac(mcla, start_prop, inv_prop, final_prop, steps):
def find_mac(mcla,
cam_file, cam_step_file, cam_complete_file,
steps, final_prop, start_prop, inv_prop):
# Build query
query = MCLSimpleQuery(start_prop, inv_prop, final_prop)
# Build query
query = MCLSimpleQuery(start_prop, inv_prop, final_prop)
# Is the property reacheable ?
reacheable = mcla.sq_is_satisfiable(query, steps)
# If yes, in how many steps ?
min_step = mcla.unfolder.get_current_step()
# Is the property reacheable ?
reacheable = mcla.sq_is_satisfiable(query, steps)
# If yes, in how many steps ?
min_step = mcla.unfolder.get_current_step()
if reacheable:
LOGGER.info(
"Property {} is reacheable in {} steps".format(
final_prop, min_step
)
if reacheable:
LOGGER.info(
"Property {} is reacheable in {} steps".format(
final_prop, min_step
)
else:
LOGGER.info(
"Property {} is NOT reacheable in {} steps".format(
final_prop, min_step
)
)
else:
LOGGER.info(
"Property {} is NOT reacheable in {} steps".format(
final_prop, min_step
)
LOGGER.info("STOP the search!")
exit()
# Find next MAC
next_mac_object = mcla.next_mac(query, min_step)
if next_mac_object:
LOGGER.debug("Next MAC object:\n{}".format(next_mac_object))
# Save MAC and timings
LOGGER.debug("Save MAC and timings...")
with open(cam_complete_file, 'a') as file:
next_mac_object.save(file)
# Save MAC
next_mac = next_mac_object.activated_frontier
LOGGER.debug("Save next MAC: {}".format(next_mac))
with open(cam_file, 'a') as file:
file.write('\t'.join(next_mac) + '\n')
# Save min steps
min_step = mcla.unfolder.get_current_step()
LOGGER.debug("Save minimal steps: {}".format(min_step))
with open(cam_step_file, 'a') as file:
file.write(str(min_step)+'\n')
return next_mac, min_step
else:
LOGGER.info("STOP the search! No more MAC.")
exit()
)
LOGGER.info("STOP the search!")
exit()
# Find next MAC
next_mac_object = mcla.next_mac(query, min_step)
if next_mac_object:
LOGGER.debug("Next MAC object:\n{}".format(next_mac_object))
# Save MAC and timings
LOGGER.debug("Save MAC and timings...")
with open(cam_complete_file, 'a') as file:
next_mac_object.save(file)
# Save MAC
next_mac = next_mac_object.activated_frontier
LOGGER.debug("Save next MAC: {}".format(next_mac))
with open(cam_file, 'a') as file:
file.write('\t'.join(next_mac) + '\n')
# Save min steps
min_step = mcla.unfolder.get_current_step()
LOGGER.debug("Save minimal steps: {}".format(min_step))
with open(cam_step_file, 'a') as file:
file.write(str(min_step)+'\n')
return next_mac, min_step
else:
LOGGER.info("STOP the search! No more MAC.")
exit()
def detect_model_type(mclanalyser, filepath):
"""Return the function to use to load the model.
bcx file: Build an MCLAnalyser from a .bcx file:
build_from_chart_file()
cal file: Build an MCLAnalyser from a .cal file of PID database
build_from_cadlang()
xml file: Build an MCLAnalyser from a .xml file of PID database:
build_from_pid_file()
"""
build_func = {".bcx": mclanalyser.build_from_chart_file,
".cal": mclanalyser.build_from_cadlang,
".xml": mclanalyser.build_from_pid_file,
}
try:
extension = re.search('^.*(\.[bcx|xml|cal]{3})', filepath).group(1)
LOGGER.debug("Find '" + extension + "' extension")
except:
LOGGER.error("Unauthorized file")
exit()
return build_func[extension]
def main(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file,
steps, final_prop, start_prop, inv_prop):
......@@ -190,19 +223,6 @@ def main(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file
# BUILD MCLA
error_reporter = ErrorRep()
mcla = MCLAnalyser(error_reporter)
# build_from_chart_model
# Build an MCLAnalyser from a chartmodel object
# @param model: object - ChartModel
# = représentation interne...
# build_from_chart_file
# Build an MCLAnalyser from a .bcx file
# @param file_name: str - path of the .bcx file
# build_from_pid_file
# Build an MCLAnalyser from a .xml file of PID database
# @param file_name: str - path of .xml file
# build_from_cadlang
# Build an MCLAnalyser from a .cal file of PID database
# @param file_name: str - path of .cal file
mcla.build_from_chart_file(chart_file)
if error_reporter.error:
......@@ -211,14 +231,6 @@ def main(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file
#return
print("ERROR:: " + error_reporter.error)
raise
#
# if len(inv_prop) == 0:
# inv_prop = None
# else :
# inv_prop = "not ("+inv_prop+")"
#
# if len(start_prop) == 0:
# start_prop = None
#
# BUILD QUERY
query = MCLSimpleQuery(start_prop, inv_prop, final_prop)
......@@ -233,7 +245,7 @@ def main(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file
# print("DEBUG:: " + str(lsol))
# print("DEBUG:: ", len( lsol))
# Dans le programme: minimal activation conditions
# minimal activation conditions
# on_cam function:
# cam_list = self.mcla.mac_search(query, self.max_step)
# if len(cam_list)==0 :
......@@ -280,37 +292,30 @@ def main(chart_file, cam_file, cam_step_file, cam_complete_file, cam_strong_file
return 1
def compute_macs(args):
"""Launch Cadbiom search of MACs (Minimal Activation Conditions)"""
if __name__ == "__main__":
# Limit recursion
import sys
import os.path
sys.setrecursionlimit(10000)
# EXPERIMENT PARAMS
MODEL_NAME = "mini_test_publi"
# MODEL_NAME = "pid_or_clock"
params = args_to_param(args)
# QUERY PARAMETERS
steps = 10
# final_prop = "CCR5"
final_prop = "P"
start_prop = None
inv_prop = None
# Todo beware with type of separators in path..
MODEL_NAME = params['chart_file'].split('/')[-1][:-4]
# FILES
CAM_FILE_PREFIX = RESULT_FOLDER + MODEL_NAME
# chart_file
chart_file = MODEL_FOLDER + MODEL_NAME + ".bcx"
CAM_FILE_PREFIX = params['output'] + MODEL_NAME + \
'_' + params['final_prop'] + '_cam'
# cam_file
cam_file = CAM_FILE_PREFIX + "_P_cam.txt"
cam_file = CAM_FILE_PREFIX + ".txt"
# cam_step_file
cam_step_file = CAM_FILE_PREFIX + "_P_cam_step.txt"
cam_step_file = CAM_FILE_PREFIX + "_step.txt"
# cam_complete_file
cam_complete_file = CAM_FILE_PREFIX + "_P_cam_complete.txt"
cam_complete_file = CAM_FILE_PREFIX + "_complete.txt"
# cam_strong_file
cam_strong_file = CAM_FILE_PREFIX + "_P_cam_strongA.txt"
cam_strong_file = CAM_FILE_PREFIX + "_strongA.txt"
# Reset files
def remove_file(file):
......@@ -326,11 +331,49 @@ if __name__ == "__main__":
# MAC research
main2(
chart_file, # chart_file
cam_file, # cam_file
cam_step_file, # cam_step_file
cam_complete_file, # cam_complete_file
cam_strong_file, # cam_strong_file
steps, final_prop, start_prop, inv_prop
params['chart_file'], # chart_file
cam_file, # cam_file
cam_step_file, # cam_step_file
cam_complete_file, # cam_complete_file
cam_strong_file, # cam_strong_file
params['steps'], params['final_prop'],
params['start_prop'], params['inv_prop']
)
def args_to_param(args):
"""Return argparse namespace as a dict {variable name: value}"""
return {k: v for k, v in vars(args).items() if k != 'func'}
if __name__ == "__main__":
# parser configuration
parser = argparse.ArgumentParser(description=__doc__)
# Default log level: debug
parser.add_argument('-vv', '--verbose', nargs='?', default='debug')
# Subparsers
subparsers = parser.add_subparsers(title='subcommands')
# subparser: Compute macs
# steps = 10
# final_prop = "P"
# start_prop = None
# inv_prop = None
parser_input_file = subparsers.add_parser('compute_macs',
help=compute_macs.__doc__)
parser_input_file.add_argument('chart_file')
parser_input_file.add_argument('final_prop')
parser_input_file.add_argument('--steps', type=int, nargs='?', default=10)
parser_input_file.add_argument('--start_prop', nargs='?', default=None)
parser_input_file.add_argument('--inv_prop', nargs='?', default=None)
parser_input_file.add_argument('--output', nargs='?', default='result/')
parser_input_file.set_defaults(func=compute_macs)
# get program args and launch associated command
args = parser.parse_args()
# Set log level
cm._logger.setLevel(cm.LOG_LEVELS[vars(args)['verbose']])
# launch associated command
args.func(args)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment