Musings

I'm just copying my father

Home

### revisiting-rebelfit-2026

Revisiting RebelFit in 2026

First Published: 2026 June 22

Prereading note: this is very rotational spec heavy and very rambly... readers be advised.

Addendum to Draft 1: 22 June 2026

Ok so below I said that there’s no way to guarantee bounds of the values for A, B, and C given nothing but I, but I think that there is.

We know that I is defined as the inverse sum of A, B, and C. We know that A is greater than or equal to B is greater than or equal to C. So if we assume A and B are both infinite, then that means that C would have to equal 1/I. If B is anything less than infinite, than C is not going to be 1/I. It instead equals 1/(I - 1/B).

If, by contrast, 1/C is less than I, then C is greater than 1/I, because A, B, and C all must be greater than 0, and so subtracting 1/B will make I smaller, which makes 1 divided by larger. Great.

So A greater than or equal to B greater than or equal to C. If A and B are not infinite, then the smallest possible value they can have is C. From that, we get that the value of C becomes I/3 = 1/C.

So, we can find lower bounds on A, B. A cannot be lower than that, and B cannot be lower than I/2=1/B.

There’s not really a way to calculate upper bounds except that if we take a random value of C, it’s almost certainly going to be less than I1. Oh, I guess one option could be that in the initial sample given only mass, we assume there’s a way to get I from that, give it arbitrary error bars, and then sample the asymmetry number from 0 to 1, using that to calculate the max and min values for C, then B, which gets us A.

That seems fun enough!

This does, of course, assume that we can estimate the molar mass of a molecule. Let’s see, if we assume a molecule is a sphere, then I=2/5MR squared. Ope, what’s R? Eh, we can start with a basic assumption that R would be 1 per carbon in the largest chain?

Let’s see, for the molecule I researched, this assumes some values that I’m not feeling like calculating.

Eh, I think it’s reasonable enough to demand at least A, B, C (or X, Y, Z) at the very start of the program for now. Most people are running fairly high-level calculations, and so they should be able to calculate them relatively easily. From there, there’s probably a better way to estimate the difference, but I’m generally going to go with if the absolute asymmetry is greater than .25, assume that it’s from half to 1.5 the asymmetry. Otherwise, assume that it’s within .25 of 0.

Oh, wait, what about the whole “I have ray’s asymmetry to play with”?

I think that it could be fun to set Ray’s, I, and then C. What would that do?

It should uniquely define A and B, since Ray’s asymmetry parameter uses A, B, C and so does I. Three equations, three unknowns and all. Hmm.

Maybe that’s something to hand-write out, because I know that the equation is something like 2B-A-C/(A-C). So then if we assume that it, I, C all independent (for now), can get I = 1/A - 1/C - 1/B, A = 1/(I-1/C-1/B). Define I-1/C = X and we get A = 1/(X-1/B), and for shorthand, 1/n = N and vice versa. A = 1/(X-b).

Then we plug that in to the above, and we get 2B-1/(X-b)-C/((1/X-b)-C), has a single value since we know the other side of the equation.

Define ray’s as r: 2B-A-C/(A-C) = r, r(A-C) = 2B-A-C, 2B = rA-rC+A+C= (r+1)A- (r-1)C. Since we can express A in terms of B and C and I, we can get out B, and then we can plug in anywhere to get A again. Or, what if we try solving for B instead of A, then 2/(X-a)=r+1 A - r-1 C, 2 = (X-a)(r+1...)... yeah that’s still a pain and a half, but it is theoretically doable, which is really what matters. Especially if I put vague limits on ray’s and I, I don’t really know how much I need to limit A, B, and C. That’s kinda fun! Is there some equivalent truth for distortion constants? Probably not, but that’s ok.

I guess, there’s something to be said for the idea that like the higher X, Y, or Z is, the more likely it is to distort? So then is there a way to limit deltaX, deltaY, or deltaZ, or more difficultly, deltaXY etc.?

I don’t think so, but again, that’s a question for another time. Maybe I just say 1 percent but it’s a soft bound2.

Is this really an addendum?

Not really so much any more, alas. I feel very very sorry for everyone reading this.

Draft 1: 22 June 2026

So, I really want to get back into the spectral fitting program which made up the bulk of my Ph.D. dissertation. My biggest let downs with the project as it stood then were:

The other major features that I would want to add to the program to call is something to be proud of:

So, how would I resolve this?3

Let’s start with the first issue: calling the catalog generating program a number of times. This is not a new issue in the field of rotational spectroscopy. Since before even this program was created4, there have been methods to approximate the value of the energy levels in a way that can be pre-computed. If I remember correctly, three-ish gigabytes is the storage needed to solve the primary rotational constants to basically floating point error. It also only took like twenty minutes to generate, and that gives all possible values of the rotational constants. Since RebelFit works within a range of values, that takes far less time. Still, thinking about the optimization part of it should come later. For now, let’s talk through what I would need to solve in order to get this to work.

  1. Showing that SPCAT A, B, C and a hard-coded (read: manually solved (read: I put in the math and make my computer solve it)) A, B, C produce the same transition locations

  2. Showing that SPCAT A, B, C and hand-solved X, Y, Z lead to the same transition locations

  3. Showing that SPCAT A, B, C and A reduction lead to the same transitions as hand-solved A, B, C (or X, Y, Z) and A reduction

  4. Showing that SPCAT A, B, C and A reduction lead to the same transitions as hand-solved X, Y, Z and Watson T reduction5

  5. Showing that hand-solved X, Y, Z match up to the approximation version for X, Y, Z

  6. Showing that hand-solved X, Y, Z and T match up to the approximation version for X, Y, Z and rho6

  7. Showing that SPACT A reduction matches the approximation version

  8. Reading and using the paper that defines transition intensity to match the approximation to the SPCAT intensities7.

  9. Ensuring that this new version is actually faster than the old version

  10. Hopefully don’t need to repeat to get the S-reduction available

  11. Something something make it work for other forms of distortion8

Since I’m often told something that my writing9 lacks is connection between fact and conclusion, let’s motivate each step.

  1. SPCAT A B C matching computed A B C.

    This is in theory not a step that I actually need to do. These are mathematically identical. However, I’ve tried to read the SPCAT source code before and I have legitimately no idea what it’s doing. Three rotational constants is easy enough that I should be able to do the coding for it in a few seconds, and then the issue is just having SPCAT run a few times. In general, I probably want it to run one very oblate, one very prolate, and one that’s just basically intermediate.

  2. SPCAT A B C matching computed X Y Z

    So, in general, rotational spectra are solved using A, B, C rotational constants. However, computational chemists are more likely to use X, Y, Z. There are10 six ways to pair X, Y, Z to A, B, C. So long as I match them appropriately, this should take moments at best to verify.

    Given that I think it’s trivial to verify, why do it? A few reasons:

    Once we ensure that we can reliably match the rigid rotor to the SPCAT rigid rotor, it becomes important to match them with reductions. There’s a slight hiccup here, which is that A, B, C in rigid rotor world are not, as it turns out, the same as A, B, C in A reduction world. As I write this, I am a little curious if that’s the issue that I’m running into or was running into, at least, when I last worked on this.

  3. Showing that SPCAT A, B, C and A reduction lead to the same transitions as hand-solved A, B, C (or X, Y, Z) and A reduction

    So, this is better named as three different steps:

    Since realistically, I don’t really want to manually compute these values, I’m likely going to have to trust that the values are as linearly interconvertible as I remember that they should be. In practice, this calculation is way more computationally expensive, because the Hamiltonian gets much more complex. Then again, since it remains a numeric matrix, computers do, in fact, go brrr.

    Assuming that I get this, I have more or less proved to myself that SPCAT and real Hamiltonians result in the same transitions.11

  4. Showing that SPCAT A B C and A quartic match the computed X Y Z and Watson T12 transitions.

    The ultimate goal here is to use the approximate form of the rotational Hamiltonian that Watson outlines. Watson gives his T values in terms of A quartics and in terms of the approximate quartics. While I’m sure that there’s a better way to solve for them, I don’t entirely know what they would be.

    Two questions to try here are giving SPCAT values and back solving for T values, and giving T values and feeding SPCAT the T values.13

    If this works out, then I have confirmed for myself that I can, in fact, solve five equations for five variables. Also, it makes it easier to test the next parts.

    At this point, I luckily no longer need to use SPCAT, which means that I get to save the half a gigabyte of storage that computing transitions takes up on my computer. That’s probably offset by the amount of memory that my computer is using, but that’s not something I have to manually clear, which is great.

  5. Showing that hand-solved X Y Z match approximate A B C

    Again, this should be relatively straightforward. At this point I don’t really care too much about the transition energies14, and so can just compare matrix outputs.

    I’ll probably want to generate a representative sample of values, just to be certain15.

    Above I had this listed as approximate X Y Z, but I’m like 99 percent certain that the approximate value calculation relies on A B C. In theory, though, it’s incredibly straightforward to match X Y Z to A B C, so again, that’s not a huge concern

  6. Showing that hand-solved X Y Z and quartic distortion (either A or T, since we’ve demonstrated interchangibility) match approximate distortion form (most likely using the Watson approximate distortion)

    This one is likely to be the painful portion, if only because I’ll need to be really clear whether I’m working with A(A) or A. Then again, assuming that I calculate out the values for the hand-solved exact version, I can also play around with different options and versions within the approximate form. At the very least, it’s something that I can try!

    If this works out, then I’ve (through the transitive property) shown that the approximate version of the rotational constants matches the SPCAT output for quartic centrifugal distortion. Sextic distortion at that point should go really quickly.16

  7. Showing that SPCAT A and approximate match up

    Having tested the intermediary, I’ll throw the program against what most people would use: SPCAT itself. Issue here will be again, ensuring that I’m using the right versions of each constant.

  8. Showing that I can also calculate rotational transition intensity

    There’s, as far as I can tell, basically a single paper that people use for determining the transition intensity of a rotational transition. I’ll read the literature a little more to make sure that’s true17, and then have the calculations run given the arbitrary constants and some arbitrary values for the dipoles.

    Realistically, as long as they more or less approximate the values that SPCAT uses, I’m totally happy. SPCAT is known to produce approximate transition intensities, and so that’s so totally fine with me if mine is approximate as well. One issue I’m foreseeing is that calculating transition intensities requires population analysis, which is temperature dependent. My assumption is this is where most of SPCAT’s runtime actually occurs, and so that’s not great.18 Then again, it’s also likely something that I can extrapolate to a general form when solving the Hamiltonian a million times.

    E.g. if I solve the relative population as a function of energy one time at the start of the run (or for all energies before a run), then all I really have to do is use a lookup table! (Assuming that this is the right way of viewing the problem. I forget whether the exponent has other funky things)

  9. Ensuring that this new version is actually faster than the old version

    Since we need to solve for energy levels, it’s possible that a single run may be much slower. When doing one hundred runs, however, I cannot believe that it would be anything but far faster. When doing more than ten thousand runs, there’s no chance that it’s not faster.19

  10. Hopefully don’t need to repeat to get the S-reduction available

    The A and S reductions are the most popular ways to solve a centrifugally distorted rotor. Having done all the work to make A work, I’m assuming that the work to make S work will be trivial, especially because A and S reductions are interconvertible.

  11. Something something make it work for other forms of distortion20

    There’re other forms of distortion that people care about. A lot of the research Hamiltonians focuses on these complex issues, especially because most easy molecules have been solved. Then again, there are still a number of molecules with no rotors or unpaired electrons, so there’s every chance people would jump on the promise of more or less instant solving.

How do I make the Latin Capped Hyperspherework? Few steps21:

  1. Figure out how to pick the n+1 sample space based on the output of the n sample space.

  2. Ensure that the powers of two are all lined up, because in the past I’m fairly sure I wasn’t letting it search as far

  3. Ensure that it works to converge on the right answer

Let’s motivate the Latin Capped Hypersphere:

There’s a relatively recent paper that argues a better way to sample astronomical observations is via Hypersphere, rather than Hypercube. The main argument comes down to the fact that a hypersphere inscribed in a hypercube takes up vanishing amounts of the hypervolume at higher dimensions. If I remember correctly, it’s something like 1 percent the hypervolume by ten dimensions.

So, if one is relatively confident in their center point, then there’s effectively a hundred-fold increase in sampling density within the reasonable area by using a hypersphere rather than a hypercube.

My own personal motivation for capped hypersphere is that it feels somewhat rational. That is, I’m fairly sure that, at early levels of solving the rotational Hamiltonian, there is no real assumption that the center point is correct, so a Hypercube is the appropriate choice. When approaching the correct answer, however, the displacement that a transition needs is well-correlated to multiple values, and so searching around the near space makes the most sense.

As I write this, though, I’m realizing that I’m already intending to include multiple forms of distortion constants so that I can have for the distortion what I have for A, B, C: something which imposes constraints on the pure sample space. That’s pretty exciting to me, and likely will be exciting enough to others.

There’s a question in my mind about whether to use the limiting values based on A, A(A) and A(S) or not. I think that it could make sense to truncate the distortion constant ranges based on them, but not so much A, B, C. Mostly that’s because it feels rational to me that the “pure” rotational constants would be better able to be found than the distorted ones, but maybe that’s not true!

Ugh, then we get into the hard issue of “given that A(A) depends on A, Delta J, and Delta JK22, what is the actual variable values of A given the bounds of A(A), the bounds of Delta J, and the bounds of Delta JK?” I don’t know that this would actually be too much of an issue, but it kind of feels like it would be.

Let’s assume not.

So, the ending sample space would have nine dimensions: X, Y, Z, XX, XY, XZ, YY, YZ, ZZ. That is, the rotational constant in X, Y, Z and the six quartic distortion constants. From there, we would sample I (real), which is defined as the sum of 1/X or Y or Z (real). I think that’s the best one to choose as our defining value, because it’s the one that’s most physically meaningful. Regardless of the representation we use or whether we ensured all inertia is along axes, it feels reasonable to assume we can know the total moment of inertia.

After I (real), we’d sample C (real). C (real) would be limited by the maximum of:

and the minimum of basically the above.

We now have two of nine dimensions sampled. Since sampling either of A or B gives the other for free26, let’s see what we’d do there. Lower bound of A27 is the largest of:

Oh wait, can I ignore A(X) for sampling C? That’s something I think that I need to think through more... I think so, but I don’t feel confident.

Let’s see, if we assume C max, then the possible ranges for A are dependent on that, and therefore so are the possible values for A(X). Is it possible that C max defines a value of ranges for A which, given the ranges for distortion, are not possible for A(X)? Mathematically it sure seems like it! Maybe. Given that we know that C max has to have an available value for A, I have to assume that it would never end up breaking. Still, probably good to ensure that it’s true for realsies. Maybe I throw that calculation in the C(X) calculations, though.

That’s a question for future distortion me.

So three variables later, we have (effectively) X, Y, Z and A, B, C.

From there, we know that each of the five distortion constants can be calculated based on some linear combination of the six real distortion constants.28

Set each constant based on its limit given itself, the bounds of the other constants in each X, and the bounds for A(X), B(X), and C(X).

This goes point-wise, and creates a really weird sample space after the first hypercube. At some point want to set it to re-open, though that’s again a question as to when. Also, what are the starting ranges?

Part of me wants to go fully computing and say “we have no idea what literally any value can be”, part of me thinks that maybe asking the person for reasonable bounds would work, and part of me thinks that like starting at 1 percent of A, B, and C for distortion constants feels reasonable as an absolute limit? Or as a starting limit if not entered.

Realistically, all that would need to be input is a range for I and a range for C. I’m sure that one can reasonably well approximate the moment of inertia of a molecule based on just its molecular mass. And then let’s see, we know that C is greater than B is greater than A.  If all of the mass is in the C direction, then it’s value will be 1/I, and B will equal A will equal infinity. That’s not super helpful.

We could try asking for an approximate level of non-prolateness29, or we could just set arbitrary bounds and let people manually set bounds if they’d rather. As a scientist, it’s always frustrating to me when a modeling software30 doesn’t let me set arbitrary bounds. Exactly what the default set of inputs I’ll require and outputs I’ll give will be, that’s a question for the implementation team.

I do kind of feel inspired by the idea of using something with expected values. E.g. instead of a Latin hypercube, do an orthogonal search31 based on the empirical CDF from the previous search. Maybe somehow have like increase the orthogonalization as the dimension searched increases?

Or something like “the more that the optimal value for a constant moved, the more/less to use orthogonal search?”

I just generally don’t like the current method of take the top 532 points and use them to define the new sample space. It feels ugly, and even if it worked in the sample molecule, it still failed a fair number of times overall. So, let’s come back to the question of rebounding later, once we’ve got the question of sampling down.

Oh wait, those two are kind of linked questions.

Eh, maybe a distribution with a floor function?  That is, less than some percentage of our maximum strength just doesn’t count?

I know that in the past, using previous values resulted in bad outcomes because one lucky guess would just forever fix the current values. I do still believe in the fundamental stability of the correct answer and the cheapness of computation. Throwing out a previous run’s values upon generating the next run does still feel pretty ok to me, especially if I store them for later use.

Part of me does still think about the question of the total hyper-radius, as much as that makes sense as a concept. Eh, that’s a problem for V2.

Upcoming Posts

Daily Reflection: 22 June 2026


  1. read: I can at the very least demand that

  2. read: the values can keep growing forever if they really want, rather than adding a check that it doesn’t escape the limits

  3. for those asking why I write this here, rather than just doing the work, mostly it’s that I had a script that had most of the tests and hard-written math pre-coded in it that somehow (read: when I purged my computer, being done with graduate school), didn’t make it to my current computer setup. When I return to the campus wifi, I do plan to try to find it again.

  4. I think, don’t fact check this claim right now

  5. which he calls the more interesting reduction iirc. There’s equations he gives which have T1 in delta X etc. format, but not vice versa. I’m like 40 percent sure that I did that in my thesis though

  6. I think? Watson introduces distortion constants that use the approximation, though I forget where

  7. within a few orders of magnitude and in relative accuracy. E.g. if it’s all off by a flat factor, that’s fine, because it’s all relative strength anyways

  8. admittedly, this is a dream step

  9. at least, my academic writing

  10. shockingly

  11. and if they don’t, I am very concerned, because they REALLY should, or someone else in the field should’ve caught it in the last three decades

  12. my naming

  13. which is also true above, now that I think about it

  14. which I only cared about because that’s the output format that SPCAT uses. I’m almost positive that nearly all of the computational time comes from computing these values also

  15. and also to make sure that I can plug in arbitrary values for A, B, C and know it will work

  16. I am manifesting this for myself

  17. read: look at the WesterFit paper and see if they use anything else

  18. then again, there’s also likely a fair amount of time spent manually writing the file with all of the data it uses

  19. ok at one second per SPCAT call, if it takes 30 minutes to generate the full array, that’s 1800 seconds, so yeah that’s absolutely going to save time

  20. admittedly, this is a dream step

  21. is this post just going to be five thousand or so words of me rambling about the research I could be doing? ...yeah, if it’s taken this long for you to notice, I’m very sorry

  22. or something

  23. X here meaning “arbitrary version of C”

  24. because I(X) feels icky for some reason I can’t fully articulate

  25. or, I think that I might forcibly move I such that its bounds are possible... that’s something to consider, if there’s a way to balance I being able to converge with the fact that like, I do want to explore A, B, C. Eh.

  26. in theory

  27. biggest number

  28. n.b. in real life, we are unable to mathematically uniquely identify values for the six distortion constants based on transitions, we can only get five values out. That’s why we use five distortion constants in the reductions. They’re mathematically equivalent, just one is unique and one is not guaranteed to be. I’m pretty sure that by using the deltas and d’s (the S reduction uses d), we’ll be able to make unique sets, but maybe not! It’ll be fun to find out! That’s for sure.

  29. I forget the term for that value

  30. which RebelFit arguably is

  31. difference is that the Latin hypercube only uses end points, while an orthogonal search uses a weighted distribution

  32. iirc

  33. stolen from a prior list

  34. see the above post, I guess

  35. admittedly, very tentative