LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
Namespaces | Classes | Typedefs | Enumerations | Functions
ast Namespace Reference

AST wrapper classes and functions. More...

Namespaces

 detail
 

Classes

class  Channel
 Channel provides input/output of AST objects. More...
 
class  ChebyDomain
 The domain over which a Chebyshev polynomial is defined; returned by ChebyMap.getDomain. More...
 
class  ChebyMap
 A ChebyMap is a form of Mapping which performs a Chebyshev polynomial transformation. More...
 
class  CmpFrame
 A CmpFrame is a compound Frame which allows two component Frames (of any class) to be merged together to form a more complex Frame. More...
 
class  CmpMap
 Abstract base class for SeriesMap and ParallelMap. More...
 
class  DirectionPoint
 Struct returned by Frame::offset2 containing a direction and a point. More...
 
class  FileStream
 File-based source or sink (not both) for channels. More...
 
class  FitsChan
 A specialized form of Channel which reads and writes FITS header cards. More...
 
class  FoundValue
 A value and associated validity flag. More...
 
class  Frame
 Frame is used to represent a coordinate system. More...
 
class  FrameDict
 A FrameSet whose frames can be referenced by domain name. More...
 
class  FrameMapping
 Struct returned by Frame::pickAxes containing a frame and a mapping. More...
 
class  FrameSet
 A FrameSet consists of a set of one or more Frames (which describe coordinate systems), connected together by Mappings (which describe how the coordinate systems are inter-related). More...
 
class  KeyMap
 KeyMap is used to store a set of values with associated keys which identify the values. More...
 
class  LutMap
 LutMap is a specialised form of Mapping which transforms 1-dimensional coordinates by using linear interpolation in a lookup table. More...
 
class  MapBox
 Object to compute the bounding box which just encloses another box after it has been transformed by a mapping. More...
 
class  Mapping
 An abstract base class for objects which transform one set of coordinates to another. More...
 
class  MapSplit
 A Mapping split off as a subset of another Mapping. More...
 
class  MathMap
 A MathMap is a Mapping which allows you to specify a set of forward and/or inverse transformation functions using arithmetic operations and mathematical functions similar to those available in C. More...
 
class  MatrixMap
 MatrixMap is a form of Mapping which performs a general linear transformation. More...
 
class  NormMap
 A Mapping which normalises coordinate values using the norm method of the supplied Frame. More...
 
class  NReadValue
 Struct returned by Frame::unformat containing the number of characters read and corresponding value. More...
 
class  Object
 Abstract base class for all AST objects. More...
 
class  ParallelMap
 A parallel compound mapping where the first Mapping is used to transform the lower numbered coordinates of each point and the second Mapping is used to transform the remaining coordinates. More...
 
class  PcdMap
 A PcdMap is a non-linear Mapping which transforms 2-dimensional positions to correct for the radial distortion introduced by some cameras and telescopes. More...
 
class  PermMap
 A Mapping which permutes the order of coordinates, and possibly also changes the number of coordinates, between its input and output. More...
 
class  PolyMap
 PolyMap is a Mapping which performs a general polynomial transformation. More...
 
class  QuadApprox
 A quadratic approximation to a 2D Mapping. More...
 
class  RateMap
 RateMap is a Mapping which represents a single element of the Jacobian matrix of another Mapping. More...
 
class  ResolvedPoint
 Struct returned by Frame::resolve containing a point and the resolved vector components. More...
 
class  SeriesMap
 A series compound mapping where the first Mapping is used to transform the coordinates of each point and the second Mapping is then applied to the result. More...
 
class  ShiftMap
 ShiftMap is a linear Mapping which shifts each axis by a specified constant value. More...
 
class  SkyFrame
 SkyFrame is a specialised form of Frame which describes celestial longitude/latitude coordinate systems. More...
 
class  SlaMap
 SlaMap is a specialised form of Mapping which can be used to represent a sequence of conversions between standard celestial (longitude, latitude) coordinate systems. More...
 
class  SpecFrame
 A specialised form of one-dimensional Frame which represents various coordinate systems used to describe positions within an electro-magnetic spectrum. More...
 
class  SphMap
 A SphMap is a Mapping which transforms points from a 3-dimensional Cartesian coordinate system into a 2-dimensional spherical coordinate system (longitude and latitude on a unit sphere centred at the origin). More...
 
class  Stream
 A stream for ast::Channel. More...
 
class  StringStream
 String-based source and sink for channels. More...
 
class  TimeFrame
 A TimeFrame is a specialised form of one-dimensional Frame which represents various coordinate systems used to describe positions in time. More...
 
class  TimeMap
 A TimeMap is a specialised form of 1-dimensional Mapping which can be used to represent a sequence of conversions between standard time coordinate systems. More...
 
class  TranMap
 TranMap is a Mapping which combines the forward transformation of a supplied Mapping with the inverse transformation of another supplied Mapping, ignoring the un-used transformation in each Mapping (indeed the un-used transformation need not exist). More...
 
class  UnitMap
 A UnitMap is a unit (null) Mapping that has no effect on the coordinates supplied to it. More...
 
class  UnitNormMap
 The forward transformation of a UnitNormMap subtracts the specified centre and then transforms the resulting vector to a unit vector and the vector norm. More...
 
class  WcsMap
 Map from a spherical system to a cartesian system using standard FITS sky coordinate projections. More...
 
class  WinMap
 A WinMap is a linear Mapping which transforms a rectangular window in one coordinate system into a similar window in another coordinate system by scaling and shifting each axis (the window edges being parallel to the coordinate axes). More...
 
class  XmlChan
 XmlChan provides input/output of AST objects. More...
 
class  ZoomMap
 A Mapping which "zooms" a set of points about the origin by multiplying all coordinate values by the same scale factor. More...
 

Typedefs

using Array2D = ndarray::Array< double, 2, 2 >
 2D array of const double; typically used for lists of const points More...
 
using ConstArray2D = ndarray::Array< const double, 2, 2 >
 2D array of const double; typically used for lists of const points More...
 
using PointI = std::vector< int >
 Vector of ints; typically used for the bounds of Mapping.tranGridForward and inverse. More...
 
using PointD = std::vector< double >
 Vector of double; used for bounds, points. More...
 

Enumerations

enum  DataType {
  DataType::IntType = AST__INTTYPE, DataType::ShortIntType = AST__SINTTYPE, DataType::ByteType = AST__BYTETYPE, DataType::DoubleType = AST__DOUBLETYPE,
  DataType::FloatType = AST__FLOATTYPE, DataType::StringType = AST__STRINGTYPE, DataType::ObjectType = AST__OBJECTTYPE, DataType::PointerType = AST__POINTERTYPE,
  DataType::UndefinedType = AST__UNDEFTYPE, DataType::BadType = AST__BADTYPE
}
 Data types held by a KeyMap. More...
 
enum  FitsKeyState { FitsKeyState::ABSENT = 0, FitsKeyState::NOVALUE, FitsKeyState::PRESENT }
 Enums describing the presence or absence of a FITS keyword. More...
 
enum  CardType {
  CardType::NOTYPE = AST__NOTYPE, CardType::COMMENT = AST__COMMENT, CardType::INT = AST__INT, CardType::FLOAT = AST__FLOAT,
  CardType::STRING = AST__STRING, CardType::COMPLEXF = AST__COMPLEXF, CardType::COMPLEXI = AST__COMPLEXI, CardType::LOGICAL = AST__LOGICAL,
  CardType::CONTINUE = AST__CONTINUE, CardType::UNDEF = AST__UNDEF
}
 Enums describing the FITS card type. More...
 
enum  WcsType {
  WcsType::AZP = AST__AZP, WcsType::SZP = AST__SZP, WcsType::TAN = AST__TAN, WcsType::STG = AST__STG,
  WcsType::SIN = AST__SIN, WcsType::ARC = AST__ARC, WcsType::ZPN = AST__ZPN, WcsType::ZEA = AST__ZEA,
  WcsType::AIR = AST__AIR, WcsType::CYP = AST__CYP, WcsType::CEA = AST__CEA, WcsType::CAR = AST__CAR,
  WcsType::MER = AST__MER, WcsType::SFL = AST__SFL, WcsType::PAR = AST__PAR, WcsType::MOL = AST__MOL,
  WcsType::AIT = AST__AIT, WcsType::COP = AST__COP, WcsType::COE = AST__COE, WcsType::COD = AST__COD,
  WcsType::COO = AST__COO, WcsType::BON = AST__BON, WcsType::PCO = AST__PCO, WcsType::TSC = AST__TSC,
  WcsType::CSC = AST__CSC, WcsType::QSC = AST__QSC, WcsType::NCP = AST__NCP, WcsType::GLS = AST__GLS,
  WcsType::TPN = AST__TPN, WcsType::HPX = AST__HPX, WcsType::XPH = AST__XPH, WcsType::WCSBAD = AST__WCSBAD
}
 WCS types that give the projection type code (in upper case) as used in the FITS-WCS "CTYPEi" keyword. More...
 

Functions

void assertOK (AstObject *rawPtr1=nullptr, AstObject *rawPtr2=nullptr)
 Throw std::runtime_error if AST's state is bad. More...
 
bool escapes (int include=-1)
 Control whether graphical escape sequences are included in strings. More...
 
std::shared_ptr< FrameSetappend (FrameSet const &first, FrameSet const &second)
 Construct a FrameSet that performs two transformations in series. More...
 
std::shared_ptr< MappingmakeRadialMapping (std::vector< double > const &center, Mapping const &mapping1d)
 Construct a radially symmetric mapping from a 1-dimensional mapping. More...
 
ConstArray2D arrayFromVector (std::vector< double > const &vec, int nAxes)
 Reshape a vector as a 2-dimensional array that shares the same memory. More...
 
Array2D arrayFromVector (std::vector< double > &vec, int nAxes)
 Reshape a vector as a 2-dimensional array that shares the same memory. More...
 

Detailed Description

AST wrapper classes and functions.

Typedef Documentation

◆ Array2D

using ast::Array2D = typedef ndarray::Array<double, 2, 2>

2D array of const double; typically used for lists of const points

Definition at line 42 of file base.h.

◆ ConstArray2D

using ast::ConstArray2D = typedef ndarray::Array<const double, 2, 2>

2D array of const double; typically used for lists of const points

Definition at line 46 of file base.h.

◆ PointD

using ast::PointD = typedef std::vector<double>

Vector of double; used for bounds, points.

Also used to store a list of points as sequential data, as an alternative to Array2D and ConstArray2D

Definition at line 57 of file base.h.

◆ PointI

using ast::PointI = typedef std::vector<int>

Vector of ints; typically used for the bounds of Mapping.tranGridForward and inverse.

Definition at line 50 of file base.h.

Enumeration Type Documentation

◆ CardType

enum ast::CardType
strong

Enums describing the FITS card type.

Enumerator
NOTYPE 

card does not exist (card number invalid)

COMMENT 

card is a comment-style card with no "=" (COMMENT, HISTORY, ...)

INT 

integer

FLOAT 

float

STRING 

string

COMPLEXF 

complex floating point

COMPLEXI 

complex integer

LOGICAL 

boolean

CONTINUE 

CONTINUE card.

UNDEF 

card has no value

Definition at line 48 of file FitsChan.h.

48  {
49  NOTYPE = AST__NOTYPE,
50  COMMENT = AST__COMMENT,
51  INT = AST__INT,
52  FLOAT = AST__FLOAT,
53  STRING = AST__STRING,
54  COMPLEXF = AST__COMPLEXF,
55  COMPLEXI = AST__COMPLEXI,
56  LOGICAL = AST__LOGICAL,
57  CONTINUE = AST__CONTINUE,
58  UNDEF = AST__UNDEF,
59 };
complex integer
complex floating point
card is a comment-style card with no "=" (COMMENT, HISTORY, ...)
card has no value
card does not exist (card number invalid)

◆ DataType

enum ast::DataType
strong

Data types held by a KeyMap.

Enumerator
IntType 
ShortIntType 
ByteType 
DoubleType 
FloatType 
StringType 
ObjectType 
PointerType 
UndefinedType 
BadType 

Definition at line 62 of file base.h.

62  {
63  IntType = AST__INTTYPE,
64  ShortIntType = AST__SINTTYPE,
65  ByteType = AST__BYTETYPE,
66  DoubleType = AST__DOUBLETYPE,
67  FloatType = AST__FLOATTYPE,
68  StringType = AST__STRINGTYPE,
69  ObjectType = AST__OBJECTTYPE,
70  PointerType = AST__POINTERTYPE,
71  UndefinedType = AST__UNDEFTYPE,
72  BadType = AST__BADTYPE
73 };

◆ FitsKeyState

enum ast::FitsKeyState
strong

Enums describing the presence or absence of a FITS keyword.

Enumerator
ABSENT 

keyword is not present

NOVALUE 

keyword is present, but has no value

PRESENT 

keyword is present and has a value

Definition at line 39 of file FitsChan.h.

39  {
40  ABSENT = 0,
41  NOVALUE,
42  PRESENT
43 };
keyword is present and has a value
keyword is present, but has no value
keyword is not present

◆ WcsType

enum ast::WcsType
strong

WCS types that give the projection type code (in upper case) as used in the FITS-WCS "CTYPEi" keyword.

You should consult the FITS-WCS paper for a list of the available projections. The additional code of WcsType::TPN can be supplied which represents a TAN projection with polynomial correction terms as defined in an early draft of the FITS-WCS paper.

These have the same value as the corresponding AST__ constant, e.g. WcsType::TAN = AST__TAN.

I am not sure what AST__WCSBAD is used for, but I included it anyway.

Enumerator
AZP 
SZP 
TAN 
STG 
SIN 
ARC 
ZPN 
ZEA 
AIR 
CYP 
CEA 
CAR 
MER 
SFL 
PAR 
MOL 
AIT 
COP 
COE 
COD 
COO 
BON 
PCO 
TSC 
CSC 
QSC 
NCP 
GLS 
TPN 
HPX 
XPH 
WCSBAD 

Definition at line 48 of file WcsMap.h.

48  {
49  AZP = AST__AZP,
50  SZP = AST__SZP,
51  TAN = AST__TAN,
52  STG = AST__STG,
53  SIN = AST__SIN,
54  ARC = AST__ARC,
55  ZPN = AST__ZPN,
56  ZEA = AST__ZEA,
57  AIR = AST__AIR,
58  CYP = AST__CYP,
59  CEA = AST__CEA,
60  CAR = AST__CAR,
61  MER = AST__MER,
62  SFL = AST__SFL,
63  PAR = AST__PAR,
64  MOL = AST__MOL,
65  AIT = AST__AIT,
66  COP = AST__COP,
67  COE = AST__COE,
68  COD = AST__COD,
69  COO = AST__COO,
70  BON = AST__BON,
71  PCO = AST__PCO,
72  TSC = AST__TSC,
73  CSC = AST__CSC,
74  QSC = AST__QSC,
75  NCP = AST__NCP,
76  GLS = AST__GLS,
77  TPN = AST__TPN,
78  HPX = AST__HPX,
79  XPH = AST__XPH,
80  WCSBAD = AST__WCSBAD,
81 };

Function Documentation

◆ append()

std::shared_ptr< FrameSet > ast::append ( FrameSet const &  first,
FrameSet const &  second 
)

Construct a FrameSet that performs two transformations in series.

When used as a Mapping, the FrameSet shall apply first, followed by second. Its inverse shall apply the inverse of second, followed by the inverse of first. The concatenation is only valid if first.getCurrent() and second.getBase() have the same number of axes.

The new FrameSet shall contain all Frames and Mappings from first, followed by all Frames and Mappings from second, preserving their original order. The current frame of first shall be connected to the base frame of second by a UnitMap. The new set's base frame shall be the base frame of first, and its current frame shall be the current frame of second.

The FrameSet shall be independent of the input arguments, so changes to the original FrameSets (in particular, reassignments of their base or current frames) shall not affect it.

Parameters
first,secondthe FrameSets to concatenate.
Returns
a pointer to a combined FrameSet as described above

Example: if first has 3 frames and secondhas 4, then the result shall contain 7 frames, of which frames 1-3 are the same as frames 1-3 of first, in order, and frames 4-7 are the same as frames 1-4 of second, in order.

Definition at line 33 of file functional.cc.

33  {
34  std::shared_ptr<FrameSet> const merged = first.copy();
35  std::shared_ptr<FrameSet> const newFrames = second.copy();
36 
37  newFrames->setCurrent(FrameSet::BASE);
38  int const joinNAxes = first.getFrame(FrameSet::CURRENT)->getNAxes();
39  merged->addFrame(FrameSet::CURRENT, UnitMap(joinNAxes), *newFrames);
40 
41  // All frame numbers from `second` have been offset in `merged` by number of frames in `first`
42  int const mergedCurrent = first.getNFrame() + second.getCurrent();
43  merged->setCurrent(mergedCurrent);
44 
45  return merged;
46 }

◆ arrayFromVector() [1/2]

ConstArray2D ast::arrayFromVector ( std::vector< double > const &  vec,
int  nAxes 
)

Reshape a vector as a 2-dimensional array that shares the same memory.

To convert a vector of coefficients to an array of coefficients for PolyMap or ChebyMap, call this with nAxes = nPoints / width, where width is the number of elements in each coefficient: width = nOut + 2 for forward coefficients, nIn + 2 for inverse coefficients.

Parameters
[in]vecVector of points, with all values for one axis first, then the next axes, and so on, e.g. x1, x2, ...xnPt, y1, y2, ...ynNpt
[in]nAxesNumber of axes per point
Returns
2-dimensional array with dimensions (nPts, nAxes)
Exceptions
std::runtime_errorif vec length is not a multiple of nAxes
Warning
You must hold onto the original vector until you are done with the returned array, else the array will be corrupted. (However, the Python version returns a copy, to avoid memory issues.)

Definition at line 65 of file base.cc.

65  {
66  return static_cast<ConstArray2D>(arrayFromVector(const_cast<std::vector<double> &>(vec), nAxes));
67 }
ndarray::Array< const double, 2, 2 > ConstArray2D
2D array of const double; typically used for lists of const points
Definition: base.h:46
ConstArray2D arrayFromVector(std::vector< double > const &vec, int nAxes)
Reshape a vector as a 2-dimensional array that shares the same memory.
Definition: base.cc:65

◆ arrayFromVector() [2/2]

Array2D ast::arrayFromVector ( std::vector< double > &  vec,
int  nAxes 
)

Reshape a vector as a 2-dimensional array that shares the same memory.

To convert a vector of coefficients to an array of coefficients for PolyMap or ChebyMap, call this with nAxes = nPoints / width, where width is the number of elements in each coefficient: width = nOut + 2 for forward coefficients, nIn + 2 for inverse coefficients.

Parameters
[in]vecVector of points, with all values for one axis first, then the next axes, and so on, e.g. x1, x2, ...xnPt, y1, y2, ...ynNpt
[in]nAxesNumber of axes per point
Returns
2-dimensional array with dimensions (nPts, nAxes)
Exceptions
std::runtime_errorif vec length is not a multiple of nAxes
Warning
You must hold onto the original vector until you are done with the returned array, else the array will be corrupted. (However, the Python version returns a copy, to avoid memory issues.)

Definition at line 69 of file base.cc.

69  {
70  int nPoints = vec.size() / nAxes;
71  if (nPoints * nAxes != vec.size()) {
73  os << "vec length = " << vec.size() << " not a multiple of nAxes = " << nAxes;
74  throw std::runtime_error(os.str());
75  }
76  Array2D::Index shape = ndarray::makeVector(nAxes, nPoints);
77  Array2D::Index strides = ndarray::makeVector(nPoints, 1);
78  return external(vec.data(), shape, strides);
79 }
T data(T... args)
T str(T... args)
T size(T... args)
std::ostream * os
Definition: Schema.cc:746

◆ assertOK()

void ast::assertOK ( AstObject *  rawPtr1 = nullptr,
AstObject *  rawPtr2 = nullptr 
)

Throw std::runtime_error if AST's state is bad.

Parameters
rawPtr1An AST object to free if status is bad
rawPtr2An AST object to free if status is bad
Note
on the first call an error handler is registered that saves error messages to a buffer.

Definition at line 49 of file base.cc.

49  {
50  // Construct ErrorHandler once, the first time this function is called.
51  // This is done to initialize `errorMsgStream` and register `reportError` as the AST error handler.
52  // See https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
53  static ErrorHandler *errHandler = new ErrorHandler();
54  if (!astOK) {
55  if (rawPtr1) {
56  astAnnul(rawPtr1);
57  }
58  if (rawPtr2) {
59  astAnnul(rawPtr2);
60  }
61  throw std::runtime_error(errHandler->getErrMsg());
62  }
63 }

◆ escapes()

bool ast::escapes ( int  include = -1)
inline

Control whether graphical escape sequences are included in strings.

The Plot class defines a set of escape sequences which can be included within a text string in order to control the appearance of sub-strings within the text. (See the Escape attribute for a description of these escape sequences). It is usually inappropriate for AST to return strings containing such escape sequences when called by application code. For instance, an application which displays the value of the Title attribute of a Frame usually does not want the displayed string to include potentially long escape sequences which a human read would have difficuly interpreting. Therefore the default behaviour is for AST to strip out such escape sequences when called by application code. This default behaviour can be changed using this function.

Parameters
[in]includePossible values are:
  • -1 (or any negative value) to return the current value without changing it.
  • 0 to not include escape sequences,
  • 1 (or any positive value) to include escape sequences,
Returns
the previous value (or current value if include is negative).

Notes:

  • This function also controls whether the AST function astStripEscapes removes escape sequences from the supplied string, or returns the supplied string without change.
  • Unlike the AST function astEscapes, this function will not attempt to execute if an error has already occurred.

Definition at line 140 of file base.h.

140  {
141  assertOK();
142  int ret = astEscapes(include);
143  assertOK();
144  return ret;
145 }
void assertOK(AstObject *rawPtr1=nullptr, AstObject *rawPtr2=nullptr)
Throw std::runtime_error if AST&#39;s state is bad.
Definition: base.cc:49

◆ makeRadialMapping()

std::shared_ptr< Mapping > ast::makeRadialMapping ( std::vector< double > const &  center,
Mapping const &  mapping1d 
)

Construct a radially symmetric mapping from a 1-dimensional mapping.

The transform will be symmetrical about the specified center. The forward transform is as follows: input -> unitNormMap -> input norm -> mapping1d -> output norm -> unitNormMap inverse -> output -> unit vector -------------------------—> where unitNormMap is UnitNormMap(center)

The returned mapping will support forward and/or inverse transformation as mapping1d does.

Parameters
[in]centerCenter of radial symmetry
[in]mapping1d1-dimensional mapping
Returns
a mapping that is radially symmetric about the center and has nIn = nOut = center.size()
Exceptions
std::invalid_argumentif mapping1d has nIn or nOut != 1
std::runtime_errorif center is empty

Definition at line 48 of file functional.cc.

48  {
49  auto naxes = center.size();
50  if (mapping1d.getNIn() != 1) {
51  throw std::invalid_argument("mapping1d has " + std::to_string(mapping1d.getNIn()) +
52  " inputs, instead of 1");
53  }
54  if (mapping1d.getNOut() != 1) {
55  throw std::invalid_argument("mapping1d has " + std::to_string(mapping1d.getNOut()) +
56  " outputs, instead of 1");
57  }
58  auto unitNormMap = UnitNormMap(center);
59  return std::make_shared<Mapping>(
60  unitNormMap.then(UnitMap(naxes).under(mapping1d)).then(*unitNormMap.inverted()));
61 }
T to_string(T... args)
T size(T... args)