def compute_evaluate_wavepackets(iom, basis="eigen", blockid=0):
    """Evaluate an in homogeneous Hagdorn wavepacket on a given grid for each timestep.
    :param iom: An ``IOManager`` instance providing the simulation data.
    :param basis: The basis where the evaluation is done. Can be 'eigen' or 'canonical'.
    :param blockid: The data block from which the values are read.
    """
    parameters = iom.load_parameters()

    # Number of time steps we saved
    timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid)
    nrtimesteps = timesteps.shape[0]

    # Prepare the potential for basis transformations
    Potential = PotentialFactory().create_potential(parameters)

    # Retrieve simulation data
    if iom.has_grid(blockid=blockid):
        grid = iom.load_grid(blockid=blockid)
    else:
        grid = iom.load_grid(blockid="global")

    params = iom.load_inhomogwavepacket_parameters(blockid=blockid)
    coeffs = iom.load_inhomogwavepacket_coefficients(blockid=blockid)

    # A data transformation needed by API specification
    params = [ [ params[j][i,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps) ]
    coeffs = [ [ coeffs[i,j,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps) ]

    # We want to save wavefunctions, thus add a data slot to the data file
    iom.add_wavefunction(parameters, timeslots=nrtimesteps, blockid=blockid)

    # Hack for allowing data blocks with different basis size than the global one
    # todo: remove when we got local parameter sets
    parameters.update_parameters({"basis_size": coeffs[0][0].shape[0]})

    HAWP = HagedornWavepacketInhomogeneous(parameters)
    HAWP.set_quadrature(None)

    WF = WaveFunction(parameters)
    WF.set_grid(grid)

    # Iterate over all timesteps
    for i, step in enumerate(timesteps):
        print(" Evaluating inhomogeneous wavepacket at timestep "+str(step))

        # Configure the wavepacket
        HAWP.set_parameters(params[i])
        HAWP.set_coefficients(coeffs[i])

        # Project to the eigenbasis if desired
        if basis == "eigen":
            HAWP.project_to_eigen(Potential)

        # Evaluate the wavepacket
        values = HAWP.evaluate_at(grid, prefactor=True)
        WF.set_values(values)

        # Save the wave function
        iom.save_wavefunction(WF.get_values(), timestep=step, blockid=blockid)
def compute_norm(iom, blockid=0):
    """Compute the norm of a wavepacket timeseries.
    :param iom: An ``IOManager`` instance providing the simulation data.
    :param blockid: The data block from which the values are read.
    """
    parameters = iom.load_parameters()

    # Number of time steps we saved
    timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid)
    nrtimesteps = timesteps.shape[0]

    Potential = PotentialFactory().create_potential(parameters)

    # Retrieve simulation data
    params = iom.load_inhomogwavepacket_parameters(blockid=blockid)
    coeffs = iom.load_inhomogwavepacket_coefficients(blockid=blockid)

    # A data transformation needed by API specification
    params = [ [ params[j][i,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps) ]
    coeffs = [ [ coeffs[i,j,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps) ]

    # We want to save norms, thus add a data slot to the data file
    iom.add_norm(parameters, timeslots=nrtimesteps, blockid=blockid)

    # Hack for allowing data blocks with different basis size than the global one
    # todo: remove when we got local parameter sets
    parameters.update_parameters({"basis_size": coeffs[0][0].shape[0]})

    # Initialize a Hagedorn wavepacket with the data
    HAWP = HagedornWavepacketInhomogeneous(parameters)
    HAWP.set_quadrature(None)

    # Iterate over all timesteps
    for i, step in enumerate(timesteps):
        print(" Computing norms of timestep "+str(step))

        # Configure the wave packet and project to the eigenbasis.
        HAWP.set_parameters(params[i])
        HAWP.set_coefficients(coeffs[i])
        HAWP.project_to_eigen(Potential)

        # Measure norms in the eigenbasis
        norm = HAWP.get_norm()

        # Save the norms
        iom.save_norm(norm, timestep=step, blockid=blockid)
def plot_frames_inhomogeneous(iom, blockid=0, view=None):
    """
    :param iom: An ``IOManager`` instance providing the simulation data.
    """
    parameters = iom.load_parameters()

    # Number of time steps we saved
    timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid)
    nrtimesteps = timesteps.shape[0]

    # Initialize a Hagedorn wavepacket with the data
    Potential = PotentialFactory().create_potential(parameters)

    # Retrieve simulation data
    grid = iom.load_grid(blockid="global")
    params = iom.load_inhomogwavepacket_parameters(blockid=blockid)
    coeffs = iom.load_inhomogwavepacket_coefficients(blockid=blockid)

    # A data transformation needed by API specification
    params = [ [ params[j][i,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps)]
    coeffs = [ [ coeffs[i,j,:] for j in xrange(parameters["ncomponents"]) ] for i in xrange(nrtimesteps)]

    # Hack for allowing data blocks with different basis size than the global one
    # todo: remove when we got local parameter sets
    parameters.update_parameters({"basis_size": coeffs[0][0].shape[0]})

    HAWP = HagedornWavepacketInhomogeneous(parameters)
    HAWP.set_quadrature(None)

    # Iterate over all timesteps
    for i, step in enumerate(timesteps):
        print(" Plotting frame of timestep "+str(step))

        # Configure the wavepacket and project to the eigenbasis.
        HAWP.set_parameters(params[i])
        HAWP.set_coefficients(coeffs[i])
        HAWP.project_to_eigen(Potential)

        values = HAWP.evaluate_at(grid, prefactor=True)
        coeffi = HAWP.get_coefficients()

        plot_frame(step, parameters, grid, values, coeffi, index=blockid, view=view)

    print(" Plotting frames finished")