def test_fizzled_3(self): # WF(Fizzled -> Completed(allow fizz parents)) == COMPLETED one = fw.Firework([], state="FIZZLED", fw_id=1) two = fw.Firework([], state="COMPLETED", fw_id=2, spec={"_allow_fizzled_parents": True}, parents=one) self.assertEqual(fw.Workflow([one, two]).state, "COMPLETED")
def test_fizzled_2(self): # WF(Fizzled -> Ready(allow fizz parents)) == RUNNING one = fw.Firework([], state="FIZZLED", fw_id=1) two = fw.Firework([], state="READY", fw_id=2, spec={"_allow_fizzled_parents": True}, parents=one) self.assertEqual(fw.Workflow([one, two]).state, "RUNNING")
def test_fizzled_2(self): # WF(Fizzled -> Ready(allow fizz parents)) == RUNNING one = fw.Firework([], state='FIZZLED', fw_id=1) two = fw.Firework([], state='READY', fw_id=2, spec={'_allow_fizzled_parents': True}, parents=one) self.assertEqual(fw.Workflow([one, two]).state, 'RUNNING')
def test_fizzled_4(self): # one child doesn't allow fizzled parents one = fw.Firework([], state="FIZZLED", fw_id=1) two = fw.Firework([], state="READY", fw_id=2, spec={"_allow_fizzled_parents": True}, parents=one) three = fw.Firework([], state="WAITING", fw_id=3, parents=one) self.assertEqual(fw.Workflow([one, two, three]).state, "FIZZLED")
def test_fizzled_4(self): # one child doesn't allow fizzled parents one = fw.Firework([], state='FIZZLED', fw_id=1) two = fw.Firework([], state='READY', fw_id=2, spec={'_allow_fizzled_parents': True}, parents=one) three = fw.Firework([], state='WAITING', fw_id=3, parents=one) self.assertEqual(fw.Workflow([one, two, three]).state, 'FIZZLED')
def test_fizzled_6(self): # deep fizzled fireworks, but still RUNNING one = fw.Firework([], state="FIZZLED", fw_id=1) two = fw.Firework([], state="FIZZLED", fw_id=2, spec={"_allow_fizzled_parents": True}, parents=one) three = fw.Firework([], state="READY", fw_id=3, spec={"_allow_fizzled_parents": True}, parents=two) self.assertEqual(fw.Workflow([one, two, three]).state, "RUNNING")
def make_detour(nparallel, previous): # make more simulations at higher pressures temperature = max(r[0] for r in previous) max_pressure = max(r[1] for r in previous) new_pressures = [max_pressure * 2, max_pressure * 4, max_pressure * 8] new_sims = [] new_pps = [] for P in new_presures: new_sims = [ make_Simfireworks(parent_fw=None, T=temperature, P=P, ncycles=None, wfname='Capacity', template=None, workdir=None) for P in new_pressures ] pp = make_PostProcess() new_me = fw.Firework( self.__class__(nparallel=nparallel, previous_results=previous), parents=new_pps, )
def Firstgen_PreGA_FW(template, pop, wf_name): """Variant of PreGA for the zeroth generation Parameters ---------- template : str path to the template for simulations pop : tuple of tuples description of the initial population wf_name : str unique key to refer to this workflow by Returns ------- firstgen_prega : fireworks.Firework Firework for the setup of GA """ stuff = utils.slurp_directory(template) return fw.Firework( [ # creates template InitTemplate(contents=stuff), # creates candidates and population InitPopulation(initial_population=pop), ], spec={ '_category': wf_name, }, name='Firstgen PreGA', )
def PreGA_FW(parent, idx, bounds, wf_name): """Operations to set up candidates Parameters ---------- parent : fw.Firework ref to previous FW idx : int index of which generation of GA this is bounds : tuple tuple containing the minimum and maximum bounds for each parameter eg `((1.0, 2.0), (10.0, 20.0))` clamps the first value between 1.0 and 2.0 wf_name : str unique key to refer to this workflow by Returns ------- prega : fireworks.Firework """ settings = VaryCandidates.default_params.copy() settings['bounds'] = bounds return fw.Firework( [ Tournament(), VaryCandidates(**settings), PassAlong(keys=['template', 'parents']), ], spec={ '_category': wf_name, }, parents=parent, name='PreGA G={}'.format(idx), )
def PostSim_FW(generation_id, candidate_id, parents, wf_name): """Collects Sims from different conditions in one candidate fitness Parameters ---------- generation_id : int id of the generation candidate_id : int id of this candidate parents : list of fw.Firework references to the preceeding Fireworks for this candidate wf_name : str unique key to refer to this workflow by Returns ------- postsim : fireworks.Firework """ return fw.Firework( [ IsothermCreate(), AssignFitness(candidate_id=candidate_id), ], spec={ '_category': wf_name, }, parents=parents, name='PostSim G={} C={}'.format(generation_id, candidate_id), )
def InitTempFW(sample_input): firework = fw.Firework(gcwf.firetasks.InitTemplate( contents=gcwf.utils.slurp_directory('template')), spec={ "workdir": ".", "name": "Template init test" }) return firework
def Sim_FW(temperature, pressure, ref, generation_id, candidate_id, ff_updater, parent, wf_name): """Generate a single simulation Firework Parameters ---------- temperature : int temperature pressure : int pressure ref : float desired result for this T & P generation_id : int id of the generation candidate_id : int which candidate this simulation refers to ff_updater : function function which does the manipulation of forcefield files parent : fw.Firework the preceeding Firework to this Firework wf_name : str unique key to refer to this workflow by Returns ------- sim : fireworks.Firework """ # convert python function to pickle form ff_updater = utils.pickle_func(ff_updater) return fw.Firework( [ CopyTemplate( temperature=temperature, pressure=pressure, fmt='raspa', parallel_id=generation_id, ), ManipulateForcefield( candidate_id=candidate_id, updater=ff_updater, ), RunSimulation(fmt='raspa'), EvaluateResult( reference=ref, fmt='raspa', temperature=temperature, pressure=pressure, ), ], spec={ '_category': wf_name, }, parents=parent, name='Sim T={} P={} C={}'.format(temperature, pressure, candidate_id), )
def analysis_task(successful_raspa, launchpad): # run analysis on a successful raspa simulation firework = fw.Firework( [ gcwf.firetasks.AnalyseSimulation(fmt='raspa', parallel_id=1), TellTale() ], spec={'simtree': os.path.abspath(successful_raspa)}, ) launchpad(fw.Workflow([firework])) yield successful_raspa
def _submit_task(self, task_spec: Dict[str, Any]) -> Tuple[Hashable, Any]: import fireworks kwargs = task_spec["spec"]["kwargs"] kwargs["return_dict"] = True fw = fireworks.Firework(fireworks.PyTask( func=task_spec["spec"]["function"], args=task_spec["spec"]["args"], kwargs=kwargs, stored_data_varname="fw_results"), spec={"_launch_dir": "/tmp/"}) launches = self.client.add_wf(fw) return list(launches.values())[0], task_spec["id"]
def copytemplate(sample_input, launchpad): cp1 = fw.Firework(gcwf.firetasks.CopyTemplate(temperature=10, pressure=20, ncycles=1234, parallel_id=1, fmt='raspa'), spec={ 'template': os.path.join(sample_input, 'template'), }) wf = fw.Workflow([cp1]) launchpad(wf) print(os.listdir()) return glob.glob('sim_*')[0]
def analysis_task_with_previous(successful_raspa, launchpad): # run analysis on a successful raspa simulation firework = fw.Firework( [ gcwf.firetasks.AnalyseSimulation( fmt='raspa', parallel_id=1, previous_results='0,123\n673,456\n', ), TellTale() ], spec={'simtree': os.path.abspath(successful_raspa)}, ) launchpad(fw.Workflow([firework])) yield successful_raspa
def bulk_relaxation( self, atoms, parameters, spec=None): """Run a relaxation of a given DB entry or atoms object. If a database object is used, the calculation will automatically store the keys and data for later retrieval. The entries uuid will also be stored and `data.calculator_parameters` will be used as the calculation parameters. Parameters ---------- images : Atoms object Initial atoms to perform workflow on. parameters : dict Calculation parameters to use. workflow_name : str Name of the fireworks calculation to be used. spec : dict Additional fireworks specifications to pass to the database. """ atoms.info['calculator_parameters'] = parameters encoding = fwio.atoms_to_encode(atoms) t0 = fireworks.PyTask( func='catkit.flow.fwio.encode_to_atoms', args=[encoding]) t1 = fireworks.PyTask( func='catkit.flow.fwase.catflow_relaxation', stored_data_varname='trajectory') tasks = [t0, t1] if spec is None: spec = {} firework = fireworks.Firework(tasks, spec=spec) workflow = fireworks.Workflow([firework], name='bulk_relaxation') workflow_id = self.launchpad.add_wf(workflow)[-1] return workflow_id
def __new__(cls, command, **kwargs): bsub_options_dict = {} spec = None name = None for key in [ 'queue', 'resources', 'walltime', 'est_wait_time', 'processors' ]: if key in kwargs: bsub_options_dict[key] = kwargs[key] spec = {} if len(bsub_options_dict.keys()) > 0: spec['_queueadapter'] = bsub_options_dict # spec['_dupefinder']={"_fw_name" : "DupeFinderScript"} if 'name' in kwargs: name = kwargs['name'] return fireworks.Firework(fireworks.ScriptTask.from_str(command), name=name, spec=spec)
def submit_tasks(self, tasks): ret = [] for task in tasks: tag = task["id"] fw = fireworks.Firework(fireworks.PyTask( func=task["spec"]["function"], args=task["spec"]["args"], kwargs=task["spec"]["kwargs"], stored_data_varname="fw_results"), spec={"_launch_dir": "/tmp/"}) launches = self.lpad.add_wf(fw) self.queue[list(launches.values())[0]] = (tag, task["parser"], task["hooks"]) ret.append(tag) return ret
def test_already_existing(sample_input, launchpad, template_contents): """Check that CopyTemplate correctly overwrites an existing Simulation""" T = 290.0 P = 100.0 gen = 1 pid = 2 # make something in the way newdir = gcwf.utils.gen_sim_path(T, P, gen, pid) os.makedirs(newdir) with open(os.path.join(newdir, 'thing.txt'), 'w') as out: out.write('hello!\n') # make and run CopyTemplate cp = fw.Firework( [ gcwf.firetasks.CopyTemplate( temperature=T, pressure=P, parallel_id=pid, fmt='raspa', workdir=os.path.abspath('.'), ) ], spec={ 'template': os.path.abspath('template'), }, ) launchpad(cp) newdir2 = gcwf.utils.gen_sim_path(T, P, gen + 1, pid) assert os.path.exists(newdir) assert os.path.exists(newdir2) assert os.path.exists(os.path.join(newdir, 'thing.txt')) for fn in template_contents: assert os.path.exists(os.path.join(newdir2, fn))
def PostGA_FW(generation_id, parents, wf_name): """Operations to finish the GA generation Parameters ---------- generation_id : int id of the generation parents : list of fw.Firework references to PostSim Fireworks wf_name : str unique key to refer to this workflow by Returns ------- postga : fireworks.Firework """ return fw.Firework( [Replacement(), PassAlong(keys=['template'])], spec={ '_category': wf_name, }, parents=parents, name='PostGA G={}'.format(generation_id), )
def test_archived(self): one = fw.Firework([], state="ARCHIVED", fw_id=1) two = fw.Firework([], state="ARCHIVED", fw_id=2) self.assertEqual(fw.Workflow([one, two]).state, "ARCHIVED")
def submit_relaxation( self, image, workflow_name, parameters=None, spec=None): """Run a relaxation of a given DB entry or atoms object. If a database object is used, the calculation will automatically store the keys and data for later retrieval. The entries uuid will also be stored and `data.calculator_parameters` will be used as the calculation parameters. Parameters ---------- images : Atoms object | AtomsRow object ASE database entry or atoms object to relax. workflow_name : str Name of the fireworks calculation to be used. parameters : dict Calculation parameters to use. Will be pulled from a database entry `data.calculator_parameters`. spec : dict Additional fireworks specifications to pass to the database. """ keys, data = {}, {} if isinstance(image, AtomsRow): atoms = image.toatoms() keys.update(image.key_value_pairs) keys.update({'uuid': image.unique_id}) data.update(image.data) else: atoms = image if parameters is None: if data.get('calculator_parameters'): parameters = data.get('calculator_parameters') del data['calculator_parameters'] elif atoms.info.get('calculator_parameters'): parameters = atoms.info.get('calculator_parameters') else: raise ValueError('Calculation parameters missing.') calculator = parameters.pop('calculator_name', None) if calculator is None: raise ValueError("'calculator_name' missing from parameters.") atoms.info['calculator_parameters'] = parameters for k, v in data.items(): if isinstance(v, np.ndarray): fwio.array_to_list(v) data[k] = v encoding = fwio.atoms_to_encode(atoms) t0 = fireworks.PyTask( func='catkit.flow.fwio.encode_to_atoms', args=[encoding]) t1 = fireworks.PyTask( func='catkit.flow.fwase.get_potential_energy', args=[calculator], stored_data_varname='trajectory') tasks = [t0, t1] if spec is None: spec = {'keys': keys, 'data': data} else: spec.update({'keys': keys, 'data': data}) firework = fireworks.Firework(tasks, spec=spec) workflow = fireworks.Workflow([firework], name=workflow_name) self.launchpad.add_wf(workflow)
def run_raspa(short_raspa, launchpad): job = fw.Firework([gcwf.firetasks.RunSimulation(fmt='raspa')], spec={'simtree': short_raspa}) launchpad(fw.Workflow([job]))
def test_paused(self): # any paused == paused one = fw.Firework([], state="COMPLETED", fw_id=1) two = fw.Firework([], state="PAUSED", fw_id=2) self.assertEqual(fw.Workflow([one, two]).state, "PAUSED")
def test_fizzled_1(self): # WF(Fizzled -> Waiting(no fizz parents)) == FIZZLED one = fw.Firework([], state="FIZZLED", fw_id=1) two = fw.Firework([], state="WAITING", fw_id=2, parents=one) self.assertEqual(fw.Workflow([one, two]).state, "FIZZLED")
def test_completed(self): # all leaves complete one = fw.Firework([], state="COMPLETED", fw_id=1) two = fw.Firework([], state="COMPLETED", fw_id=2) self.assertEqual(fw.Workflow([one, two]).state, "COMPLETED")
def make_packing_workflow(spec, simple=True): """Create an entire Isotherm creation Workflow Parameters ---------- spec : dict has all the information for workflow simple : bool, optional use decorrelation analysis to determine if to run more sims Returns ------- workflow : fw.Workflow Workflow object ready to submit to LaunchPad """ temperatures = spec['temperatures'] pressures = spec['pressures'] nparallel = spec['nparallel'] ncycles = spec['ncycles'] template = spec['template'] workdir = spec['workdir'] wfname = spec['name'] if not isinstance(template, dict): dict_template = False # Passed path to template # if passed path to template, slurp it up # old method of slurping up directory stuff = utils.slurp_directory(template) else: dict_template = True # Else passed dict of stuff stuff = template simfmt = utils.guess_format(stuff) stuff = utils.escape_template(stuff) if dict_template: init = fw.Firework(firetasks.InitTemplate(contents=stuff, workdir=workdir), spec={'_category': wfname}, name='Template Init') setup = [init] else: init = None setup = [] simulations = [] # list of simulation fireworks post_processing = [] # list of post processing fireworks for T, P in itertools.product(temperatures, pressures): this_condition = make_Simfireworks( parent_fw=init, T=T, P=P, ncycles=ncycles, nparallel=nparallel, simfmt=simfmt, wfname=wfname, template=template, workdir=workdir, ) this_condition_PP = make_PostProcess( parent_fw=this_condition, T=T, P=P, wfname=wfname, simple=simple, ) simulations.extend(this_condition) post_processing.append(this_condition_PP) flat_decide = fw.Firework(CapacityDecider(), ) iso_create = fw.Firework(firetasks.IsothermCreate(workdir=workdir), parents=post_processing, spec={'_category': wfname}, name='Isotherm create') wf = fw.Workflow( setup + simulations + post_processing + [iso_create], name=wfname, metadata={'GCMCWorkflow': True}, # tag as GCMCWorkflow workflow ) return wf
def test_fizzled_5(self): # leaf is fizzled, wf is fizzled one = fw.Firework([], state="COMPLETED", fw_id=1) two = fw.Firework([], state="FIZZLED", fw_id=2, parents=one) self.assertEqual(fw.Workflow([one, two]).state, "FIZZLED")
def test_running_1(self): one = fw.Firework([], state="COMPLETED", fw_id=1) two = fw.Firework([], state="READY", fw_id=2, parents=one) self.assertEqual(fw.Workflow([one, two]).state, "RUNNING")