Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete Laser Definition/Unclear Abstraction #105

Open
psktam opened this issue Jan 9, 2023 · 0 comments
Open

Incomplete Laser Definition/Unclear Abstraction #105

psktam opened this issue Jan 9, 2023 · 0 comments

Comments

@psktam
Copy link
Collaborator

psktam commented Jan 9, 2023

I was taking a look at a code sample to familiarize myself with how the stuff in this repo is used. One thing caught my eye on how it seems like lasers are defined:

laser = Laser(k=x̂, ϵ=ŷ)
chain = LinearChain(ions=[ion],
                    com_frequencies=(x=3e6,y=3e6,z=1e6),
                    vibrational_modes=(;z=[1]))
trap = Trap(configuration=chain, B=4e-4, Bhat=ẑ, δB=0, lasers=[laser])
Efield_from_pi_time!(2e-6, trap, 1, 1, ("S", "D"))
laser.λ = transitionwavelength(ion, ("S", "D"), trap)

The laser variable is partially instantiated at first because of the way that the E-field and wavelength are derived properties from the trap variable. But the trap variable itself needs to know which way the laser is pointing in the first place.

This is a little awkward and is vulnerable to regression because it requires that users of the code remember to "circle back" and remember to set these parameters in order to fully define the struct after it's been created.

I think two things need to happen here.

Item 1: Reduce Laser Struct to Inherent Properties of Laser Light

I think we can reduce the Laser struct down to these properties:

  • λ: wavelength
  • E: E-field magnitude (make this strictly a function)
  • ϵ: polarization direction
  • k: propagation direction
  • ϕ: phase

Note that the pointing property has been removed. I thought this was the correct thing to do, because setting that property requires that you have knowledge of the trap ahead of time that it's going to be associated with, which breaks the abstraction. (after all, why can't you use the same laser on different traps?)

I also removed Δ from the proposition above, because it seems that property is also associated with the environment the laser is part of (ie: not inherent to the laser). Please correct me if I'm wrong about that.

Item 2: Create Dedicated Constructors for Different Contexts

With the struct definition in item 1, we can rewrite the code example to look like this instead:

# Define your individual components up here first.`
magnetic_field = MagneticField(
    B=4e-4, 
    Bhat=ẑ, 
    δB=0   
)
chain = LinearChain(ions=[ion],
                    com_frequencies=(x=3e6,y=3e6,z=1e6),
                    vibrational_modes=(;z=[1]))
laser = build_laser_from_pi_time_and_transition(
    k=x̂,                        # Laser is built with a custom constructor
    ϵ=y,                        # that is purpose-built for defining the 
    pi_time=2e-6,               # E-field and wavelength from the ion it's
    ion=ion,                    # pointing at. If there are other 
    transition=("S", "D"),      # ways you need to infer these or different
    B=magnetic_field            # parameters, it's just a matter of defining
)                               # new constructors.

# Now you can create your trap here at the very end by putting them all
# together. No more need to "circle back". Everything should be fully 
# defined by this point.
trap = Trap(
    configuration=chain,
    B=magnetic_field,
    lasers=[laser],
    pointing_configuration={
        laser: [(1.0, ion)]
    }
)

Note that this example also implies the creation of a new struct for magnets.

The function build_laser_from_pi_time_and_transition is just a custom constructor that fits this specific purpose of inferring the E-field and wavelength from the pi time and the ion transition you're exciting. There are perhaps other contexts in which you would want to build the laser with different input parameters. And all you'd have to do in those cases is define new constructors for those circumstances.

Also note that the pointing property that used to belong to the laser has now moved to the trap, and it is a dictionary that maps each laser to a list of ions that it points to, annotated with the modifiers that you use to indicate how strongly incident each laser is on each ion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant