@@ -421,6 +421,8 @@ def makeFigureAndAxes(nrows=2) -> tuple[Figure, Any]:
421421def plotData (
422422 axs : npt .NDArray [np .object_ ],
423423 table : Table ,
424+ maxPointsPerDetector : int = 60 ,
425+ minPointsPerDetector : int = 5 ,
424426 prefix : str = "" ,
425427) -> None :
426428 """Plot the data from the table on the provided figure and axes.
@@ -431,38 +433,61 @@ def plotData(
431433 The array of axes objects to plot on.
432434 table : `astropy.table.Table`
433435 The table containing the data to be plotted.
436+ maxPointsPerDetector : `int`, optional
437+ The maximum number of points per detector to plot. If the number of
438+ points in the table is greater than this value, a random subset of
439+ points will be plotted.
440+ minPointsPerDetector : `int`, optional
441+ The minimum number of points per detector to plot. If the number of
442+ points in the table is less than this value,
443+ all points will be plotted.
434444 prefix : `str`, optional
435445 The prefix to be added to the column names of the rotated shapes.
436446 """
447+ tableDownsampled = randomRowsPerDetector (table , minPointsPerDetector )
448+ table = randomRowsPerDetector (table , maxPointsPerDetector )
449+
437450 x = table [prefix + "x" ]
438451 y = table [prefix + "y" ]
439452 e1 = table [prefix + "e1" ]
440453 e2 = table [prefix + "e2" ]
441454 e = table ["e" ]
442455 fwhm = table ["FWHM" ]
443456
457+ xDownsampled = tableDownsampled [prefix + "x" ]
458+ yDownsampled = tableDownsampled [prefix + "y" ]
459+ e1Downsampled = tableDownsampled [prefix + "e1" ]
460+ e2Downsampled = tableDownsampled [prefix + "e2" ]
461+ eDownsampled = tableDownsampled ["e" ]
462+
444463 # Quiver plot
445- quiver_kwargs = {
464+ quiverKwargs = {
446465 "headlength" : 0 ,
447466 "headaxislength" : 0 ,
448467 "scale" : QUIVER_SCALE ,
449468 "pivot" : "middle" ,
450469 }
451470
452- shape_angle = 0.5 * np .arctan2 (e2 , e1 ) # spin-2
453- Q_shape = axs [0 , 0 ].quiver (x , y , e * np .cos (shape_angle ), e * np .sin (shape_angle ), ** quiver_kwargs )
454- axs [0 , 1 ].quiverkey (Q_shape , X = 0.08 , Y = 0.95 , U = 0.2 , label = "0.2" , labelpos = "S" )
471+ shapeAngle = 0.5 * np .arctan2 (e2Downsampled , e1Downsampled ) # spin-2
472+ qShape = axs [0 , 0 ].quiver (
473+ xDownsampled ,
474+ yDownsampled ,
475+ eDownsampled * np .cos (shapeAngle ),
476+ eDownsampled * np .sin (shapeAngle ),
477+ ** quiverKwargs ,
478+ )
479+ axs [0 , 1 ].quiverkey (qShape , X = 0.08 , Y = 0.95 , U = 0.2 , label = "0.2" , labelpos = "S" )
455480
456481 # FWHM plot
457- cbar = addColorbarToAxes (axs [0 , 1 ].scatter (x , y , c = fwhm , s = 5 ))
482+ cbar = addColorbarToAxes (axs [0 , 1 ].scatter (x , y , c = fwhm , s = 1 ))
458483 cbar .set_label ("FWHM [arcsec]" )
459484
460485 # Ellipticity plots
461486 emax = np .quantile (np .abs (np .concatenate ([e1 , e2 ])), 0.98 )
462- axs [1 , 0 ].scatter (x , y , c = e1 , vmin = - emax , vmax = emax , cmap = "bwr" , s = 5 )
487+ axs [1 , 0 ].scatter (x , y , c = e1 , vmin = - emax , vmax = emax , cmap = "bwr" , s = 1 )
463488 axs [1 , 0 ].text (0.05 , 0.92 , "e1" , transform = axs [1 , 0 ].transAxes , fontsize = 10 )
464489
465- cbar = addColorbarToAxes (axs [1 , 1 ].scatter (x , y , c = e2 , vmin = - emax , vmax = emax , cmap = "bwr" , s = 5 ))
490+ cbar = addColorbarToAxes (axs [1 , 1 ].scatter (x , y , c = e2 , vmin = - emax , vmax = emax , cmap = "bwr" , s = 1 ))
466491 cbar .set_label ("e" )
467492 axs [1 , 1 ].text (0.89 , 0.92 , "e2" , transform = axs [1 , 1 ].transAxes , fontsize = 10 )
468493
@@ -511,6 +536,7 @@ def plotHigherOrderMomentsData(
511536 table : Table ,
512537 prefix : str = "" ,
513538 binSpacing : float = 0.1 ,
539+ maxPointsPerDetector : int = 5 ,
514540):
515541 """Plot coma, trefoil and kurtosis from the table on the provided axes.
516542
@@ -524,12 +550,16 @@ def plotHigherOrderMomentsData(
524550 The prefix to use for the column names in the table.
525551 binSpacing : `float`, optional
526552 The spacing between arrows and triangles in the plot.
553+ maxPointsPerDetector : `int`, optional
554+ The maximum number of points per detector to plot. If the number of
555+ points exceeds this value, a random subset will be selected.
527556 """
557+ table = randomRowsPerDetector (table , maxPointsPerDetector )
528558 x = table [prefix + "x" ]
529559 y = table [prefix + "y" ]
530560 kurtosis = table ["kurtosis" ]
531561
532- quiver_kwargs = {
562+ quiverKwargs = {
533563 "headlength" : 5 ,
534564 "headaxislength" : 5 ,
535565 "scale" : 1 ,
@@ -538,42 +568,49 @@ def plotHigherOrderMomentsData(
538568 }
539569
540570 coords = np .vstack ([x , y ]).T
541- mean_coma = {}
571+ meanComa = {}
542572 for i in (1 , 2 ):
543573 binning = meanify (binSpacing )
544574 binning .add_field (coords , table [f"coma{ i } " ])
545575 binning .meanify ()
546- mean_coma [i ] = binning .params0
576+ meanComa [i ] = binning .params0
547577
548- mean_coma_angle = np .arctan2 (mean_coma [2 ], mean_coma [1 ])
549- mean_coma_amplitude = np .hypot (mean_coma [2 ], mean_coma [2 ])
550- Q_coma = axs [0 ].quiver (
578+ meanComaAngle = np .arctan2 (meanComa [2 ], meanComa [1 ])
579+ meanComaAmplitude = np .hypot (meanComa [2 ], meanComa [2 ])
580+ qComa = axs [0 ].quiver (
551581 binning .coords0 [:, 0 ],
552582 binning .coords0 [:, 1 ],
553- mean_coma_amplitude * np .cos (mean_coma_angle ),
554- mean_coma_amplitude * np .sin (mean_coma_angle ),
555- ** quiver_kwargs ,
583+ meanComaAmplitude * np .cos (meanComaAngle ),
584+ meanComaAmplitude * np .sin (meanComaAngle ),
585+ ** quiverKwargs ,
556586 )
557- axs [0 ].quiverkey (Q_coma , X = 0.1 , Y = 0.88 , U = 0.05 , label = "0.05" , labelpos = "S" )
587+ axs [0 ].quiverkey (qComa , X = 0.1 , Y = 0.88 , U = 0.05 , label = "0.05" , labelpos = "S" )
558588
559- mean_trefoil = {}
589+ meanTrefoil = {}
560590 for i in (1 , 2 ):
561591 binning = meanify (binSpacing )
562592 binning .add_field (coords , table [f"trefoil{ i } " ])
563593 binning .meanify ()
564- mean_trefoil [i ] = binning .params0
594+ meanTrefoil [i ] = binning .params0
565595
566- mean_trefoil_angle = np .arctan2 (mean_trefoil [2 ], mean_trefoil [1 ]) / 3 # spin-3
567- mean_trefoil_amplitude = np .hypot (mean_trefoil [2 ], mean_trefoil [1 ])
568- SCALE_TRIANGLE = 500
569- axs [1 ].scatter (1.8 , 1.7 , s = 0.1 * SCALE_TRIANGLE , marker = (3 , 0 , 30 ), lw = 0.1 , color = "black" )
596+ meanTrefoilAngle = np .arctan2 (meanTrefoil [2 ], meanTrefoil [1 ]) / 3 # spin-3
597+ meanTrefoilAmplitude = np .hypot (meanTrefoil [2 ], meanTrefoil [1 ])
598+ scaleTriangle = 500
599+ axs [1 ].scatter (1.8 , 1.7 , s = 0.1 * scaleTriangle , marker = (3 , 0 , 30 ), lw = 0.1 , color = "black" )
570600 axs [1 ].text (1.6 , 1.35 , "0.1" )
571- for idx in range (len (mean_trefoil_amplitude )):
572- _t = mean_trefoil_amplitude [idx ]
573- _ta = mean_trefoil_angle [idx ] * 180 / np .pi
574- _xcen = binning .coords0 [idx , 0 ]
575- _ycen = binning .coords0 [idx , 1 ]
576- axs [1 ].scatter (_xcen , _ycen , marker = (3 , 0 , 30 + _ta ), s = _t * SCALE_TRIANGLE , lw = 0.1 , color = "black" )
601+ for idx in range (len (meanTrefoilAmplitude )):
602+ tVal = meanTrefoilAmplitude [idx ]
603+ trefoilAngleDeg = meanTrefoilAngle [idx ] * 180 / np .pi
604+ xCenter = binning .coords0 [idx , 0 ]
605+ yCenter = binning .coords0 [idx , 1 ]
606+ axs [1 ].scatter (
607+ xCenter ,
608+ yCenter ,
609+ marker = (3 , 0 , 30 + trefoilAngleDeg ),
610+ s = tVal * scaleTriangle ,
611+ lw = 0.1 ,
612+ color = "black" ,
613+ )
577614
578615 pos = axs [1 ].get_position () # get current position [left, bottom, width, height]
579616 axs [1 ].set_position ([pos .x0 , pos .y0 , pos .width * 0.931 , pos .height ])
@@ -896,7 +933,8 @@ def makeAzElPlot(
896933 axs : npt .NDArray [np .object_ ],
897934 table : Table ,
898935 camera : Camera ,
899- maxPointsPerDetector : int = 5 ,
936+ maxPointsPerDetector : int = 60 ,
937+ minPointsPerDetector : int = 5 ,
900938 saveAs : str = "" ,
901939) -> None :
902940 """Plot the PSFs on the focal plane, rotated to az/el coordinates.
@@ -931,6 +969,10 @@ def makeAzElPlot(
931969 The maximum number of points per detector to plot. If the number of
932970 points in the table is greater than this value, a random subset of
933971 points will be plotted.
972+ minPointsPerDetector : `int`, optional
973+ The minimum number of points per detector to plot. If the number of
974+ points in the table is less than this value,
975+ all points will be plotted.
934976 saveAs : `str`, optional
935977 The file path to save the figure.
936978 """
@@ -939,8 +981,8 @@ def makeAzElPlot(
939981
940982 if "kurtosis" in table .columns and axs .shape [0 ] > 2 :
941983 plotHigherOrderMomentsData (axs [2 , :], table , prefix = "aa_" )
942- table = randomRowsPerDetector ( table , maxPointsPerDetector )
943- plotData (axs [:2 , :], table , prefix = "aa_" )
984+
985+ plotData (axs [:2 , :], table , maxPointsPerDetector , minPointsPerDetector , prefix = "aa_" )
944986
945987 oneRaftOnly = camera .getName () in ["LSSTComCam" , "LSSTComCamSim" , "TS8" ]
946988 plotLimit = 90 * MM_TO_DEG if oneRaftOnly else 90 * MM_TO_DEG * FULL_CAMERA_FACTOR
0 commit comments