Skip to content
Snippets Groups Projects
Commit 3662b976 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

WIP

parent 059a7b69
Branches
Tags
2 merge requests!39Release 0.4.0,!20created draft for generic analysis method
Pipeline #16471 failed
#!/usr/bin/env python3
# encoding: utf-8
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2021 Indiscale GmbH <info@indiscale.com>
# Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
"""
module description
"""
import sys
import caosdb as db
def main():
# TODO remove fixed path
script = db.File(
file="../src/caosadvancedtools/serverside/examples/example_script.py",
path="Analysis/scripts/example_script.py",
)
try:
script.insert()
except:
script = db.execute_query(
"FIND FILE which is stored at 'Analysis/scripts/example_script.py'",
unique=True)
da = db.Record()
da.add_parent("Analysis")
da.add_property("scripts", value=[script], datatype=db.LIST(db.FILE))
da.add_property("sources",
value=db.execute_query(
"FIND FILE which is stored at '**/timeseries.npy'",
unique=True),
# datatype=db.LIST(db.FILE)
)
da.add_property("date", "2020-01-01")
da.add_property("identifier", "TEST")
da.add_property("responsible", db.execute_query(
"FIND RECORD Person WITH firstname=Only",
unique=True))
da.insert()
if __name__ == "__main__":
sys.exit(main())
../src/caosadvancedtools/examples/example_script.py
\ No newline at end of file
No preview for this file type
...@@ -51,6 +51,9 @@ Analysis: ...@@ -51,6 +51,9 @@ Analysis:
date: date:
identifier: identifier:
responsible: responsible:
suggested_properties:
mean_value:
datatype: DOUBLE
Publication: Publication:
Thesis: Thesis:
inherit_from_suggested: inherit_from_suggested:
......
...@@ -65,6 +65,10 @@ python3 test_table.py ...@@ -65,6 +65,10 @@ python3 test_table.py
# TODO the following test deletes lots of the data inserted by the crawler # TODO the following test deletes lots of the data inserted by the crawler
echo "Testing im and export" echo "Testing im and export"
python3 test_im_und_export.py python3 test_im_und_export.py
# automated analysis
python3 create_analysis.py
# Better safe than sorry: # Better safe than sorry:
python3 clear_database.py python3 clear_database.py
......
#!/usr/bin/env python3
# encoding: utf-8
#
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (C) 2021 Indiscale GmbH <info@indiscale.com>
# Copyright (C) 2021 Henrik tom Wörden <h.tomwoerden@indiscale.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ** end header
#
"""
module description
"""
import sys
import caosdb as db
from caosadvancedtools.serverside.generic_analysis import run
def main():
da = db.execute_query("FIND Analysis with identifier=TEST", unique=True)
run(da)
if __name__ == "__main__":
sys.exit(main())
...@@ -32,14 +32,19 @@ import argparse ...@@ -32,14 +32,19 @@ import argparse
import logging import logging
import sys import sys
from argparse import RawTextHelpFormatter from argparse import RawTextHelpFormatter
from datetime import datetime
import caosdb as db import caosdb as db
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from caosadvancedtools.cfood import assure_property_is from caosadvancedtools.cfood import assure_property_is
from caosadvancedtools.guard import INSERT, UPDATE
from caosadvancedtools.guard import global_guard as guard
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
guard.set_level(level=UPDATE)
def main(args): def main(args):
# TODO (maybe) can these checks be replaced by a more declaritive appoach? # TODO (maybe) can these checks be replaced by a more declaritive appoach?
...@@ -51,32 +56,37 @@ def main(args): ...@@ -51,32 +56,37 @@ def main(args):
)) ))
# The script may require certain information to exist. Here, we expect that # The script may require certain information to exist. Here, we expect that
# a InputDataSet Property exists that references a numpy file. # a sources Property exists that references a numpy file.
# Similarly an InputDataSet could be used.
if (dataAnalysisRecord.get_property("InputDataSet") is None if (dataAnalysisRecord.get_property("sources") is None
or db.apiutils.is_reference( or not db.apiutils.is_reference(
dataAnalysisRecord.get_property("InputDataSet"))): dataAnalysisRecord.get_property("sources"))):
raise RuntimeError("InputDataSet Refenrence must exist.") raise RuntimeError("sources Refenrence must exist.")
# ####### this core might be replaced by a call to another script ####### # # ####### this core might be replaced by a call to another script ####### #
# Download the data # Download the data
source_val = dataAnalysisRecord.get_property("sources").value
npobj = db.File( npobj = db.File(
id=dataAnalysisRecord.get_property("InputDataSet")).retrieve() id=(source_val[0]
if isinstance(source_val, list)
else source_val)).retrieve()
npfile = npobj.download() npfile = npobj.download()
data = np.load(npfile) data = np.load(npfile)
# Plot data # Plot data
filename = "hist.png" filename = "hist.png"
plt.hist(data) plt.hist(data)
plt.savefig() plt.savefig(filename)
mean = data.mean() mean = data.mean()
# ####################################################################### # # ####################################################################### #
# Insert the result plot # Insert the result plot
# TODO (must): how do we find a good file path?? # TODO (must): how do we find a good file path??
fig = db.File(file=filename, path="/uploaded/something/"+filename) fig = db.File(file=filename,
path="/uploaded/something3/"+str(datetime.now())+filename)
fig.insert() fig.insert()
# Add the result to the analysis Record # Add the result to the analysis Record
...@@ -92,7 +102,7 @@ def main(args): ...@@ -92,7 +102,7 @@ def main(args):
# be different.... Compare checksums of files? # be different.... Compare checksums of files?
assure_property_is( assure_property_is(
dataAnalysisRecord, dataAnalysisRecord,
"result", "results",
fig.id, fig.id,
) )
# TODO (must) what should be done with the old file? Removed if not referenced? # TODO (must) what should be done with the old file? Removed if not referenced?
......
...@@ -111,15 +111,15 @@ def check_referenced_script(record: db.Record): ...@@ -111,15 +111,15 @@ def check_referenced_script(record: db.Record):
script_prop = record.get_property("scripts") script_prop = record.get_property("scripts")
if (not db.apiutils.is_reference(script_prop) or if not db.apiutils.is_reference(script_prop):
not isinstance(script_prop.value, int)):
logger.warning("The 'scripts' Property of the following Record should " logger.warning("The 'scripts' Property of the following Record should "
"reference a File:\n{}".format(str(record))) "reference a File:\n{}".format(str(record)))
return return
script = db.execute_query("FIND ENTITY WITH id={}".format( script = db.execute_query("FIND ENTITY WITH id={}".format(
script_prop.value), unique=True) script_prop.value[0] if isinstance(script_prop.value, list)
else script_prop.value), unique=True)
if (not isinstance(script, db.File)): if (not isinstance(script, db.File)):
logger.warning("The 'scripts' Property of the Record {} should " logger.warning("The 'scripts' Property of the Record {} should "
...@@ -140,10 +140,14 @@ def call_script(script_name, record_id): ...@@ -140,10 +140,14 @@ def call_script(script_name, record_id):
return return
ret = subprocess.run([script_name, record_id], stdout=subprocess.PIPE, cmd = ["./"+script_name, str(record_id)]
stderr=subprocess.PIPE) print("Running: "+" ".join(cmd))
logger.debug("Running: "+" ".join(cmd))
ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(ret.stdout.decode())
print(ret.stderr.decode())
if ret.returnvalue != 0: if ret.returncode != 0:
logger.warning("Skript failed") logger.warning("Skript failed")
...@@ -184,11 +188,9 @@ def _parse_arguments(): ...@@ -184,11 +188,9 @@ def _parse_arguments():
"""Parses the command line arguments. """Parses the command line arguments.
""" """
parser = argparse.ArgumentParser(description='__doc__') parser = argparse.ArgumentParser(description='__doc__')
parser.add_argument("--entity", help="An id an input dataset.") parser.add_argument("--module", help="An id an input dataset.")
parser.add_argument("--entity", help="An id of a parameter record.") parser.add_argument("--inputset", help="An id an input dataset.")
parser.add_argument( parser.add_argument("--parameterset", help="An id of a parameter record.")
'-a', '--auth-token', required=False,
help="An authentication token (not needed, only for compatibility).")
return parser.parse_args() return parser.parse_args()
...@@ -199,9 +201,11 @@ def main(): ...@@ -199,9 +201,11 @@ def main():
dataAnalysisRecord = db.Record() dataAnalysisRecord = db.Record()
dataAnalysisRecord.add_property(name="InputDataSet", value=args.entity) dataAnalysisRecord.add_property(name="InputDataSet", value=args.entity)
dataAnalysisRecord.add_property(name="ParameterSet", value=args.parameter) dataAnalysisRecord.add_property(name="ParameterSet", value=args.parameter)
dataAnalysisRecord.add_property(name="Software", value=args.module)
# TODO: should this be done? # TODO: should this be done?
dataAnalysisRecord.insert() dataAnalysisRecord.insert()
run(dataAnalysisRecord)
if __name__ == "__main__": if __name__ == "__main__":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment