def run_calculation(job_profile, params, sections, output_type='db'): """Given an :class:`openquake.db.models.OqJobProfile` object, create a new :class:`openquake.db.models.OqCalculation` object and run the calculation. NOTE: The params and sections parameters are temporary but will be required until we can run calculations purely using Django model objects as calculator input. Returns the calculation object when the calculation concludes. :param job_profile: :class:`openquake.db.models.OqJobProfile` instance. :param params: A dictionary of config parameters parsed from the calculation config file. :param sections: A list of sections parsed from the calculation config file. :param output_type: 'db' or 'xml' (defaults to 'db') :returns: :class:`openquake.db.models.OqCalculation` instance. """ if not output_type in ('db', 'xml'): raise RuntimeError("output_type must be 'db' or 'xml'") calculation = OqCalculation(owner=job_profile.owner) calculation.oq_job_profile = job_profile calculation.status = 'running' calculation.save() # Clear any counters for this calculation_id, prior to running the # calculation. # We do this just to make sure all of the counters behave properly and can # provide accurate data about a calculation in-progress. stats.delete_job_counters(calculation.id) # Make the job/calculation ID generally available. utils_config.Config().job_id = calculation.id serialize_results_to = ['db'] if output_type == 'xml': serialize_results_to.append('xml') calc_proxy = CalculationProxy(params, calculation.id, sections=sections, serialize_results_to=serialize_results_to, oq_job_profile=job_profile, oq_calculation=calculation) # closing all db connections to make sure they're not shared between # supervisor and job executor processes. otherwise if one of them closes # the connection it immediately becomes unavailable for other close_connection() calc_pid = os.fork() if not calc_pid: # calculation executor process try: logs.init_logs_amqp_send(level=FLAGS.debug, job_id=calculation.id) _launch_calculation(calc_proxy, sections) except Exception, ex: logs.LOG.critical("Calculation failed with exception: '%s'" % str(ex)) calculation.status = 'failed' calculation.save() raise else: calculation.status = 'succeeded' calculation.save() return