|
14 | 14 | "InjectMapStub", |
15 | 15 | "InjectMaps", |
16 | 16 | "ReplicateMaps", |
| 17 | + "InvertMaps", |
| 18 | + "InvertAlternatingMaps", |
| 19 | + "RescaleMaps", |
17 | 20 | "CoaddMaps", |
18 | 21 | "RebinMaps", |
19 | 22 | "ReprojectMaps", |
@@ -238,6 +241,10 @@ def MakeMapsPolarized(frame, pol_conv=maps.MapPolConv.IAU): |
238 | 241 | def MakeMapsUnpolarized(frame): |
239 | 242 | """ |
240 | 243 | Converts individual polarized maps to temperature-only versions of the same map. |
| 244 | +
|
| 245 | + This is done by simply dropping the Q and U Stokes terms from the input frame. |
| 246 | + To ensure that the resulting T component is free of polarization, use the |
| 247 | + ``RemoveWeights`` pipeline module before this module. |
241 | 248 | """ |
242 | 249 | if "Wpol" not in frame: |
243 | 250 | return |
@@ -581,6 +588,113 @@ def ReplicateMaps(frame, input_map_id, output_map_ids, copy_weights=False): |
581 | 588 | return frames |
582 | 589 |
|
583 | 590 |
|
| 591 | +@core.indexmod |
| 592 | +def InvertMaps(frame): |
| 593 | + """ |
| 594 | + Invert T, Q, U maps in the input map frame. |
| 595 | + """ |
| 596 | + if isinstance(frame, core.G3Frame) and frame.type != core.G3FrameType.Map: |
| 597 | + return |
| 598 | + |
| 599 | + for k in "TQU": |
| 600 | + if k in frame: |
| 601 | + m = frame.pop(k) |
| 602 | + m *= -1.0 |
| 603 | + frame[k] = m |
| 604 | + |
| 605 | + return frame |
| 606 | + |
| 607 | + |
| 608 | +@core.indexmod |
| 609 | +class InvertAlternatingMaps: |
| 610 | + """ |
| 611 | + Invert T, Q, U maps in every other input map frame. |
| 612 | + """ |
| 613 | + def __init__(self): |
| 614 | + self.flip = False |
| 615 | + |
| 616 | + def __call__(self, frame): |
| 617 | + if frame.type != core.G3FrameType.Map: |
| 618 | + return |
| 619 | + |
| 620 | + if self.flip: |
| 621 | + InvertMaps(frame) |
| 622 | + self.flip = not self.flip |
| 623 | + |
| 624 | + return frame |
| 625 | + |
| 626 | + |
| 627 | +@core.indexmod |
| 628 | +def RescaleMaps(frame, t_scale=None, q_scale=None, u_scale=None, scale_weights=True): |
| 629 | + """ |
| 630 | + Rescale input map frame using the supplied calibration factors for each |
| 631 | + Stokes component. If the maps are weighted, the T, Q, and U components are |
| 632 | + divide the appropriate scale factor. If the maps are unweighted, the Stokes |
| 633 | + components are multiplied by the appropriate scale factor. If weight maps |
| 634 | + are present in the frame, each weight component is divided by the product of |
| 635 | + the scale factors that make up each weight component. In this way, calling |
| 636 | + ``RemoveWeights`` on the map frame resulting from this module should produce |
| 637 | + an unweighted map that has been multiplied by the input scale factors. |
| 638 | +
|
| 639 | + Arguments |
| 640 | + --------- |
| 641 | + t_scale : float |
| 642 | + q_scale : float |
| 643 | + u_scale : float |
| 644 | + Scale factor to apply to each Stokes component in the maps and weights. |
| 645 | + If not supplied, assumed to be unity. |
| 646 | + scale_weights : bool |
| 647 | + If True, apply the appropriate scale factor to the weights as well. |
| 648 | + Otherwise the scale factors are only applied to the T/Q/U maps. |
| 649 | + """ |
| 650 | + if isinstance(frame, core.G3Frame) and frame.type != core.G3FrameType.Map: |
| 651 | + return |
| 652 | + |
| 653 | + ValidateMaps(frame) |
| 654 | + |
| 655 | + t_scale = t_scale if t_scale is not None else 1.0 |
| 656 | + q_scale = q_scale if q_scale is not None else 1.0 |
| 657 | + u_scale = u_scale if u_scale is not None else 1.0 |
| 658 | + |
| 659 | + weighted = frame["T"].weighted |
| 660 | + |
| 661 | + scales = { |
| 662 | + "T": t_scale if weighted else 1. / t_scale, |
| 663 | + "Q": q_scale if weighted else 1. / q_scale, |
| 664 | + "U": u_scale if weighted else 1. / u_scale, |
| 665 | + } |
| 666 | + |
| 667 | + for k, scale in scales.items(): |
| 668 | + if scale == 1.0: |
| 669 | + continue |
| 670 | + if k in frame: |
| 671 | + m = frame.pop(k) |
| 672 | + m /= scale |
| 673 | + frame[k] = m |
| 674 | + |
| 675 | + if scale_weights: |
| 676 | + wscales = { |
| 677 | + "TT": t_scale * t_scale, |
| 678 | + "TQ": t_scale * q_scale, |
| 679 | + "TU": t_scale * u_scale, |
| 680 | + "QQ": q_scale * q_scale, |
| 681 | + "QU": q_scale * u_scale, |
| 682 | + "UU": u_scale * u_scale, |
| 683 | + } |
| 684 | + |
| 685 | + wkey = "Wpol" if "Wpol" in frame else "Wunpol" if "Wunpol" in frame else None |
| 686 | + if wkey is not None: |
| 687 | + weights = frame.pop(wkey) |
| 688 | + for k, scale in wscales.items(): |
| 689 | + if scale == 1.0: |
| 690 | + continue |
| 691 | + if k in weights.keys(): |
| 692 | + weights[k] /= scale |
| 693 | + frame[wkey] = weights |
| 694 | + |
| 695 | + return frame |
| 696 | + |
| 697 | + |
584 | 698 | @core.indexmod |
585 | 699 | class CoaddMaps(object): |
586 | 700 | """ |
|
0 commit comments