I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
Default Systems
Although the default empty Bundle doesn't include a system, there are available
constructors that create default systems.  To create a simple binary with component tags
'binary', 'primary', and 'secondary' (as above), you could call default_binary:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
Defining the Hierarchy
At this point all we've done is add a bunch of Parameters to our Bundle, but
we still need to specify the hierarchical setup of our system.
Here we want to place our two stars (with component tags 'primary' and 'secondary') in our
orbit (with component tag 'binary').  This can be done with several different syntaxes sent to b.set_hierarchy:
Can you write Python code for it?

b.set_hierarchy(phoebe.hierarchy.binaryorbit, b['binary'], b['primary'], b['secondary'])


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
For more details on dealing with contact binary systems, see the Contact Binary Hierarchy Tutorial and the Contact Binary Example Script.
Adding Components Manually
By default, an empty Bundle does not contain any information about our system.
So, let's first start by adding a few stars.  Here we'll call the generic add_component method.  This method works for any type of component in the system - stars, orbits, planets, disks, rings, spots, etc.  The first argument needs to be a callable or the name of a callable in phoebe.parameters.component which include the following options:

orbit
star
envelope

add_component also takes a keyword argument for the 'component' tag.  Here we'll give them component tags 'primary' and 'secondary' - but note that these are merely convenience labels and do not hold any special roles.  Some tags, however, are forbidden if they clash with other tags or reserved values - so if you get error stating the component tag is forbidden, try using a different string.
Can you write Python code for it?

b = phoebe.Bundle()

b.add_component(phoebe.component.star, component='primary')
b.add_component('star', component='secondary')


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
Here we call the add_component method of the bundle with several arguments:

a function (or the name of a function) in phoebe.parameters.component.  This
  function tells the bundle what parameters need to be added.
component: the tag that we want to give this component for future reference.
any additional keyword arguments: you can also provide initial values for Parameters
  that you know will be created.  In the last example you can see that the
  effective temperature will already be set to 6000 (in default units which is K).

and then we'll do the same to add an orbit:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
If at any point we want to flip the primary and secondary components or make
this binary a triple, its seriously as easy as changing this hierarchy and
everything else will adjust as needed (including cross-ParameterSet constraints,
and datasets)
The Hierarchy Parameter
Setting the hierarchy just sets the value of a single parameter (although it may take some time because it also does a lot of paperwork and manages constraints between components in the system).  You can access that parameter as usual:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
If you access the value that this set via get_hierarchy, you'll see that it really just resulted
in a simple string representation:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
Or you can ask for the component tag of the top-level item in the hierarchy via get_top.
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
This HierarchyParameter then has several methods unique to itself.  You can, for instance, list the component tags of all the stars or orbits in the hierarchy via get_stars or get_orbits, respectively:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
To build the same binary but as a contact system, you would call:
Can you write Python code for it?

b = phoebe.default_binary(contact_binary=True)

print(b.hierarchy)


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
We could just as easily have used this string to set the hierarchy:
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
or
Can you write Python code for it?


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
or for short:
Can you write Python code for it?

b = phoebe.default_binary()

print(b.hierarchy)


I am working on the file "2.2/tutorials/building_a_system.ipynb".
The first task is:
or through any of these shortcuts:
Can you write Python code for it?


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
Accessing Synthetics from Models
The synthetics can be accessed by their dataset and model tags.
Can you write Python code for it?

b['run_with_incl_90']

b['primary@run_with_incl_90']

b['us@primary@run_with_incl_90']


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
Adding Compute Options
In other cases, we may want to manually add additional sets of compute options.
This syntax should look very familiar by now, it takes a function (or the name of a recognized function in phoebe.parameters.compute) and then any
kwargs to set in that ParameterSet, passed to b.add_compute.
Let's say that we want to create two sets of compute options - in this example, we'll create one called 'preview' which will cut some corners to quickly get us a model, and one called 'detailed' which will get a much more precise model but likely take longer.  As with other tags, the string you provide for the compute tag is up to you (so long as it doesn't raise an error because it conflicts with other tags).
Can you write Python code for it?

b.add_compute(phoebe.compute.phoebe, compute='preview', irrad_method='none')

print(b['preview@compute'])

b.add_compute('phoebe', compute='detailed', irrad_method='wilson')

print(b.get_compute('detailed'))


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
And we'll attach some dummy datasets.  See the datasets tutorial for more details.
Can you write Python code for it?

b.add_dataset(phoebe.dataset.orb, compute_times=np.linspace(0,10,10), dataset='orb01', component=['primary', 'secondary'])

times, fluxes, sigmas = np.loadtxt('test.lc.in', unpack=True)

# test.lc.in has 1000 datapoints... let's use every 10 just for brevity
times, fluxes, sigmas = times[::10], fluxes[::10], sigmas[::10]

b.add_dataset(phoebe.dataset.lc, times=times, fluxes=fluxes, sigmas=sigmas, dataset='lc01')


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See the building a system tutorial for more details.
Can you write Python code for it?

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
Default Compute Options
Any default Bundle already has a set of default compute options to run the backend for PHOEBE 2.  In most cases, you can just edit the options in this default set of compte options.
Can you write Python code for it?

print(b.computes)

print(b.filter(context='compute'))

b.set_value('irrad_method', 'none')


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
Overriding Times
times kwarg in run_compute
You can pass times to run_compute to override the times across all datasets.
Can you write Python code for it?

b.run_compute(compute='preview',
              times=[0,0.1,0.2],
              model='override_times')

print("dataset times: {}\nmodel times: {}".format(
    b.get_value('times', dataset='lc01', context='dataset'),
    b.get_value('times', dataset='lc01', model='override_times')))


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
So in this case, 'lc01' will be computed using the options in 'detailed' while 'orb01' will use the options in 'preview'.
Can you write Python code for it?

b.run_compute(compute=['detailed', 'preview'], model='multiplecompute')

print(b.models)


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
To remove a model, call remove_model.
Can you write Python code for it?


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
as you can see, there is a copy for both of our compute options ('preview' and 'detailed').
If we know which set of compute options we'll be using, or only want to enable/disable for a given set, then we can do that:
Can you write Python code for it?

b['enabled@lc01@preview'] = False
print(b['enabled@lc01'])


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
compute_times parameter
NEW in PHOEBE 2.2
Alternatively, you can override the times (or phases) per-dataset at which the model should be computed.  This is particularly useful if you have attached real data (with a large number of data points) but want the model computed at only a subset of times.
Note that the method above (sending times as a keyword argument to run_compute) will take precedence over compute_times.
Can you write Python code for it?

b.set_value('compute_times', dataset='lc01', value=[0, 0.2, 0.4])

b.run_compute(compute='preview',
              model='override_compute_times')

print("dataset times: {}\ndataset compute_times: {}\ndataset compute_phases: {}\n model times: {}".format(
    b.get_value('times', dataset='lc01', context='dataset'),
    b.get_value('compute_times', dataset='lc01', context='dataset'),
    b.get_value('compute_phases', dataset='lc01', context='dataset'),
    b.get_value('times', dataset='lc01', model='override_compute_times')))


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
for more details, see the advanced: compute times & phases tutorial.
Running Compute with Multiple Sets of Options
So far we've seen how setting up different sets of compute options can be handy - 'preview' vs 'detailed', for example.  But there could also be situations where you want to use different sets of options per dataset.  Perhaps you have a high-precision follow-up light curve of an eclipse along with a lower-precision light curve over a longer time baseline.  So here you'd want to run 'detailed' on the high-precision light curve, but 'preview' on the lower-precision light curve.
You could of course call run_compute twice and create two separate models - but that isn't always convenient and will be a problem in the future when we want to fit data.
Instead we can send a list of compute options to run_compute.
A given dataset can only be enabled in up to 1 of the compute options we're sending to run_compute.  So let's take care of that first (if we don't, we'd get an error when trying to call run_compute):
Can you write Python code for it?

print(b['enabled@orb01'])

b.set_value_all('enabled@orb01@detailed', False)
b.set_value_all('enabled@orb01@preview', True)
print(b['enabled@orb01'])


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
or of course through method access:
Can you write Python code for it?

print(b.get_value(qualifier='us', dataset='orb01', component='primary', model='run_with_incl_90')[:10])


I am working on the file "2.2/tutorials/compute.ipynb".
The first task is:
or to enable/disable a dataset for all sets of compute options, we can use the set_value_all method:
Can you write Python code for it?


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
As always, let's do imports and create a new Bundle.  See Building a System for more details.
Can you write Python code for it?

import phoebe
from phoebe import u # units

b = phoebe.default_binary()

b.add_dataset('lc', times=phoebe.linspace(0,10,101), dataset='lc01')


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
If we plot the dataset and model, we see that the model was only computed for one cycle, whereas the dataset extends further in time.
Can you write Python code for it?


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
Note that under the hood, PHOEBE always works in time-space, meaning it is the constrained value of compute_times that is being passed under-the-hood.
Also note that if directly passing compute_phases to b.add_dataset, the constraint will be flipped on our behalf.  We would then need to flip the constraint in order to provide compute_times instead.
Finally, it is important to make the distinction that this is not adding support for observations in phases.  If we have an old light curve that is only available in phase, we still must convert these to times manually (or via b.to_time).  This restriction is intentional: we do not want the mapping between phase and time to change as the ephemeris is changed or fitted, rather we want to try to map from phase to time using the ephemeris that was originally used when the dataset was recorded (if possible, or the best possible guess).
Interpolating the Model
Whether or not we used compute_times/compute_phases or not, it is sometimes useful to be able to interpolate on the resulting model.  In the case where we provided compute_times/compute_phases to "down-sample" from a large dataset, this can be particularly useful.
We can call interp_value on any FloatArrayParameter.
Can you write Python code for it?

b.get_parameter('fluxes', context='model').get_value()

b.get_parameter('fluxes', context='model').interp_value(times=1.0)

b.get_parameter('fluxes', context='model').interp_value(times=phoebe.linspace(0,3,101))


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
Overriding Computation Times
If compute_times is not empty (by either providing compute_times or compute_phases), the provided value will be used to compute the model instead of those in the times parameter.
In the case of a mesh dataset or orbit dataset, observations cannot be attached to the dataset, so a times parameter does not exist.  In this case compute_times or compute_phases will always be used.
Can you write Python code for it?

print(b.filter(qualifier=['times', 'compute_times'], context='dataset'))

b.set_value('compute_times', phoebe.linspace(0,3,11))

b.run_compute()

print("dataset times: {}\ndataset compute_times: {}\nmodel times: {}".format(
    b.get_value('times', context='dataset'),
    b.get_value('compute_times', context='dataset'),
    b.get_value('times', context='model')
    ))


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
Phase-Time Conversion
In addition to the ability to provide compute_times, we can alternatively provide compute_phases.  These two parameters are linked via a constraint (see the constraints tutorial), with compute_phases constrained by default.
Can you write Python code for it?

print(b.filter(qualifier=['times', 'compute_times', 'compute_phases', 'compute_phases_t0'], context='dataset'))


I am working on the file "2.2/tutorials/compute_times_phases.ipynb".
The first task is:
compute_times (when not empty) overrides the value of times when computing the model.  However, passing times as a keyword argument to run_compute will take precedence over either - and override the computed times across all enabled datasets.
Can you write Python code for it?

b.run_compute(times=[0,0.2])

print("dataset times: {}\ndataset compute_times: {}\nmodel times: {}".format(
    b.get_value('times', context='dataset'),
    b.get_value('compute_times', context='dataset'),
    b.get_value('times', context='model')
    ))

b.run_compute()

print("dataset times: {}\ndataset compute_times: {}\nmodel times: {}".format(
    b.get_value('times', context='dataset'),
    b.get_value('compute_times', context='dataset'),
    b.get_value('times', context='model')
    ))


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
Changing Hierarchies
Some of the built-in constraints depend on the system hierarchy, and will automatically adjust to reflect changes to the hierarchy.
For example, the masses depend on the period and semi-major axis of the parent orbit but also depend on the mass-ratio (q) which is defined as the primary mass over secondary mass.  For this reason, changing the roles of the primary and secondary components should be reflected in the masses (so long as q remains fixed).
In order to show this example, let's set start with a fresh binary and set the mass-ratio to be non-unity.
Can you write Python code for it?

b = phoebe.default_binary()

b.set_value('q', 0.8)


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
Here the star with component tag 'primary' is actually the primary component in the hierarchy, so should have the LARGER mass (for a q < 1.0).
Can you write Python code for it?

print("M1: {}, M2: {}".format(b.get_value('mass@primary@component'),
                              b.get_value('mass@secondary@component')))


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
Here we see the equation used to derive the mass of the primary star
from its orbit, as well as the current value
If we access the Parameter that it is constraining we can see that it
is automatically kept up-to-date.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
If you change the hierarchy, built-in cross-object constraints (like mass
that depends on its parent orbit), will be adjusted to reflect the new hierarchy.  See the 'Changing Hierarchies' section below for more details.
Built-in Constraints
There are a number of built-in constraints that can be applied to our system.  Those added by default are all listed below:
asini
This constraint handles computing the projected semi-major axis along the line of sight and can be automatically inverted to solve for either 'asini', 'sma', or 'incl'.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
Notice that the qualifier tag has changed from 'mass' to 'period' and the 'component' tag has changed from 'primary' to 'binary' (since sma is in the binary).
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
Re-Parameterizing
NOTE: this is an experimental feature.  When re-parameterizing, please be
careful and make sure all results and parameters make sense.
As we've just seen, the mass is a constrained (ie derived) parameter.  But
let's say that you would rather provide masses for some reason (perhaps
that was what was provided in a paper).  You can choose to provide mass
and instead have one of its related parameters constrained by calling flip_constraint.
Can you write Python code for it?

print(b['mass@primary@component'].constrained_by)

print(b['value@mass@primary@component'], b['value@mass@secondary@component'], b['value@period@orbit@component'])

b.flip_constraint('mass@primary', solve_for='period')

b['mass@primary@component'] = 1.0

print(b['value@mass@primary@component'], b['value@mass@secondary@component'], b['value@period@orbit@component'])


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
What are Constraints?
Constraints live in their own context of the Bundle, and many are created
by default - either when you add a component or when you set the system hierarchy.
Let's look at all the existing constraints for our binary system.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
esinw, ecosw
These constraints handle computing the projected eccentricity which can be helpful in that they are better representations of the geometry of a light curve and result in symmetric posteriors for near-circular orbits.
Both can be inverted to also automatically solve for 'ecc' or 'per0'.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
pitch/yaw (incl/long_an)
pitch constrains the relation between the orbital and rotational inclination whereas yaw constrains the relation between the orbital and rotational long_an.  When pitch and yaw are set to 0, the system is aligned.
Can you write Python code for it?

b['incl@constraint']

b['incl@primary@constraint']

b['long_an@constraint']

b['long_an@primary@constraint']


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
requiv_max
This constraint handles solving for the maxium equivalent radius (for a detached system).
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
rotation period
This constraint handles computing the rotation period of a star given its synchronicity parameter (syncpar).
It can be inverted to solve for any of the three parameters 'period' (both rotational and orbital) and 'syncpar'.
Can you write Python code for it?


I am working on the file "2.2/tutorials/constraints.ipynb".
The first task is:
t0
This constraint handles converting between different t0 conventions - namely providing a reference time at periastron passage (t0_perpass) and at superior conjunction (t0_supconj).
Currently, this constraint only supports inverting to be solved for 't0_supconj' (ie you cannot automatically invert this constraint to constraint phshift or per0).
Can you write Python code for it?


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Adding Datasets
Can you write Python code for it?

b_cb.add_dataset('mesh', compute_times=[0], dataset='mesh01')

b_cb.add_dataset('orb', compute_times=np.linspace(0,1,201), dataset='orb01')

b_cb.add_dataset('lc', times=np.linspace(0,1,21), dataset='lc01')

b_cb.add_dataset('rv', times=np.linspace(0,1,21), dataset='rv01')


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
And because of this, the potential and requiv@secondary constraints cannot be updated from the constraints.
Can you write Python code for it?


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
As you can see, the overcontact system has an additional "component" with method "envelope" and component label "contact_envelope".
Next let's look at the parameters in the envelope and star components. You can see that most of parameters in the envelope class are constrained, while the equivalent radius of the primary is unconstrained. The value of primary equivalent radius constrains the potential and fillout factor of the envelope, as well as the equivalent radius of the secondary.
Can you write Python code for it?

print(b_cb.filter(component='contact_envelope', kind='envelope', context='component'))

print(b_cb.filter(component='primary', kind='star', context='component'))

b_cb['requiv@primary'] = 1.5

b_cb['pot@contact_envelope@component']

b_cb['fillout_factor@contact_envelope@component']

b_cb['requiv@secondary@component']


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
For comparison, we'll do the same to our detached system
Can you write Python code for it?

b_detached.add_dataset('mesh', compute_times=[0], dataset='mesh01')

b_detached.add_dataset('orb', compute_times=np.linspace(0,1,201), dataset='orb01')

b_detached.add_dataset('lc', times=np.linspace(0,1,21), dataset='lc01')

b_detached.add_dataset('rv', times=np.linspace(0,1,21), dataset='rv01')


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Here we'll initialize a default binary, but ask for it to be created as a contact system.
Can you write Python code for it?


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
However, since our system was detached, the system is not overflowing, and therefore doesn't pass system checks
Can you write Python code for it?


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Likewise, we can make a contact system detached again simply by removing the envelope from the hierarchy.  The parameters themselves will still exist (unless you remove them), so you can always just change the hierarchy again to change back to an overcontact system.
Can you write Python code for it?

hier = phoebe.hierarchy.binaryorbit(b_detached['binary'], b_detached['primary'], b_detached['secondary'])
print(hier)

b_detached.set_hierarchy(hier)

print(b_detached.hierarchy)


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Orbits
Can you write Python code for it?

afig, mplfig = b_cb['orb01@model'].plot(x='ws',show=True)

afig, mplfig = b_detached['orb01@model'].plot(x='ws',show=True)


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Plotting
Meshes
Can you write Python code for it?

afig, mplfig = b_cb['mesh01@model'].plot(x='ws', show=True)

afig, mplfig = b_detached['mesh01@model'].plot(x='ws', show=True)


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
RVs
Can you write Python code for it?

afig, mplfig = b_cb['rv01@model'].plot(show=True)

afig, mplfig = b_detached['rv01@model'].plot(show=True)


I am working on the file "2.2/tutorials/contact_binary_hierarchy.ipynb".
The first task is:
Running Compute
Can you write Python code for it?


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Adding a Dataset from Arrays
To add a dataset, you need to provide the function in
phoebe.parameters.dataset for the particular type of data you're dealing with, as well
as any of your "observed" arrays.
The current available methods include:

lc light curves (tutorial)
rv radial velocity curves (tutorial)
lp spectral line profiles (tutorial)
orb orbit/positional data (tutorial)
mesh discretized mesh of stars (tutorial)

Without Observations
The simplest case of adding a dataset is when you do not have observational "data" and only want to compute a synthetic model.  Here all you need to provide is an array of times and information about the type of data and how to compute it.
This situation will almost always be the case for orbits and meshes - its unlikely that you have observed positions and velocities for each of your components, but you still may like to store that information for plotting or diagnostic purposes.
Here we'll do just that - we'll add an orbit dataset which will track the positions and velocities of both our 'primary' and 'secondary' stars (by their component tags) at each of the provided times.
NEW in PHOEBE 2.2: Unlike other datasets, the mesh and orb dataset cannot accept actual observations, so there is no times parameter, only the compute_times and compute_phases parameters.  For more details on these, see the Compute Times & Phases tutorial.
Can you write Python code for it?

b.add_dataset(phoebe.dataset.orb,
              compute_times=np.linspace(0,10,20),
              dataset='orb01',
              component=['primary', 'secondary'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
All of these by default use the period in the top-level of the current hierarchy,
but accept a component keyword argument if you'd like the ephemeris of an
inner-orbit or the rotational ephemeris of a star in the system.
We'll see how plotting works later, but if you manually wanted to plot the dataset
with phases, all you'd need to do is:
Can you write Python code for it?


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Although it isn't possible to attach data in phase-space, it is possible (new in PHOEBE 2.2) to tell PHOEBE at which phases to compute the model by setting compute_phases.  Note that this overrides the value of times when the model is computed.
Can you write Python code for it?

b.add_dataset('lc',
              compute_phases=np.linspace(0,1,11),
              dataset='lc01',
              overwrite=True)


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
As you could probably predict by now, add_dataset  can either take a function or the name of a function in phoebe.parameters.dataset.  The following line would do the same thing (and we'll pass overwrite=True to avoid the error of overwriting dataset='orb01').
Can you write Python code for it?

b.add_dataset('orb',
              compute_times=np.linspace(0,10,20),
              component=['primary', 'secondary'],
              dataset='orb01',
              overwrite=True)


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
As you might expect, if you want to pass different values to different components, simply provide them in a dictionary.
Can you write Python code for it?

b.add_dataset('lc',
              times=[0,1],
              ld_mode='manual',
              ld_func={'primary': 'logarithmic', 'secondary': 'quadratic'},
              dataset='lc01',
             overwrite=True)

print(b['ld_func@lc01'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Enabling and Disabling Datasets
See the Compute Tutorial
Dealing with Phases
Datasets will no longer accept phases.  It is the user's responsibility to convert
phased data into times given an ephemeris.  But it's still useful to be able to
convert times to phases (and vice versa) and be able to plot in phase.
Those conversions can be handled via b.get_ephemeris, b.to_phase, and b.to_time.
Can you write Python code for it?

print(b.get_ephemeris())

print(b.to_phase(0.0))

print(b.to_time(-0.25))


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
For datasets which attach to individual components, however, this isn't always the desired behavior.
For a single-lined RV where we only attach to one component, everything is as expected.
Can you write Python code for it?

b.add_dataset('rv',
              times=[0,1],
              rvs=[-3,3],
              component='primary',
              dataset='rv01',
              overwrite=True)

print(b['rvs@rv01'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Here we added an RV dataset and can see that it was automatically created for both stars in our system.  Under-the-hood, another entry is created for component='_default'.  The default parameters hold the values that will be replicated if a new component is added to the system in the future.  In order to see these hidden parameters, you need to pass check_default=False to any filter-type call (and note that '_default' is no longer exposed when calling .components).  Also note that for set_value_all, this is automatically set to False.
Since we did not explicitly state that we only wanted the primary and secondary components, the time array on '_default' is filled as well.  If we were then to add a tertiary component, its RVs would automatically be computed because of this replicated time array.
Can you write Python code for it?

print(b.filter(qualifier='times', dataset='rv01', check_default=False).components)

print(b.get('times@_default@rv01', check_default=False))


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
However, for a double-lined RV we probably don't want to do the following:
Can you write Python code for it?

b.add_dataset('rv',
              times=[0,0.5,1],
              rvs=[-3,3],
              dataset='rv02')

print(b['rvs@rv02'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Instead we want to pass different arrays to the 'rvs@primary' and 'rvs@secondary'.  This can be done by explicitly stating the components in a dictionary sent to that argument:
Can you write Python code for it?

b.add_dataset('rv',
              times=[0,0.5,1],
              rvs={'primary': [-3,3], 'secondary': [4,-4]},
              dataset='rv02',
              overwrite=True)

print(b['rvs@rv02'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
Note here that we didn't explicitly override the defaults for '_default', so they used the phoebe-wide defaults.  If you wanted to set a value for the ld_coeffs of any star added in the future, you would have to provide a value for '_default' in the dictionary as well.
Can you write Python code for it?


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
The simplest way to remove a dataset is by its dataset tag:
Can you write Python code for it?


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
With Observations
Loading datasets with observations is (nearly) as simple.
Passing arrays to any of the dataset columns will apply it to all of the same components in which the time will be applied (see the 'Without Observations' section above for more details).  This make perfect sense for fluxes in light curves where the time and flux arrays are both at the system level:
Can you write Python code for it?

b.add_dataset('lc', times=[0,1], fluxes=[1,0.5], dataset='lc01')

print(b['fluxes@lc01@dataset'])


I am working on the file "2.2/tutorials/datasets.ipynb".
The first task is:
You may notice that add_dataset does take some time to complete.  In the background, the passband is being loaded (when applicable) and many parameters are created and attached to the Bundle.
If you do not provide a list of component(s), they will be assumed for you based on the dataset method.  LCs (light curves) and meshes can only attach at the system level (component=None), for instance, whereas RVs and ORBs can attach for each star.
Can you write Python code for it?

b.add_dataset('rv', times=np.linspace(0,10,20), dataset='rv01')

print(b.filter(qualifier='times', dataset='rv01').components)


I am working on the file "2.2/tutorials/detach.ipynb".
The first task is:
And at any point we can choose to "re-attach".  If the job isn't yet complete, we'll be in a wait loop until it is.  Once the job is complete, the new model will be loaded and accessible.
Can you write Python code for it?

b['mymodel'].attach()

b['mymodel']

axs, artists = b['mymodel'].plot(show=True)


I am working on the file "2.2/tutorials/detach.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/detach.ipynb".
The first task is:
If we want, we can even save the Bundle and load it later to retrieve the results.  In this case where the job is being run in a different Python thread but on the same machine, you cannot, however, exit Python or restart your machine.
When detaching and running on a server (coming soon), you will then be able to exit your Python session or even open the Bundle on a different machine.
Can you write Python code for it?

b.save('test_detach.bundle')

b = phoebe.Bundle.open('test_detach.bundle')

print(b['mymodel'].status)


I am working on the file "2.2/tutorials/detach.ipynb".
The first task is:
Now we'll add datasets
Can you write Python code for it?


I am working on the file "2.2/tutorials/distance.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?


I am working on the file "2.2/tutorials/distance.ipynb".
The first task is:
Note that 'pblum' is defined such that a (spherical, non-eclipsed, non-limb darkened) star with a pblum of 4pi will contribute a flux of 1.0 at 1.0 m (the default distance).
For more information, see the pblum tutorial
Influence on Meshes (Intensities)
Distance does not affect the intensities stored in the mesh (including those in relative units).  In other words, like third light, distance only scales the fluxes.
NOTE: this is different than pblums which DO affect the relative intensities.  Again, see the pblum tutorial for more details.
To see this we can run both of our distances again and look at the values of the intensities in the mesh.
Can you write Python code for it?

b.add_dataset('mesh', times=[0], dataset='mesh01', columns=['intensities@lc01', 'abs_intensities@lc01'])

b.set_value('distance', 1.0)

b.run_compute(model='dist1', overwrite=True)

b.set_value('distance', 2.0)

b.run_compute(model='dist2', overwrite=True)

print("dist1 abs_intensities: ", np.nanmean(b.get_value(qualifier='abs_intensities', component='primary', dataset='lc01', model='dist1')))
print("dist2 abs_intensities: ", np.nanmean(b.get_value(qualifier='abs_intensities', component='primary', dataset='lc01', model='dist2')))

print("dist1 intensities: ", np.nanmean(b.get_value(qualifier='intensities', component='primary', dataset='lc01', model='dist1')))
print("dist2 intensities: ", np.nanmean(b.get_value(qualifier='intensities', component='primary', dataset='lc01', model='dist2')))


I am working on the file "2.2/tutorials/distance.ipynb".
The first task is:
Since we doubled the distance from 1 to 2 m, we expect the entire light curve at 2 m to be divided by 4 (note the y-scales on the plots below).
Can you write Python code for it?

afig, mplfig = b['lc01'].plot(show=True, legend=True)


I am working on the file "2.2/tutorials/distance.ipynb".
The first task is:
To make things easier to compare, let's disable limb darkening
Can you write Python code for it?

b.set_value_all('ld_mode', 'manual')
b.set_value_all('ld_func', 'logarithmic')
b.set_value_all('ld_coeffs', [0.,0.])

b.set_value('distance', 1.0)

b.run_compute(model='dist1', overwrite=True)

b.set_value('distance', 2.0)

b.run_compute(model='dist2', overwrite=True)


I am working on the file "2.2/tutorials/ebv_Av_Rv.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?


I am working on the file "2.2/tutorials/ebv_Av_Rv.ipynb".
The first task is:
Now let's add a light curve so that we can access the relevant parameters.
Can you write Python code for it?


I am working on the file "2.2/tutorials/ebv_Av_Rv.ipynb".
The first task is:
Relevant Parameters
Extinction is parameterized by 3 parameters: ebv (E(B-V)), Av, and Rv.  Of these three, two can be provided and the other must be constrained.  By default, ebv is the constrained parameter.  To change this, see the tutorial on constraints and the b.flip_constraint API docs.
Can you write Python code for it?

print(b['ebv'])

print(b['ebv@dataset'])

print(b['ebv@constraint'])

print(b['Av'])

print(b['Rv'])


I am working on the file "2.2/tutorials/ecc.ipynb".
The first task is:
Influence on Light Curves (fluxes)
Can you write Python code for it?

b.add_dataset('lc', times=np.linspace(0,1,51))

b.run_compute()

afig, mplfig = b['lc@model'].plot(show=True)


I am working on the file "2.2/tutorials/ecc.ipynb".
The first task is:
Influence on Meshes (volume conservation)
Can you write Python code for it?

b.add_dataset('mesh', times=np.linspace(0,1,11), columns=['volume'])

b.set_value('ecc', 0.2)

b.run_compute()

print(b['volume@primary@model'])

afig, mplfig = b['mesh01'].plot(x='times', y='volume', show=True)

b.remove_dataset('mesh01')


I am working on the file "2.2/tutorials/ecc.ipynb".
The first task is:
Influence on Radial Velocities
Can you write Python code for it?

b.add_dataset('rv', times=np.linspace(0,1,51))

b.run_compute()

afig, mplfig = b['rv@model'].plot(show=True)

b.remove_dataset('rv01')


I am working on the file "2.2/tutorials/ecc.ipynb".
The first task is:
Relevant Parameters
Can you write Python code for it?

print(b.get_parameter(qualifier='ecc'))

print(b.get_parameter(qualifier='ecosw', context='component'))

print(b.get_parameter(qualifier='esinw', context='component'))


I am working on the file "2.2/tutorials/eclipse.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

phoebe.devel_on() # DEVELOPER MODE REQUIRED FOR VISIBLE_PARTIAL - DON'T USE FOR SCIENCE

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/eclipse.ipynb".
The first task is:
Let's just compute the mesh at a single time-point that we know should be during egress.
Can you write Python code for it?


I am working on the file "2.2/tutorials/eclipse.ipynb".
The first task is:
Native
The 'native' eclipse method computes what percentage (by area) of each triangle is visible at the current time.  It also determines the centroid of the visible portion of each triangle.
Physical quantities (temperatures, intensities, velocities, etc) are computed at the vertices of each triangle, and this centroid is then used to determine the average quantity across the visible portion of the triangle (by assuming a linear gradient across the triangle).
Let's plot the visibilities (ratio of the area that is visible) as the color scale, with red being completely hidden and green being completely visible.
Can you write Python code for it?

b.run_compute(eclipse_method='native')

afig, mplfig = b.plot(component='primary', fc='visibilities', xlim=(-0.5, 0.25), ylim=(-0.4, 0.4), show=True)


I am working on the file "2.2/tutorials/eclipse.ipynb".
The first task is:
Visible Partial
The 'visible partial' eclipse method simply determines which triangles are hidden, which are visible, and which are partially visible.  It then assigns a visibility of 0.5 to any partially visible triangles - meaning they will contribute half of their intensities when integrated (assume that half of the area is visible).  There are no longer any centroids - values are still computed at the vertices but are then averaged to be at the geometric center of EACH triangle.
Again, let's plot the visibilities (ratio of the area that is visible) as the color scale, with red being completely hidden and green being completely visible.
Can you write Python code for it?

b.run_compute(eclipse_method='visible_partial')

afig, mplfig = b.plot(component='primary', fc='visibilities', xlim=(-0.5, 0.25), ylim=(-0.4, 0.4), show=True)


I am working on the file "2.2/tutorials/fti.ipynb".
The first task is:
An 'fti_method' parameter exists for each set of compute options and each lc dataset.  By default this is set to 'none' - meaning that the exposure times are ignored during b.run_compute().
Can you write Python code for it?

print(b['fti_method'])

b['fti_method'] = 'oversample'


I am working on the file "2.2/tutorials/fti.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()

b.add_dataset('lc', times=np.linspace(0,1,101), dataset='lc01')


I am working on the file "2.2/tutorials/fti.ipynb".
The first task is:
Influence on Light Curves
Can you write Python code for it?

b.run_compute(fti_method='none', irrad_method='none', model='fti_off')

b.run_compute(fti_method='oversample', irrad_method='none', model='fit_on')


I am working on the file "2.2/tutorials/fti.ipynb".
The first task is:
Once we set fti_method to be 'oversample', the corresponding 'fti_oversample' parameter(s) become visible.  This option defines how many different time-points PHOEBE should sample over the width of the exposure time and then average to return a single flux point.  By default this is set to 5.
Note that increasing this number will result in better accuracy of the convolution caused by the exposure time - but increases the computation time essentially linearly.  By setting to 5, our computation time will already be almost 5 times that when fti is disabled.
Can you write Python code for it?


I am working on the file "2.2/tutorials/fti.ipynb".
The first task is:
Relevant Parameters
An 'exptime' parameter exists for each lc dataset and is set to 0.0 by default.  This defines the exposure time that should be used when fti is enabled.  As stated in its description, the time stamp of each datapoint is defined to be the time of mid-exposure.  Note that the exptime applies to all times in the dataset - if times have different exposure-times, then they must be split into separate datasets manually.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
All of these arguments are optional and will default to clevel='WARNING' if not provided.  There is therefore no need to provide a filename if you don't provide a value for flevel.
So with this logger, anything with INFO, WARNING, ERROR, or CRITICAL levels will be printed to the screen.  All messages of any level will be written to a file named 'tutorial.log' in the current directory.
Note: the logger messages are not included in the outputs shown below.
Parameters
Parameters hold a single value, but need to be aware about their own types, limits, and connection with other Parameters (more on this later when we discuss ParameterSets).
Note that generally you won't ever have to "create" or "define" your own Parameters, those will be created for you by helper functions, but we have to start somewhere... so let's create our first Parameter.
We'll start with creating a StringParameter since it is the most generic, and then discuss and specific differences for each type of Parameter.
Can you write Python code for it?

param = phoebe.parameters.StringParameter(qualifier='myparameter',
                                          description='mydescription',
                                          value='myvalue')


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
As with Python, an empty string will cast to False and a non-empty string will cast to True
Can you write Python code for it?

param.set_value('')
print(param.get_value())

param.set_value('some_string')
print(param.get_value())


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Bool Parameters
BoolParameters are even simpler - they accept True or False.
Can you write Python code for it?

param = phoebe.parameters.BoolParameter(qualifier='myboolparameter',
                                        description='mydescription',
                                        value=True)

print(param)

print(param.attributes)


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
But note that the limits are still stored as a quantity object in the originally defined default_units
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
But we can also request the value in a different unit, by passing an astropy Unit object or its string representation.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
But we can also use set and get_value methods from the ParameterSet itself:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Calling get_value will then return a float in these units
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Filtering
Any of the tags can also be used to filter the ParameterSet:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
FloatArrayParameters also allow for built-in interpolation... but this requires them to be a member of a Bundle, so we'll discuss this in just a bit.
ParametersSets
ParameterSets are a collection of Parameters that can be filtered by their tags to return another ParameterSet.
For illustration, let's create 3 random FloatParameters and combine them to make a ParameterSet.
Can you write Python code for it?

param1 = phoebe.parameters.FloatParameter(qualifier='param1',
                                          description='param1 description',
                                          default_unit=u.m,
                                          limits=[None,20],
                                          value=5,
                                          context='context1',
                                          kind='kind1')

param2 = phoebe.parameters.FloatParameter(qualifier='param2',
                                          description='param2 description',
                                          default_unit=u.deg,
                                          limits=[0,2*np.pi],
                                          value=0,
                                          context='context2',
                                          kind='kind2')

param3 = phoebe.parameters.FloatParameter(qualifier='param3',
                                          description='param3 description',
                                          default_unit=u.kg,
                                          limits=[0,2*np.pi],
                                          value=0,
                                          context='context1',
                                          kind='kind2')

ps = phoebe.parameters.ParameterSet([param1, param2, param3])

print(ps.to_list())


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
FloatParameters
FloatParameters are probably the most common Parameter used in PHOEBE and hold both a float and a unit, with the ability to retrieve the value in any other convertible unit.
Can you write Python code for it?

param = phoebe.parameters.FloatParameter(qualifier='myfloatparameter',
                                         description='mydescription',
                                         default_unit=u.m,
                                         limits=[None,20],
                                         value=5)

print(param)


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
FloatParameters also have their own method to access an astropy Quantity object that includes both the value and the unit
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
FloatParameters have an attribute which holds the "default_unit" - this is the unit in which the value is stored and the unit that will be provided if not otherwise overriden.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
For the special case of the 'value' attribute, there is also a get_value method (will become handy later when we want to be able to request the value in a specific unit).
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
However, SelectParameters also allow you to use * as a wildcard and will expand to any of the choices that match that wildcard.  For example,
Can you write Python code for it?

param.set_value(["choice*"])

print(param.get_value())

print(param.expand_value())


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
If for some reason you want to change the default_unit, you can do so as well:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
If we print a ParameterSet, we'll see a listing of all the Parameters and their values.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
If you ever need to know the type of a Parameter, you can always use python's built-in type functionality:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
IntParameters
IntParameters are essentially the same as FloatParameters except they always cast to an Integer and they have no units.
Can you write Python code for it?

param = phoebe.parameters.IntParameter(qualifier='myintparameter',
                                       description='mydescription',
                                       limits=[0,None],
                                       value=1)

print(param)

print(param.attributes)


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
It doesn't make much sense to need to define a mass if this thing isn't baryonic.  So if we change the value of 'what_is_this' to 'aether' then the 'mass' Parameter will temporarily hide itself.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Let's get started with some basic imports
Can you write Python code for it?

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Like FloatParameters above, IntParameters still have limits
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Most of these "metatags" act as labels - for example, you can give a component tag to each of the components for easier referencing.
But a few of these tags are fixed and not editable:

qualifier: literally the name of the parameter.
kind: tells what kind a parameter is (ie whether a component is a star or an orbit).
context: tells what context this parameter belongs to
twig: a shortcut to the parameter in a single string.
uniquetwig: the minimal twig needed to reach this parameter.
uniqueid: an internal representation used to reach this parameter

These contexts are (you'll notice that most are represented in the tags):

setting
history
system
component
feature
dataset
constraint
compute
model
fitting [not yet supported]
feedback [not yet supported]
plugin [not yet supported]

One way to distinguish between context and kind is with the following question and answer:
"What kind of [context] is this?  It's a [kind] tagged [context]=[tag-with-same-name-as-context]."
In different cases, this will then become:

"What kind of component is this?  It's a star tagged component=starA." (context='component', kind='star', component='starA')
"What kind of feature is this?  It's a spot tagged feature=spot01." (context='feature', kind='spot', feature='spot01')
"What kind of dataset is this?  It's a LC (light curve) tagged dataset=lc01." (context='dataset', kind='LC', dataset='lc01')
"What kind of compute (options) are these?  They're phoebe (compute options) tagged compute=preview." (context='compute', kind='phoebe', compute='preview')

As we saw before, these tags can be accessed at the Parameter level as either a dictionary key or as an object attribute.  For ParameterSets, the tags are only accessible through object attributes.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Note that this returned the ParameterObject itself, so you can now use any of the Parameter methods or attributes we saw earlier.  For example:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Note that, like IntParameters, BoolParameters will attempt to cast anything you give it into True or False.
Can you write Python code for it?

param.set_value(0)
print(param.get_value())

param.set_value(None)
print(param.get_value())


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Now we can interpolate the 'ys' param for any given value of 'xs'
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Now we see that we have drilled down to a single Parameter.  Note that a ParameterSet is still returned - filter will always return a ParameterSet.
We could have accomplished the exact same thing with a single call to filter:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Of course, once you get the Parameter you can then use dictionary keys to access any attributes of that Parameter.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
SelectParameters
 NEW IN PHOEBE 2.1
SelectParameters are very similar to ChoiceParameters except that the value is a list, where each item must match one of the prescribed choices.
Can you write Python code for it?

param = phoebe.parameters.SelectParameter(qualifier='myselectparameter',
                                          description='mydescription',
                                          choices=['choice1', 'choice2'],
                                          value=['choice1'])

print(param)

print(param.attributes)

print(param['choices'], param.choices)

print(param.get_value())


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
So we decided we might as well allow access to those attributes directly from the twig as well
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
The 'qualifier' attribute is essentially an abbreviated name for the Parameter.
These tags will be shared across all Parameters, regardless of their type.
Attributes, on the other hand, can be dependent on the type of the Parameter and tell the Parameter its rules and how to interpret its value.  You can access a list of available attributes as follows:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
The Bundle
The Bundle is nothing more than a glorified ParameterSet with some extra methods to compute models, add new components and datasets, etc.
You can initialize an empty Bundle as follows:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
The value attribute is also the only attribute that you'll likely want to change, so it also has a set_value method:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
This returns None since not all objects in this ParameterSet share a single context.  But you can see all the options for a given tag by providing the plural version of that tag name:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
Twigs
The string notation used for the Parameters is called a 'twig' - its simply a combination of all the tags joined with the '@' symbol and gives a very convenient way to access any Parameter.
The order of the tags doesn't matter, and you only need to provide enough tags to produce a unique match.  Since there is only one parameter with kind='kind1', we do not need to provide the extraneous context='context1' in the twig to get a match.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
You can see here that we've defined three a few things about parameter: the qualifier, description, and value (others do exist, they just don't show up in the summary).
These "things" can be split into two groups: tags and attributes (although in a pythonic sense, both can be accessed as attributes).  Don't worry too much about this distinction - it isn't really important except for the fact that tags are shared across all Parameters whereas attributes are dependent on the type of the Parameter.
The tags of a Parameter define the Parameter and how it connects to other Parameters (again, more on this when we get to ParameterSets).  For now, just know that you can access a list of all the tags as follows:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
You'll notice here a few new mentions in the summary... "Constrained by", "Constrains", and "Related to" are all referring to constraints which will be discussed in a future tutorial.
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
and again, each of these are available through both a dictionary key and as an object attribute.  For example, all parameters have a 'description' attribute which gives additional information about what the Parameter means:
Can you write Python code for it?


I am working on the file "2.2/tutorials/general_concepts.ipynb".
The first task is:
and that each of these is available through both a dictionary key and an object attribute.  For example:
Can you write Python code for it?


I am working on the file "2.2/tutorials/grav_redshift.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()

b.add_dataset('rv', times=np.linspace(0,1,101), dataset='rv01')

b.set_value_all('ld_mode', 'manual')
b.set_value_all('ld_func', 'logarithmic')
b.set_value_all('ld_coeffs', [0.0, 0.0])
b.set_value_all('atm', 'blackbody')


I am working on the file "2.2/tutorials/grav_redshift.ipynb".
The first task is:
Besides the obvious change in the Rossiter-McLaughlin effect (not due to gravitational redshift), we can see that making the radii smaller shifts the entire RV curve up (the spectra are redshifted as they have to climb out of a steeper potential at the surface of the stars).
Can you write Python code for it?


I am working on the file "2.2/tutorials/grav_redshift.ipynb".
The first task is:
Influence on Radial Velocities
Can you write Python code for it?

afig, mplfig = b.filter(model=['defaultradii_true', 'smallradii_true']).plot(legend=True, show=True)

afig, mplfig = b.filter(model=['smallradii_true', 'smallradii_false']).plot(legend=True, show=True)


I am working on the file "2.2/tutorials/grav_redshift.ipynb".
The first task is:
Relevant Parameters
Gravitational redshifts are only accounted for flux-weighted RVs (dynamical RVs literally only return the z-component of the velocity of the center-of-mass of each star).
First let's run a model with the default radii for our stars.
Can you write Python code for it?


I am working on the file "2.2/tutorials/gravb_bol.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()

b.add_dataset('lc', dataset='lc01')
b.add_dataset('mesh', times=[0], columns=['intensities*'])


I am working on the file "2.2/tutorials/gravb_bol.ipynb".
The first task is:
Comparing these two plots, it is essentially impossible to notice any difference between the two models.  But if we compare the intensities directly, we can see that there is a subtle difference, with a maximum difference of about 3%.
Can you write Python code for it?

np.nanmax((b.get_value('intensities', component='primary', model='gravb_bol_32') - b.get_value('intensities', component='primary', model='gravb_bol_10'))/b.get_value('intensities', component='primary', model='gravb_bol_10'))


I am working on the file "2.2/tutorials/gravb_bol.ipynb".
The first task is:
If you have a logger enabled, PHOEBE will print a warning if the value of gravb_bol is outside the "suggested" ranges.  Note that this is strictly a warning, and will never turn into an error at b.run_compute().
You can also manually call b.run_checks().  The first returned item tells whether the system has passed checks: True means it has, False means it has failed, and None means the tests pass but with a warning.  The second argument tells the first warning/error message raised by the checks.
The checks use the following "suggested" values:
 * teff 8000+: gravb_bol >= 0.9 (suggest 1.0)
 * teff 6600-8000: gravb_bol 0.32-1.0
 * teff 6600-: grav_bol < 0.9 (suggest 0.32)
Can you write Python code for it?

print(b.run_checks())

b['teff@primary'] = 8500
b['gravb_bol@primary'] = 0.8
print(b.run_checks())

b['teff@primary'] = 7000
b['gravb_bol@primary'] = 0.2
print(b.run_checks())

b['teff@primary'] = 6000
b['gravb_bol@primary'] = 1.0
print(b.run_checks())


I am working on the file "2.2/tutorials/gravb_bol.ipynb".
The first task is:
Relevant Parameters
The 'gravb_bol' parameter corresponds to the β coefficient for gravity darkening corrections.
Can you write Python code for it?


I am working on the file "2.2/tutorials/intens_weighting.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()

b.add_dataset('lc', times=np.linspace(0,1,101))


I am working on the file "2.2/tutorials/intens_weighting.ipynb".
The first task is:
Influence on Light Curves (fluxes)
Let's (roughtly) reproduce Figure 5 from Prsa et al. 2016 which shows the difference between photon and energy intensity weighting.
<img src="prsa+2016_fig5.png" alt="Figure 8" width="600px"/>
Can you write Python code for it?

for teff_primary in [5000,7500,10000,12500,15000]:
    b['teff@primary'] = teff_primary
    b['teff@secondary'] = 0.9 * teff_primary

    for weighting in ['energy', 'photon']:
        b['intens_weighting'] = weighting
        b.run_compute(irrad_method='none', model='{}_{}'.format(teff_primary, weighting))

teff_colormap = {5000: 'm', 7500: 'r', 10000: 'g', 12500: 'c', 15000: 'b'}

fig = plt.figure()
ax1, ax2 = fig.add_subplot(211), fig.add_subplot(212)

for teff, color in teff_colormap.items():
    fluxes_energy = b.get_value('fluxes@{}_energy'.format(teff))
    fluxes_photon = b.get_value('fluxes@{}_photon'.format(teff))
    phases = b.to_phase('times@lc@dataset')

    # alias data from -0.6 to 0.6
    fluxes_energy = np.append(fluxes_energy, fluxes_energy[abs(phases) > 0.4])
    fluxes_photon = np.append(fluxes_photon, fluxes_photon[abs(phases) > 0.4])
    phases = np.append(phases, phases[abs(phases)>0.4]+1.0)
    phases[phases > 1.0] = phases[phases > 1.0] - 2.0

    sort = phases.argsort()
    phases = phases[sort]
    fluxes_energy = fluxes_energy[sort]
    fluxes_photon = fluxes_photon[sort]

    ax1.plot(phases, fluxes_energy, color=color)
    ax2.plot(phases, fluxes_photon-fluxes_energy, color=color)

lbl = ax1.set_xlabel('')
lbl = ax1.set_ylabel('flux')
lbl = ax2.set_xlabel('phase')
lbl = ax2.set_ylabel('flux diff')


I am working on the file "2.2/tutorials/intens_weighting.ipynb".
The first task is:
Relevant Parameters
Can you write Python code for it?


I am working on the file "2.2/tutorials/irrad_method_horvat.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger('error')

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/irrad_method_horvat.ipynb".
The first task is:
Influence on Light Curves (fluxes)
Let's (roughtly) reproduce Figure 8 from Prsa et al. 2016 which shows the difference between Wilson and Horvat schemes for various inclinations.
<img src="prsa+2016_fig8.png" alt="Figure 8" width="600px"/>
First we'll roughly create a A0-K0 binary and set reasonable albedos.
Can you write Python code for it?

b['teff@primary'] = 11000
b['requiv@primary'] = 2.5
b['gravb_bol@primary'] = 1.0

b['teff@secondary'] = 5000
b['requiv@secondary'] = 0.85

b['q@binary'] = 0.8/3.0

b.flip_constraint('mass@primary', solve_for='sma@binary')
b['mass@primary'] = 3.0

print(b.filter(qualifier=['mass', 'requiv', 'teff'], context='component'))

b['irrad_frac_refl_bol@primary'] = 1.0
b['irrad_frac_refl_bol@secondary'] = 0.6


I am working on the file "2.2/tutorials/irrad_method_horvat.ipynb".
The first task is:
Relevant Parameters
For parameters that affect reflection and heating (irrad_frac_*) see the tutorial on reflection and heating.
The 'irrad_method' compute option dictates whether irradiation is handled according to the new Horvat scheme which includes Lambert Scattering, Wilson's original reflection scheme, or ignored entirely.
Can you write Python code for it?


I am working on the file "2.2/tutorials/irrad_method_horvat.ipynb".
The first task is:
We'll also disable any eclipsing effects.
Can you write Python code for it?


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
Influence on Light Curves (Fluxes)
"Third" light is simply additional flux added to the light curve from some external source - whether it be crowding from a background object, light from the sky, or an extra component in the system that is unaccounted for in the system hierarchy.
To see this we'll compare a light curve with and without "third" light.
Can you write Python code for it?

b.run_compute(irrad_method='none', model='no_third_light')

b.set_value('l3_mode', 'flux')
b.set_value('l3', 5)

b.run_compute(irrad_method='none', model='with_third_light')


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
Influence on Meshes (Intensities)
"Third" light does not affect the intensities stored in the mesh (including those in relative units).  In other words, like distance, "third" light only scales the fluxes.
NOTE: this is different than pblums which DO affect the relative intensities.  Again, see the pblum tutorial for more details.
To see this we can run both of our models again and look at the values of the intensities in the mesh.
Can you write Python code for it?

b.add_dataset('mesh', times=[0], dataset='mesh01', columns=['intensities@lc01', 'abs_intensities@lc01'])

b.set_value('l3', 0.0)

b.run_compute(irrad_method='none', model='no_third_light', overwrite=True)

b.set_value('l3', 5)

b.run_compute(irrad_method='none', model='with_third_light', overwrite=True)

print("no_third_light abs_intensities: ", np.nanmean(b.get_value(qualifier='abs_intensities', component='primary', dataset='lc01', model='no_third_light')))
print("with_third_light abs_intensities: ", np.nanmean(b.get_value(qualifier='abs_intensities', component='primary', dataset='lc01', model='with_third_light')))

print("no_third_light intensities: ", np.nanmean(b.get_value(qualifier='intensities', component='primary', dataset='lc01', model='no_third_light')))
print("with_third_light intensities: ", np.nanmean(b.get_value(qualifier='intensities', component='primary', dataset='lc01', model='with_third_light')))


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
So let's add a LC dataset
Can you write Python code for it?


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
To compute the fractional third light from the provided value in flux units, call b.compute_l3s.  This assumes that the flux of the system is the sum of the extrinsic passband luminosities (see the pblum tutorial for more details on intrinsic vs extrinsic passband luminosities) divided by $4\pi$ at t0@system, and according to the compute options.
Note that calling compute_l3s is not necessary, as the backend will handle the conversion automatically.
Can you write Python code for it?


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
We now see that the LC dataset created an 'l3_mode' parameter, and since l3_mode is set to 'flux' the 'l3' parameter is also visible.
Can you write Python code for it?


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
l3_mode = 'flux'
When l3_mode is set to 'flux', the l3 parameter defines (in flux units) how much extraneous light is added to the light curve in that particular passband/dataset.
Can you write Python code for it?


I am working on the file "2.2/tutorials/l3.ipynb".
The first task is:
l3_mode = 'fraction'
When l3_mode is set to 'fraction', the l3 parameter is now replaced by an l3_frac parameter.
Can you write Python code for it?

b.set_value('l3_mode', 'fraction')

print(b.filter(qualifier='l3*'))

print(b.get_parameter('l3_frac'))


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
All other limb-darkening parameters (ld_mode, ld_func, ld_coeffs_source, and ld_coeffs) are per-component and per-dataset parameters with context='dataset'.
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new bundle.  See Building a System for more details.
Can you write Python code for it?

%matplotlib inline

import phoebe

logger = phoebe.logger()

b = phoebe.default_binary()


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
Note that ld_func, ld_coeffs_source, and ld_coeffs aren't visible (relevant) if ld_mode is set to  'interp' (which it is by default).
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
To access the interpolated values that will be used under-the-hood, we can call b.compute_ld_coeffs.
(To only compute the bolometric quantities, pass dataset='bol')
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
To manually choose an available atmosphere table, you can choose some other value ('ck2004', for example).
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
ld_mode = 'interp'
Unlike bolometric limb-darkening, passband limb-darkening coefficients can be interpolated directly from atmosphere tables, this is the default case, with ld_mode set to 'interp'.
Note that before PHOEBE 2.2, this was accomplished by setting ld_func to 'interp' (see this explanation for migrating from earlier versions).
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
ld_mode = 'lookup'
Setting the value of ld_mode to 'lookup' will expose the ld_func and ld_coeffs_source parameters.  Note that this behavior is slightly new as of PHOEBE 2.2 (see this explanation for migrating from earlier versions).
When set to 'lookup', then the limb-darkening will be interpolated per-element (for PHOEBE 2, other backends may interpolate per-star) for the function given in ld_func from the atmosphere table dictated by the ld_coeffs_source parameter (or the atm parameter and falling back on 'ck2004' if no match is found if ld_coeffs_source is set to 'auto').
Note that the bolometric ld_mode_bol of 'lookup' interpolates per-component, but not per-element.
Can you write Python code for it?

b.set_value(qualifier='ld_mode', dataset='lc01', component='primary', value='lookup')

print(b.filter(qualifier='ld*', dataset='lc01', component='primary'))


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
ld_mode_bol = 'lookup'
By default, ld_mode_bol is set to 'lookup', in which case the coefficients are pulled from the atmosphere table (according to ld_coeffs_source_bol) per-component (but not per-element).  Note that this differs slightly from the dataset-treatment where the lookup is handled per-element.
Can you write Python code for it?


I am working on the file "2.2/tutorials/limb_darkening.ipynb".
The first task is:
ld_mode_bol = 'manual'
To pass coefficients manually, we can change ld_mode_bol to 'manual'
Can you write Python code for it?

b.set_value_all('ld_mode_bol', value='manual')

print(b['ld_coeffs_bol@primary'])


I am working on the file "2.2/tutorials/logg.ipynb".
The first task is:
Flipping logg to solve for the mass is a little more involved, as mass is already constrained by period, sma and q.  So we must first flip the mass constraint to solve for either period or sma.
Can you write Python code for it?

print(b.filter(qualifier=['logg', 'mass', 'requiv'], component='secondary'))

b.flip_constraint('mass@secondary', solve_for='sma')

print(b.filter(qualifier=['logg', 'mass', 'requiv'], component='secondary'))

b.flip_constraint('logg@secondary', solve_for='mass')

print(b.filter(qualifier=['logg', 'mass', 'requiv'], component='secondary'))


I am working on the file "2.2/tutorials/logg.ipynb".
The first task is:
Flipping the Constraint
The logg constraint can be easily flipped so that logg is provided by the user in place of requiv.
See also:
 * tutorial on constraints
 * flip_constraint API docs
Can you write Python code for it?

print(b.filter(qualifier=['logg', 'mass', 'requiv'], component='primary'))

b.flip_constraint('logg@primary', solve_for='requiv')

print(b.filter(qualifier=['logg', 'mass', 'requiv'], component='primary'))


I am working on the file "2.2/tutorials/logg.ipynb".
The first task is:
Input vs Observed
As mentioned above, the logg parameter is defined explicitly to be at requiv and may not be comparable directly to an estimation of logg from observations.
To show this, we'll see that it can even differ from the flux-weighted loggs of the individual surface elements.
Can you write Python code for it?

b.add_dataset('lc', dataset='lc01')
b.add_dataset('mesh', times=[0, 0.25], columns=['loggs', 'areas', 'mus', 'visibilities', 'abs_intensities@lc01', 'ldint@lc01'])

b.run_compute(irrad_method='none')


I am working on the file "2.2/tutorials/logg.ipynb".
The first task is:
Now we can manually compute the 'flux-weighted' logg from each of these times (similar to the way that RVs are computed to account for Rossiter-McLaughlin, but note that even flux-weighted loggs may not be a fair comparison to spectral-derived loggs).
Can you write Python code for it?

for time in [0.0, 0.25]:
    ps = b.filter(time=time, component='primary', context='model')
    fluxes = ps.get_value('abs_intensities') * ps.get_value('areas') * ps.get_value('mus') * ps.get_value('ldint') * ps.get_value('visibilities')
    visible = ps.get_value('visibilities') > 0
    logg = np.average(ps.get_value('loggs')[visible], weights=fluxes[visible])
    print("time = {}, logg weighted = {}".format(time, logg))

print("logg parameter value = {}".format(b.get_value('logg', component='primary')))


I am working on the file "2.2/tutorials/ltte.ipynb".
The first task is:
Comparing with and without ltte
In order to have a binary system with any noticeable ltte effects, we'll set a somewhat extreme mass-ratio and semi-major axis.
Can you write Python code for it?


I am working on the file "2.2/tutorials/ltte.ipynb".
The first task is:
Now let's add a light curve dataset to see how ltte affects the timings of eclipses.
Can you write Python code for it?

b.add_dataset('lc', times=phoebe.linspace(-0.05, 0.05, 51), dataset='lc01')


I am working on the file "2.2/tutorials/ltte.ipynb".
The first task is:
Relevant Parameters
The 'ltte' parameter in context='compute' defines whether light travel time effects are taken into account or not.
Can you write Python code for it?


I am working on the file "2.2/tutorials/meshes.ipynb".
The first task is:
Any of the exposed columns are then available for plotting the mesh, via b.plot.
Can you write Python code for it?

afig, mplfig = b.plot(kind='mesh', time=0.2, fc='teffs', ec='none', show=True)


I am working on the file "2.2/tutorials/meshes.ipynb".
The first task is:
As always, let's do imports and initialize a logger and a new Bundle.  See Building a System for more details.
Can you write Python code for it?


I am working on the file "2.2/tutorials/meshes.ipynb".
The first task is:
NEW in PHOEBE 2.2: Unlike other datasets, the mesh dataset cannot accept actual observations, so there is no times parameter, only the compute_times and compute_phases parameters.  For more details on these, see the Compute Times & Phases tutorial.
Can you write Python code for it?

print(b.get_parameter(qualifier='compute_times', kind='mesh'))

print(b.get_parameter(qualifier='include_times', kind='mesh'))


I am working on the file "2.2/tutorials/meshes.ipynb".
The first task is:
Note that we can manually set the times of the mesh AND/OR reference the times for existing non-mesh datasets (such as the light curve we just added) as well as any of the various t0s in the system.
Can you write Python code for it?

b.set_value('compute_times', kind='mesh', value=[10])

b.set_value('include_times', kind='mesh', value=['lc01'])

b.run_compute()

print(b.filter(kind='mesh', context='model').times)


I am working on the file "2.2/tutorials/meshes.ipynb".
The first task is:
The 'Mesh' Dataset
You must create a mesh dataset and specify the times and columns which you'd like exposed.  For more information, see the tutorial on the MESH dataset.
The mesh will be exposed at the times specified by the compute_times Parameter, as well as any times referenced by the include_times SelectParameter.
So let's add an LC and MESH datasets.
Can you write Python code for it?

b.add_dataset('lc', times=phoebe.linspace(0,1,6))

b.add_dataset('mesh')


I am working on the file "2.2/tutorials/mpi.ipynb".
The first task is:
MPI Modes
As of the 2.1 release, PHOEBE officially support parallelization using MPI.  Note that the 2.1.1 release fixed a bug related to using PHOEBE within non-openmpi environments.
There are several "modes of operation" depending on your settings and whether you're running your script within python or mpirun.  You can enable/disable MPI within phoebe by placing phoebe.mpi_on() or phoebe.mpi_off() at the top of your script.  If you do not do this, MPI will be enabled by default if within mpirun and disabled otherwise.
When MPI is enabled, PHOEBE will do the following:
* if within mpirun: uses PHOEBE's built-in per-dataset or per-time parallelization.  The main code you write in your script is executed on a single processor, but during run_compute the task is divided among the available resources.
* if not within mpirun (ie. in a serial python environment): will spawn a separate thread at phoebe.frontend.bundle.Bundle.run_compute, using number of processors sent to phoebe.mpi_on (for example: phoebe.mpi_on(nprocs=4)).
When MPI is disabled, PHOEBE will do the following:
* if within mpirun: PHOEBE will run equally on all processors. The user can customize parallelization with access to phoebe.mpi.nprocs, phoebe.mpi.myrank.  Your script runs equally on each processor, meaning you have multiple (separate) copies of the bundle.
* if not within mpirun (ie. in a serial python environment): PHOEBE will run on a single processor in serial-mode.
Accessing/Changing MPI Settings
To check the currently adopted settings, as well as quickly access information needed for manually doing your own parallelization, access the phoebe.mpi object.
Can you write Python code for it?

print(phoebe.mpi.enabled)

print(phoebe.mpi.mode)

phoebe.mpi_on()

print(phoebe.mpi.enabled)

print(phoebe.mpi.mode)

print(phoebe.mpi.myrank)

print(phoebe.mpi.nprocs)


I am working on the file "2.2/tutorials/mpi.ipynb".
The first task is:
PHOEBE determines whether the current script is running within an MPI environment by checking for environment variables set by mpirun/mpiexec.  If you run into any issues with PHOEBE not behaving as expected, check to see whether PHOEBE thinks its within mpirun.
Can you write Python code for it?


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
If disabled, you can always manually run the checks via b.run_checks().
Can you write Python code for it?

print(b.run_checks())

b.set_value('requiv', component='primary', value=50)

print(b.run_checks())


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
Interactivity Options
When running in an interactive Python session, PHOEBE updates all constraints and runs various checks after each command.  Although this is convenient, it does take some time, and it can sometimes be advantageous to disable this to save computation time.
Interactive Checks
By default, interactive checks are enabled when PHOEBE is being run in an interactive session (either an interactive python, IPython, or Jupyter notebook session), but disabled when PHOEBE is run as a script directly from the console.  When enabled, PHOEBE will re-run the system checks after every single change to the bundle, raising warnings via the logger as soon as they occur.
This default behavior can be changed via phoebe.interactive_checks_on() or phoebe.interactive_checks_off().  The current value can be accessed via phoebe.conf.interactive_checks.
Can you write Python code for it?

print(phoebe.conf.interactive_checks)

phoebe.interactive_checks_off()

print(phoebe.conf.interactive_checks)


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
No need to worry though - all constraints will be run automatically before passing to the backend.  If you need to access the value of a constrained parameter, you can explicitly ask for all delayed constraints to be executed via b.run_delayed_constraints().
Can you write Python code for it?

b.run_delayed_constraints()

print(b.filter('mass', component='primary'))

phoebe.reset_settings()


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
Note that the mass has already updated, according to the constraint, when the value of the semi-major axes was changed.  If we disable interactive constraints this will not be the case.
Can you write Python code for it?

phoebe.interactive_constraints_off()

print(phoebe.conf.interactive_constraints)

print(b.filter('mass', component='primary'))

b.set_value('sma@binary', 15)

print(b.filter('mass', component='primary'))


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
and can still manually check to see that it shouldn't be visible (isn't currently relevant given the value of ld_func):
Can you write Python code for it?

print(b.get_parameter(qualifier='ld_coeffs_source', component='primary').is_visible)

phoebe.reset_settings()


I am working on the file "2.2/tutorials/optimizing.ipynb".
The first task is:
check_default
Similarly, PHOEBE automatically excludes any parameter which is tagged with a '_default' tag.  These parameters exist to provide default values when a new component or dataset are added to the bundle, but can usually be ignored, and so are excluded from any filter calls.  Although not at all expensive, this too can be disabled at the settings level or by passing check_default=False to any filter call.
This default behavior can be changed via phoebe.check_default_on() or phoebe.check_default_off().
Can you write Python code for it?

print(b.get_dataset())

print(b.get_dataset(check_default=False))

phoebe.check_default_off()

print(b.get_dataset())

phoebe.reset_settings()


I am working on the file "2.2/tutorials/passband_updates.ipynb".
The first task is:
As of the 2.2 release, PHOEBE allows you to check for online updates to local install passbands.  If we add a new atmosphere table or feature (extinction as in this release, for example) to a passband table, you can now update directly from the python interface of PHOEBE.
If you try using extinction in a version of a table that does not support extinction, for example, an error will be raised (either during run_compute or you can check by calling run_checks manually).  If extinction tables are available in the online version of the passband (from tables.phoebe-project.org), then the local installed version will automatically be updated if the timestamps on the passbands match, otherwise a message will be raised with instructions to manually call phoebe.update_passband.
If you'd like to manually check for updates, you can use phoebe.list_all_update_passbands_available or phoebe.update_passband_available.
Can you write Python code for it?

import phoebe

print(phoebe.list_installed_passbands())

print(phoebe.list_all_update_passbands_available())

print(phoebe.update_passband_available('Johnson:V'))


I am working on the file "2.2/tutorials/passband_updates.ipynb".
The first task is:
If there are updates available that you'd like to apply, you can apply them all via phoebe.update_all_passbands
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Checking the content property again shows that the table has been successfully computed:
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Getting started
Let us start by importing phoebe, numpy and matplotlib:
Can you write Python code for it?

%matplotlib inline
import phoebe
from phoebe import u # units
import numpy as np
import matplotlib.pyplot as plt

logger = phoebe.logger(clevel='WARNING')


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
If you plan on computing model atmosphere intensities (as opposed to only blackbody intensities), you will need to download atmosphere tables and unpack them into a local directory of your choice. Keep in mind that this will take a long time. Plan to go for lunch or leave it overnight. The good news is that this needs to be done only once. For the purpose of this document, we will use a local tables/ directory and assume that we are computing intensities for all available model atmospheres:
mkdir tables
cd tables
wget http://phoebe-project.org/static/atms/ck2004.tgz
wget http://phoebe-project.org/static/atms/phoenix.tgz
<!-- wget http://phoebe-project.org/static/atms/tmap.tgz -->

Once the data are downloaded, unpack the archives:
tar xvzf ck2004.tgz
tar xvzf phoenix.tgz
<!-- tar xvzf tmap.tgz -->

That should leave you with the following directory structure:
tables
|____ck2004
|     |____TxxxxxGxxPxx.fits (3800 files)
|____phoenix
|     |____ltexxxxx-x.xx-x.x.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits (7260 files)
I don't care about the details, just show/remind me how it's done
Makes sense, and we don't judge: you want to get to science. Provided that you have the passband transmission file available and the atmosphere tables already downloaded, the sequence that will generate/register a new passband is:
Can you write Python code for it?

import phoebe
from phoebe import u

# Register a passband:
pb = phoebe.atmospheres.passbands.Passband(
    ptf='my_passband.ptf',
    pbset='Custom',
    pbname='mypb',
    effwl=330,
    wlunits=u.nm,
    calibrated=True,
    reference='A completely made-up passband published in Nowhere (2017)',
    version=1.0,
    comments='This is my first custom passband'
)

# Blackbody response:
pb.compute_blackbody_response()

# CK2004 response:
pb.compute_ck2004_response(path='tables/ck2004')
pb.compute_ck2004_intensities(path='tables/ck2004')
pb.compute_ck2004_ldcoeffs()
pb.compute_ck2004_ldints()

# PHOENIX response:
pb.compute_phoenix_response(path='tables/phoenix')
pb.compute_phoenix_intensities(path='tables/phoenix')
pb.compute_phoenix_ldcoeffs()
pb.compute_phoenix_ldints()

# Impute missing values from the PHOENIX model atmospheres:
pb.impute_atmosphere_grid(pb._phoenix_energy_grid)
pb.impute_atmosphere_grid(pb._phoenix_photon_grid)
pb.impute_atmosphere_grid(pb._phoenix_ld_energy_grid)
pb.impute_atmosphere_grid(pb._phoenix_ld_photon_grid)
pb.impute_atmosphere_grid(pb._phoenix_ldint_energy_grid)
pb.impute_atmosphere_grid(pb._phoenix_ldint_photon_grid)
for i in range(len(pb._phoenix_intensity_axes[3])):
    pb.impute_atmosphere_grid(pb._phoenix_Imu_energy_grid[:,:,:,i,:])
    pb.impute_atmosphere_grid(pb._phoenix_Imu_photon_grid[:,:,:,i,:])

# Wilson-Devinney response:
pb.import_wd_atmcof('atmcofplanck.dat', 'atmcof.dat', 22)

# Save the passband:
pb.save('my_passband.fits')


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Let us now plot a range of temperatures, to make sure that normal emergent passband intensities do what they are supposed to do. While at it, let us compare what we get for the Johnson:V passband.
Can you write Python code for it?

jV = phoebe.get_passband('Johnson:V')
teffs = np.linspace(5000, 8000, 100)
plt.xlabel('Temperature [K]')
plt.ylabel('Inorm [W/m^3]')
plt.plot(teffs, pb.Inorm(teffs, atm='blackbody', ld_func='linear', ld_coeffs=[0.0]), label='mypb')
plt.plot(teffs, jV.Inorm(teffs, atm='blackbody', ld_func='linear', ld_coeffs=[0.0]), label='jV')
plt.legend(loc='lower right')
plt.show()


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Let us now save these data in a file that we will use to register a new passband.
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Let us now use the same low-level function as before to compare normal emergent passband intensity for our custom passband for blackbody and ck2004 model atmospheres. One other complication is that, unlike blackbody model that depends only on the temperature, the ck2004 model depends on surface gravity (log g) and heavy metal abundances as well, so we need to pass those arrays.
Can you write Python code for it?

loggs = np.ones(len(teffs))*4.43
abuns = np.zeros(len(teffs))
plt.xlabel('Temperature [K]')
plt.ylabel('Inorm [W/m^3]')
plt.plot(teffs, pb.Inorm(teffs,               atm='blackbody', ld_func='linear', ld_coeffs=[0.0]), label='blackbody')
plt.plot(teffs, pb.Inorm(teffs, loggs, abuns, atm='ck2004',    ld_func='linear', ld_coeffs=[0.0]), label='ck2004')
plt.legend(loc='lower right')
plt.show()


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Let us plot this mock passband transmission function to see what it looks like:
Can you write Python code for it?

plt.xlabel('Wavelength [nm]')
plt.ylabel('Passband transmission')
plt.plot(wl, ptf, 'b-')
plt.show()


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Note, of course, that you will need to change the path to point to the directory where you unpacked the ck2004 tables. The verbosity parameter verbose will report on the progress as computation is being done. Depending on your computer speed, this step will take up to a minute to complete. We can now check the passband's content attribute again:
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Quite a difference. That is why using model atmospheres is superior when accuracy is of importance. Next, we need to compute direction-dependent intensities for all our limb darkening and boosting needs. This is a step that takes a long time; depending on your computer speed, it can take a few minutes to complete.
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Registering a passband
The first step in introducing a new passband into PHOEBE is registering it with the system. We use the Passband class for that.
Can you write Python code for it?

pb = phoebe.atmospheres.passbands.Passband(
    ptf='my_passband.ptf',
    pbset='Custom',
    pbname='mypb',
    effwl=330.,
    wlunits=u.nm,
    calibrated=True,
    reference='A completely made-up passband published in Nowhere (2017)',
    version=1.0,
    comments='This is my first custom passband')


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Since we have not computed any tables yet, the list is empty for now. Blackbody functions for computing the lookup tables are built into PHOEBE and you do not need any auxiliary files to generate them. The lookup tables are defined for effective temperatures between 300K and 500,000K. To compute the blackbody response, issue:
Can you write Python code for it?


I am working on the file "2.2/tutorials/passbands.ipynb".
The first task is:
Still an appreciable difference.
Saving the passband table
The final step of all this (computer's) hard work is to save the passband file so that these steps do not need to be ever repeated. From now on you will be able to load the passband file explicitly and PHOEBE will have full access to all of its tables. Your new passband will be identified as 'Custom:mypb'.
To make PHOEBE automatically load the passband, it needs to be added to one of the passband directories that PHOEBE recognizes. If there are no proprietary aspects that hinder the dissemination of the tables, please consider contributing them to PHOEBE so that other users can use them.
Can you write Python code for it?