<commit_before>"""
The records module defines the Record class, which gathers and stores
information about an individual simulation or analysis run.

Classes
-------

Record - gathers and stores information about an individual simulation or
         analysis run.
         Can be instantiated directly, but more usually created by the
         new_record() method of Project.
"""

from datetime import datetime
import time
import os
import re
import getpass
from operator import or_
from formatting import get_formatter
import dependency_finder

def assert_equal(a, b, msg=''):
    assert a == b, "%s: %s %s != %s %s" % (msg, a, type(a), b, type(b))

class Record(object):
    
    def __init__(self, executable, repository, main_file, version, parameters,
                 launch_mode, datastore, label=None, reason=None, diff='',
                 user='', on_changed='error'):
        self.timestamp = datetime.now() # might need to allow for this to be set as argument to allow for distributed/batch simulations on machines with out-of-sync clocks
        self.label = label or self.timestamp.strftime("%Y%m%d-%H%M%S")
        assert len(self.label) > 0
        self.reason = reason
        self.duration = None
        self.executable = executable # an Executable object incorporating path, version, maybe system information
        self.repository = repository # a Repository object
        self.main_file = main_file
        self.version = version
        self.parameters = parameters # a ParameterSet object
        self.launch_mode = launch_mode # a LaunchMode object - basically, run serially or with MPI. If MPI, what configuration
        self.datastore = datastore.copy()
        self.outcome = None
        self.data_key = None
        self.tags = set()
        self.diff = diff
        self.user = user
        self.on_changed = on_changed  
    
    def register(self):
        """Record information about the environment."""
        # Check the code hasn't changed and the version is correct
        if len(self.diff) == 0:
            assert not self.repository.working_copy.has_changed()
        assert_equal(self.repository.working_copy.current_version(), self.version, "version")
        # Record dependencies
        self.dependencies = dependency_finder.find_dependencies(self.main_file, self.executable, self.on_changed)
        # Record platform information
        self.platforms = self.launch_mode.get_platform_information()
    
    def run(self, with_label=False):
        """
        Launch the simulation or analysis.
        
        with_label - adds the record label either to the parameter file
                     (with_label="parameters") or to the end of the command
                     line (with_label="cmdline"), and appends the label to the
                     datastore root. This allows the program being run to
                     create files in a directory specific to this run.
        """
        data_label = None
        if with_label:
            if with_label == 'parameters':
                self.parameters.update({"sumatra_label": self.label})
            elif with_label == 'cmdline':
                data_label = self.label
            else:
                raise Exception("with_label must be either 'parameters' or 'cmdline'")
            self.datastore.root  = os.path.join(self.datastore.root, self.label)
        print "datastore.root = ", self.datastore.root
        # run pre-simulation/analysis tasks, e.g. nrnivmodl
        self.launch_mode.pre_run(self.executable)
        # Write the executable-specific parameter file
        parameter_file = "%s.param" % self.label.replace("/", "_")
        self.executable.write_parameters(self.parameters, parameter_file)
        # Run simulation/analysis
        start_time = time.time()
        result = self.launch_mode.run(self.executable, self.main_file, parameter_file, data_label)
        self.duration = time.time() - start_time
        # Run post-processing scripts
        pass # skip this if there is an error
        # Search for newly-created datafiles
        self.data_key = self.datastore.find_new_files(self.timestamp)
        print "Data key is", self.data_key
        if os.path.exists(parameter_file):
            os.remove(parameter_file)
    
    def describe(self, format='text', mode='long'):
        formatter = get_formatter(format)([self])
        return formatter.format(mode)<commit_msg>The temporary parameter file should be deleted before `find_new_files()`<commit_after>"""
The records module defines the Record class, which gathers and stores
information about an individual simulation or analysis run.

Classes
-------

Record - gathers and stores information about an individual simulation or
         analysis run.
         Can be instantiated directly, but more usually created by the
         new_record() method of Project.
"""

from datetime import datetime
import time
import os
import re
import getpass
from operator import or_
from formatting import get_formatter
import dependency_finder

def assert_equal(a, b, msg=''):
    assert a == b, "%s: %s %s != %s %s" % (msg, a, type(a), b, type(b))

class Record(object):
    
    def __init__(self, executable, repository, main_file, version, parameters,
                 launch_mode, datastore, label=None, reason=None, diff='',
                 user='', on_changed='error'):
        self.timestamp = datetime.now() # might need to allow for this to be set as argument to allow for distributed/batch simulations on machines with out-of-sync clocks
        self.label = label or self.timestamp.strftime("%Y%m%d-%H%M%S")
        assert len(self.label) > 0
        self.reason = reason
        self.duration = None
        self.executable = executable # an Executable object incorporating path, version, maybe system information
        self.repository = repository # a Repository object
        self.main_file = main_file
        self.version = version
        self.parameters = parameters # a ParameterSet object
        self.launch_mode = launch_mode # a LaunchMode object - basically, run serially or with MPI. If MPI, what configuration
        self.datastore = datastore.copy()
        self.outcome = None
        self.data_key = None
        self.tags = set()
        self.diff = diff
        self.user = user
        self.on_changed = on_changed  
    
    def register(self):
        """Record information about the environment."""
        # Check the code hasn't changed and the version is correct
        if len(self.diff) == 0:
            assert not self.repository.working_copy.has_changed()
        assert_equal(self.repository.working_copy.current_version(), self.version, "version")
        # Record dependencies
        self.dependencies = dependency_finder.find_dependencies(self.main_file, self.executable, self.on_changed)
        # Record platform information
        self.platforms = self.launch_mode.get_platform_information()
    
    def run(self, with_label=False):
        """
        Launch the simulation or analysis.
        
        with_label - adds the record label either to the parameter file
                     (with_label="parameters") or to the end of the command
                     line (with_label="cmdline"), and appends the label to the
                     datastore root. This allows the program being run to
                     create files in a directory specific to this run.
        """
        data_label = None
        if with_label:
            if with_label == 'parameters':
                self.parameters.update({"sumatra_label": self.label})
            elif with_label == 'cmdline':
                data_label = self.label
            else:
                raise Exception("with_label must be either 'parameters' or 'cmdline'")
            self.datastore.root  = os.path.join(self.datastore.root, self.label)
        print "datastore.root = ", self.datastore.root
        # run pre-simulation/analysis tasks, e.g. nrnivmodl
        self.launch_mode.pre_run(self.executable)
        # Write the executable-specific parameter file
        parameter_file = "%s.param" % self.label.replace("/", "_")
        self.executable.write_parameters(self.parameters, parameter_file)
        # Run simulation/analysis
        start_time = time.time()
        result = self.launch_mode.run(self.executable, self.main_file, parameter_file, data_label)
        self.duration = time.time() - start_time
        # Run post-processing scripts
        pass # skip this if there is an error
        # Search for newly-created datafiles
        if os.path.exists(parameter_file):
            os.remove(parameter_file)
        self.data_key = self.datastore.find_new_files(self.timestamp)
        print "Data key is", self.data_key
        
    
    def describe(self, format='text', mode='long'):
        formatter = get_formatter(format)([self])
        return formatter.format(mode)
{'fraction_non_alphanumeric': 0.08789237668161436, 'fraction_numerical': 0.0004484304932735426, 'mean_word_length': 2.5149724192277385, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2171339', 'n_tokens_mistral': 2368, 'n_tokens_neox': 2303, 'n_words': 745}