예제 #1
0
    def get_simulation_csv(self, simulation):
        user = self.getCurrentUser()
        simulation_model = Simulation()
        summary_stats = simulation_model.get_summary_stats(simulation, user)

        # The values of summary stats will typically be nested dicts, now we flatten them
        summary_stats = {
            time: flatten_dict(data)
            for time, data in summary_stats.items()
        }
        # move it to a list and sort by time
        summary_stats = [(time, data) for time, data in summary_stats.items()]
        summary_stats.sort(key=lambda x: float(x[0]))

        # write a csv to memory
        with io.StringIO() as sio:
            csvwriter = csv.writer(sio, dialect='excel')
            if len(summary_stats) > 0:
                # header
                csvwriter.writerow(
                    ["time", *[label for label, value in summary_stats[0][1]]])

                for time, data in summary_stats:
                    csvwriter.writerow(
                        [time, *[value for label, value in data]])

            rest.setResponseHeader('Content-Type', 'text/csv')
            return sio.getvalue()
예제 #2
0
 def list_simulations(self,
                      limit,
                      offset,
                      sort,
                      includeArchived,
                      mine,
                      experiments,
                      creator=None,
                      config=None):
     user = self.getCurrentUser()
     simulation_model = Simulation()
     if mine and user is None:
         return []
     if mine and creator and creator['_id'] != user['_id']:
         return []
     if mine:
         creator = user
     return simulation_model.list(
         includeArchived=includeArchived,
         user=user,
         limit=limit,
         offset=offset,
         sort=sort,
         creator=creator,
         config=config,
         in_experiment=experiments,
     )
예제 #3
0
파일: api.py 프로젝트: knappa/girder-nlisim
    def execute_simulation(self, name, config, folder=None):
        target_time = config.get('simulation', {}).get('run_time', 50)
        user, token = self.getCurrentUser(returnToken=True)
        folder_model = Folder()
        job_model = Job()

        if folder is None:
            folder = folder_model.findOne(
                {'parentId': user['_id'], 'name': 'Public', 'parentCollection': 'user'}
            )
            if folder is None:
                raise RestException('Could not find the user\'s "public" folder.')

        simulation_model = Simulation()
        simulation = simulation_model.createSimulation(
            folder,
            name,
            config,
            user,
            True,
        )
        girder_config = GirderConfig(
            api=GIRDER_API, token=str(token['_id']), folder=str(folder['_id'])
        )
        simulation_config = SimulationConfig(NLI_CONFIG_FILE, config)

        # TODO: This would be better stored as a dict, but it's easier once we change the
        #       config object format.
        simulation_config_file = StringIO()
        simulation_config.write(simulation_config_file)

        job = job_model.createJob(
            title='NLI Simulation',
            type=NLI_JOB_TYPE,
            kwargs={
                'girder_config': attr.asdict(girder_config),
                'simulation_config': simulation_config_file.getvalue(),
                'config': config,
                'simulation_id': simulation['_id'],
            },
            user=user,
        )

        simulation['nli']['job_id'] = job['_id']
        simulation_model.save(simulation)

        run_simulation.delay(
            name=name,
            girder_config=girder_config,
            simulation_config=simulation_config,
            target_time=target_time,
            job=job,
            simulation_id=simulation['_id'],
        )
        return job
예제 #4
0
 def cancel_experiment(self, experiment):
     simulation_model = Simulation()
     for simulation in simulation_model.childFolders(
             experiment['_id'], 'folder'):
         # TODO: I added the 'folder' so that the signature matches. This was my best guess;
         #  'folder', 'user', 'collection' are the available options.
         # noinspection PyBroadException
         try:
             self._cancel_simulation(simulation)
         except Exception:
             logger.exception(
                 f'Failed to cancel simulation "{simulation["_id"]}"')
예제 #5
0
def update_status(event):
    simulation_model = Simulation()
    job = event.info['job']
    if job['type'] != NLI_JOB_TYPE:
        return

    simulation_id = job['kwargs'].get('simulation_id')
    simulation = simulation_model.load(simulation_id, force=True)

    if simulation is None:
        logger.error(f'Could not find simulation for job {job["_id"]}')
        return

    progress = job['progress']
    simulation['nli']['progress'] = 100 * (progress['current'] /
                                           progress['total'])
    simulation['nli']['status'] = job['status']
    simulation_model.save(simulation)
예제 #6
0
def simulation_runner(
    *,
    config,
    parent_folder,
    job_model: Job,
    run_name,
    target_time,
    token,
    user,
    experiment=None,
):
    simulation_model = Simulation()
    simulation = simulation_model.createSimulation(
        parentFolder=parent_folder,
        name=run_name,
        config=config,
        creator=user,
        version=nlisim_version,
        public=True,
        experiment=experiment,
    )

    # if this is to be part of an experiment, let the experiment know about it
    if experiment is not None:
        experiment['nli']['component_simulations'].append(simulation['_id'])
        experiment['nli']['per_sim_progress'][str(simulation['_id'])] = 0.0
        experiment['nli']['per_sim_status'][str(
            simulation['_id'])] = JobStatus.INACTIVE
        experiment_model = Experiment()
        experiment_model.save(experiment)

    girder_config = GirderConfig(api=GIRDER_API,
                                 token=str(token['_id']),
                                 folder=str(parent_folder['_id']))
    simulation_config = SimulationConfig(NLI_CONFIG_FILE, config)
    # TODO: This would be better stored as a dict, but it's easier once we change the
    #       config object format.
    simulation_config_file = StringIO()
    simulation_config.write(simulation_config_file)
    job = job_model.createJob(
        title='NLI Simulation',
        type=NLI_JOB_TYPE,
        kwargs={
            'girder_config': attr.asdict(girder_config),
            'simulation_config': simulation_config_file.getvalue(),
            'config': config,
            'simulation_id': simulation['_id'],
            'in_experiment': (experiment is not None),
            'experiment_id': None if experiment is None else experiment['_id'],
        },
        user=user,
    )

    simulation['nli']['job_id'] = job['_id']
    simulation_model.save(simulation)
    run_simulation.delay(
        name=run_name,
        girder_config=girder_config,
        simulation_config=simulation_config,
        target_time=target_time,
        job=job,
        simulation_id=simulation['_id'],
    )
    return job, simulation
예제 #7
0
 def mark_simulation_archived(self, simulation, archived):
     simulation['nli']['archived'] = archived
     simulation_model = Simulation()
     return simulation_model.save(simulation)
예제 #8
0
 def mark_simulation_complete(self, simulation):
     simulation_model = Simulation()
     return simulation_model.setSimulationComplete(simulation)
예제 #9
0
 def get_simulation_json(self, simulation):
     user = self.getCurrentUser()
     simulation_model = Simulation()
     return simulation_model.get_summary_stats(simulation, user)
def update_status(event):
    simulation_model = Simulation()
    job = event.info['job']
    if job['type'] != NLI_JOB_TYPE:
        return

    simulation_id = job['kwargs'].get('simulation_id')
    simulation = simulation_model.load(simulation_id, force=True)

    if simulation is None:
        logger.error(f'Could not find simulation for job {job["_id"]}')
        return

    progress = job['progress']
    simulation['nli']['progress'] = 100 * (progress['current'] / progress['total'])
    simulation['nli']['status'] = job['status']
    simulation_model.save(simulation)

    # update the progress for the experiment, if this is part of one
    if job['kwargs'].get('in_experiment'):
        experiment_model = Experiment()
        experiment = experiment_model.load(job['kwargs'].get('experiment_id'), force=True)

        # update the individual progress
        experiment['nli']['per_sim_progress'][str(simulation_id)] = simulation['nli']['progress']
        per_sim_progress = experiment['nli']['per_sim_progress']

        # update the total progress (defining this as the mean progress)
        experiment['nli']['progress'] = sum(per_sim_progress.values()) / len(per_sim_progress)

        # update job status
        experiment['nli']['per_sim_status'][str(simulation_id)] = job['status']
        # any errors or cancellations count as an error or cancellation of the experiment,
        # experiment doesn't become active until all of the sims are active.
        if any(
            status == JobStatus.ERROR for status in experiment['nli']['per_sim_status'].values()
        ):
            experiment['nli']['status'] = JobStatus.ERROR
        elif any(
            status == JobStatus.CANCELED for status in experiment['nli']['per_sim_status'].values()
        ):
            experiment['nli']['status'] = JobStatus.CANCELED
        elif any(
            status == JobStatus.INACTIVE for status in experiment['nli']['per_sim_status'].values()
        ):
            experiment['nli']['status'] = JobStatus.INACTIVE
        else:
            # in this case, all statuses must be QUEUED, RUNNING, or SUCCESS
            # we take the "minimum" for the experiment's status.
            if any(
                status == JobStatus.QUEUED
                for status in experiment['nli']['per_sim_status'].values()
            ):
                experiment['nli']['status'] = JobStatus.QUEUED
            elif any(
                status == JobStatus.RUNNING
                for status in experiment['nli']['per_sim_status'].values()
            ):
                experiment['nli']['status'] = JobStatus.RUNNING
            else:
                experiment['nli']['status'] = JobStatus.SUCCESS

        experiment_model.save(experiment)