✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

✨ Developing PerturbationMatrix class - #59

Merged
christinahedges merged 27 commits into
masterfrom
refactor-time
Apr 18, 2022
Merged

✨ Developing PerturbationMatrix class#59
christinahedges merged 27 commits into
masterfrom
refactor-time

Conversation

@christinahedges

@christinahedgeschristinahedges commented Mar 30, 2022

Copy link
Copy Markdown
Contributor

This PR is for developing a new PerturbationMatrix class which will ultimately factor our a lot of the headaches we're having inside machine

To Do

  • Documentation (docstrings!)
  • Merge into machine.py
  • Write some tests for Kepler/K2/TESS data

@christinahedgeschristinahedges added the enhancement New feature or request label Mar 30, 2022
@christinahedges

Copy link
Copy Markdown
ContributorAuthor

Roughly how to use:

If flux and flux_err are arrays with dimensions (ntimes x npixels)

P=PerturbationMatrix3d(time=time, dx=dx, dy=dy)
P.fit(flux, flux_err)
model=P.model()

model will then also have (ntimes x npixels)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I think the basic functionalities are implemented here.

Something that will be good to have is a pixel_mask argument in PerturbationMatrix3D so we can create matrix with the source_mask (for fitting) pixels and the uncontaminated_source_mask (for building) in one perturbation object.

I did a couple of "performance" test with TPF data and turned out that the self.model method runs really slow, about 1.7 sec/iter. We need to find why this is so slow.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadtests/test_perturbation.py
Comment threadsrc/psfmachine/perturbation.py
Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@jorgemarpajorgemarpa mentioned this pull request Apr 6, 2022
5 tasks
@christinahedgeschristinahedges changed the title [WIP] ✨ Developing PerturbationMatrix class✨ Developing PerturbationMatrix classApr 8, 2022
@christinahedges

christinahedges commented Apr 11, 2022

Copy link
Copy Markdown
ContributorAuthor

I added a PCA method so you can do something like:

y= [whitened_timeseries, whitened_timeseries]
p=PerturbationMatrix(...)
p.pca(y, ncomponents=10)
p.fit(y)

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christinahedges I found the bug with the inconsistent shape when doing self.model(). The problem is when using PerturbationMatrix through PerturbationMatrix3D that some attributes from the latter are not updated to reflect the addition of PCA components in self.vectors. See my comments for more details.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment threadsrc/psfmachine/perturbation.py Outdated
@christinahedges

christinahedges commented Apr 12, 2022

Copy link
Copy Markdown
ContributorAuthor

Any vectors that aren't the time polynomial are now set to zero mean in each "segment" during _clean_vectors method. The pca method can now be repeated and it will just update the pca components, not append ad infinitum

Comment threadsrc/psfmachine/perturbation.py Outdated
Co-authored-by: Jorge Martínez-Palomera <jorgemarpa@users.noreply.github.com>

@jorgemarpajorgemarpa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested a handful of component combinations and other parameters to check the matrices look Ok.
It fulfills what we always thought about the perturbation matrix API.

I just added a couple of comments regarding docstrings. Besides those, I think this is ready to be merged.


return func

def pca(self, y, ncomponents=5, smooth_time_scale=0):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be consistent with the rest

Suggested change
defpca(self, y, ncomponents=5, smooth_time_scale=0):
defpca(self, y, ncomponents=3, smooth_time_scale=0):

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +301 to +302
Will add two time scales of principal components, definied by `long_time_scale`
and `med_time_scale`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Willaddtwotimescalesofprincipalcomponents, definiedby`long_time_scale`
and`med_time_scale`.

Comment threadsrc/psfmachine/perturbation.py Outdated
Comment on lines +310 to +316
long_time_scale: float
The time scale where variability is considered "long" term. Should be
in the same units as `self.time`.
med_time_scale: float
The time scale where variability is considered "medium" term. Should be
in the same units as `self.time`. Variability longer than `long_time_scale`,
or shorter than `med_time_scale`, will be removed before building components

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the scale of smooth_time_scale?

Suggested change
long_time_scale: float
Thetimescalewherevariabilityisconsidered"long"term. Shouldbe
inthesameunitsas`self.time`.
med_time_scale: float
Thetimescalewherevariabilityisconsidered"medium"term. Shouldbe
inthesameunitsas`self.time`. Variabilitylongerthan`long_time_scale`,
orshorterthan`med_time_scale`, willberemovedbeforebuildingcomponents
smooth_time_scale: float
Amounttosmooththecomponents, usingasplineintime.
If0, thecomponentswillnotbesmoothed.

Comment on lines +136 to +154
# def _clean_vectors(self):
# """Remove time polynomial from other vectors"""
# nvec = self.poly_order + 1
# if self.focus:
# nvec += 1
# if self.segments:
# s = nvec * (len(self.breaks) + 1)
# else:
# s = nvec
#
# if s != self.vectors.shape[1]:
# X = self.vectors[:, :s]
# w = np.linalg.solve(X.T.dot(X), X.T.dot(self.vectors[:, s:]))
# self.vectors[:, s:] -= X.dot(w)
# # Each segment has mean zero
# self.vectors[:, s:] -= np.asarray(
# [v[v != 0].mean() * (v != 0) for v in self.vectors[:, s:].T]
# ).T
# return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can still keep this function in case we want to remove the temporal trend for other components. But it isn't necessary with the current API.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestready-to-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@christinahedges@jorgemarpa