Curly and Floppy Twistytail, the Funny Piggie Boys
by Howard R. Garis
Chapter 23: “The Piggies and the Fish”
Additional Information
- Year Published: 1918
- Language: English
- Country of Origin: United States of America
- Source: Garis, H. R. (1918). Curly and Floppy Twistytail, the Funny Piggie Boys. New York, NY: A. L. Burt Co.
-
Readability:
- Flesch–Kincaid Level: 5.0
- Word Count: 1,489
- Genre: Fantasy
- ✎ Cite This
Downloads
On the morning of the day when it was to be Hallowe’en, Curly Tail, and Flop Ear, the two piggie boys, awakened in Uncle Wiggily’s bungalow, on Raccoon Island in Lake Hopatcong, and Curly Tail whispered:
“What are you going to dress up like, Flop Ear?”
“Oh, I guess I’ll make believe I’m a loaf of bread. What are you going to be?”
“An apple pie,” said the other little piggie boy, “I’ll stick apples all over myself, and some bits of pie crust, and when we get through playing Hallowe’en we can eat them.”
“Fine!” cried Curly Tail. “I wish I was going dressed up like an ice cream cone, but then I’d melt so fast I wouldn’t have any fun.
“We surely will,” declared his brother. But if they could have looked into the next room, and have seen Uncle Wiggily laughing to himself, and winking his eyes, and rubbing his leg that had rheumatism in it—well, maybe those piggie boys wouldn’t have felt so funny.
“Fool me, eh? Will they?” whispered Uncle Wiggily. “We’ll see about it,” and then he hopped about on his crutch to help the boys get breakfast.
“We must have all the good times we can,” said the old gentleman rabbit, “for soon the new roof will be on your school and you will have to begin studying your lessons again. Be happy while you’re here, for soon the snow will fly and the ice will come, and we will have to go away from the lake.”
“Oh, we’re going to have a good time, Uncle Wiggily,” said Curly Tail, or Curly, as I often call him for short, and then he looked at his brother, and they both laughed and pretended it wasn’t anything at all. But Uncle Wiggily knew better.
“Well,” said the old gentleman rabbit, after breakfast, “I guess I’ll go down and play Scotch checkers with Pop Goes the Weasel. You boys can stay here, but if the bad alligator or the fuzzy fox tries to get you, just call for me.”
“All right,” said Curly Tail, and when his uncle was out of sight he and his brother began to dress up for Hollowe’en, which is the night everyone puts on false faces you know.
One of the piggie boys made a lot of flour paste, colored with brown sugar, and that was to fix him so he would look like a loaf of bread. And Flop Ear made himself look like an apple pie.

Just before supper Uncle Wiggily came home from having played Scotch checkers with Pop Goes the Weasel. The old gentleman had something under his coat, but when Curly Tail and Flop Ear asked him what it was he only laughed and said:
“Oh, you’ll soon see!”
Well, it got pretty dark, and Curly Tail and his brother thought it was time for them to dress up and play a trick on their uncle. So they took their false faces, one like a lump of buttered bread and the other like a piece of cheese, and went out in the woods to dress. They intended to come and knock on the bungalow door and see what Uncle Wiggily would do and say when he saw them.
Pretty soon they were both ready, and, really, if I do say it myself, Curly Tail looked just like a ten-cent loaf, with flour in his buttonhole and all that, only he didn’t have any real butter on, as that was so greasy. And Flop Ear, or Flop, or Floppy, for short, looked too cute for anything—just exactly like an apple pie, and he even carried a bit of cheese to go with it, and a toasting fork.
“Now, we’ll fool Uncle Wiggily,” they said, as they started for the bungalow. But they didn’t know what had happened to the rabbit gentleman. They hadn’t gone very far before, out in a boat on the lake, not far from shore, they heard a voice calling:
“Oh, help! Help! He’s such a big one that I can’t get him in, and Percival has fallen overboard! Help! Help!”
“My goodness! What’s that?” asked Curly Tail, in surprise.
“Some one must be in trouble,” said Flop Ear. “Let’s see who it is.”
“But it might be the bad skillery-scalery alligator, with the lumps on his tail,” said the other piggie boy. Then Flop Ear looked out on the lake, where it was all lighted by the moon and he said:
“I see a lady in a boat. Surely she would not harm us. And she spoke of Percival—she must mean the old circus dog! I am going to see what is the matter!”
“Better not! Maybe it’s a trick to catch us!” said Curly Tail.
But just then a lady on the lake called again: “Oh help! He is such a big one that I can’t get him into the boat, and Percival has fallen overboard!”
Then there was a great splashing, and a rustling in the bushes and Flop Ear called:
“We’re coming to help you, lady! What have you got that is so big?”
“A fish,” she answered. “My husband, Percival, is a great fisherman and he caught the biggest fish in all the lake, but it pulled him out of the boat. However, I have hold of the pole and line, and the fish is still fast to the hook. Oh, help me to catch him!”
So the piggie boys said they would, and they ran down to the shore, and the lady in the boat passed them the pole. Then Curly and Flop pulled as hard as they could, and old circus dog Percival scrambled out of the water, and he helped pull, too, and, all of a sudden, from the bushes along the edge of the lake—on dry land, but not in the water—there suddenly flopped the biggest fish any one had ever seen.
“Oh, what long ears the fish has!” cried Curly Tail, when the moon shone on the fish. “I never saw a fish with ears!”
“I’m not a fish,” said a voice. “Oh, please let me go. The hook is caught in my collar. Please let me go!”
“Who are you?” asked Percival, in wonder.
“I’m Uncle Wiggily Longears,” was the answer. “I dressed up like a Hallowe’en fish to fool Curly Tail and Flop Ear. I was walking along the shore in the dark, thinking I could catch the piggie boys, when, all of a sudden, something caught in my coat collar, and I was dragged through the bushes. I was choked so I could hardly speak, and I didn’t know what had happened to me.”
“Oh, that’s too bad,” said Percival. “I guess I happened to catch you on my fishhook by mistake, when I was tossing it around. But why are you all dressed up?” he asked Curly Tail and Flop Ear and Uncle Wiggily.
“Because it is Hallowe’en,” said Flop Ear; “but I guess we have had enough of it.”
“Yes,” said Uncle Wiggily, “come up into the bungalow and we will duck for apples, eat marshmallows and have fun.”
So Curly Tail took off his bread crumbs clothes, and Flop Ear his apple pie suit, and Uncle Wiggily his fish scales, and they all took off their false faces, and Percival and the lady whose name was Gertrude, had a good time.
And in the next story in case the ash can doesn’t roll off the roof and fall on the dog house to scare the puppy cake I’ll tell you about Curly Tail and the little afraid girl.


| DSK Required Reading |
Table of ContentsDSK Required Reading Abstract Purpose Intended Audience References Introduction DSK Software High-Level DSK-Enabled Geometry Functions DSK File Loading and Unloading DSK Utility Functions DSK Type 2 Functions DLA and DAS Functions Surface Name and ID Conversion Functions SPICE Toolkit DSK Utility Programs Non-SPICE Toolkit DSK Utility Programs DSK Concepts Shapes and Surfaces Surface IDs Defining Surface Name-ID Mappings Segments DLA and DSK Descriptors Reference Frames Coordinate Systems and Spatial Coverage Spatial coverage: Dimensions Spatial coverage: Gaps and Padding Time Bounds Data Types Data Classes Data Competition and Priority Greedy Algorithms Greedy Ray-Segment Boundary Intercepts DSK Type 2 Plate Expansion Additional Greedy Algorithms DSK Tolerances Drawbacks Access to DSK Tolerances and Margin Values DSK Files DAS Files DLA Files DSK File Format DSK Type 2: Triangular Plate Model Type 2 Shape Data Vertices Plates Type 2 Ancillary Information Pointers and Offsets DSK Type 2 Segment Parameters Spatial Index: Voxel-Plate Mapping Fine Voxel Grid Fine Voxel Scale Coarse Voxel Grid Purpose of the Coarse Voxel Grid Voxel-Plate Pointer Array Voxel-Plate Association Array Size of the Voxel-Plate Association Array Spatial Index: Vertex-Plate Mapping Structure of the Vertex-Plate Mapping Size of the Vertex-Plate Mapping Array Layout of DSK Type 2 Segments DSK Type 2 Integer Segment Component DSK Type 2 Double Precision Segment Component Coordinate System Parameters Common Problems Slow DSK Computations Non-Portable and Unstable Results Non-Convex and Multi-Valued Surfaces DSK File Creation Errors MKDSK Setup File Errors Data Errors Segment Coverage Errors Poor Data Distribution Across Segments Appendix A --- Revision History 2017 APR 05 by N. J. Bachman. Appendix B --- DSK Subsystem Limits General Limits DSK Type 2 Segment Limits DSK Required Reading
Abstract
Purpose
Intended Audience
This document assumes you already have a strong understanding of SPICE concepts and terminology. References
https://naif.jpl.nasa.gov/naif/tutorials.html
DLACAT BINGOare utilities that are not part of the SPICE Toolkit, but that operate on DSK files. They are available on the NAIF web site at
https://naif.jpl.nasa.gov/naif/utilities.html Introduction
DSK data also can represent shapes of artificial objects such as spacecraft components, or represent abstractions such as the subset of a target body's surface that has a property of interest. The DSK subsystem comprises software, the DSK file format specification, and documentation. The primary purpose of the DSK subsystem is to enable SPICE-based applications to conveniently and efficiently use detailed shape data in geometry computations performed by SPICE functions. DSK data enable these functions to produce more accurate results than those obtainable using triaxial ellipsoid shape models. See the section below titled ``High-Level DSK-Enabled Geometry Routines'' for details. The DSK implementation ensures that shape data used by SPICE are accompanied by all of the attribute information necessary for correct, programmatic use of the data---including, but not limited to, reference frames, central bodies, coordinate systems, spatial coverage bounds, and time bounds of applicability. The DSK format enables data to be augmented by indexes, or other pre-computed parameters, that greatly enhance the speed of common geometric computations, such as those of ray-surface intercepts. DSK data sets can be distributed across multiple DSK files; this is normal for large data sets. Such sets of files can be ``loaded'' (made available for read access by Mice software) concurrently; Mice software will select data from the appropriate files as needed to perform computations. The DSK file format facilitates storage, transmission, and archival of shape data. It allows the data to be annotated with free-form descriptive comments, also called ``metadata.'' DSK documentation uses the term ``data type'' to refer to types of mathematical shape representations, associated DSK file formats, and software. The DSK subsystem is designed to accommodate multiple data types, and to enable high-level SPICE geometry software to function independently of these types. Currently there is only one DSK data type, which represents the shape of an object by a set of triangular plates. This representation is called a ``tessellated plate model'' or ``triangular plate model.'' The DSK documentation refers to this type as ``DSK type 2.'' Support for digital elevation models (DEMs) will be added in a later version of the SPICE Toolkit; one or more new DSK data types will be developed to support such data. Because many popular file formats for shape data exist, and because it is impractical for these formats to be used directly by SPICE for geometric computations, the DSK subsystem supports conversion of a variety of text-based shape data file formats to DSK format; it also supports conversion of DSK files to a variety of text formats. DSK Software
High-Level DSK-Enabled Geometry Functions
All of these routines perform computations that involve a target body. All can model the shape of that body using data provided by DSK files. Many of the functions can use triaxial ellipsoid models as well. These functions have extensive header documentation. Each header describes all input and output arguments and includes one or more example programs accompanied by example meta-kernels and corresponding program outputs.
DSK File Loading and Unloading
DSK Utility Functions
Functions for DSK file creation:
Function for fetching DSK segment attributes:
DSK Type 2 Functions
DLA and DAS Functions
Some lower-level functionality is provided by functions of the DLA and DAS subsystems. The routines below support linear traversal of the doubly linked list---also called ``searching'' the list---of DSK segments within a DSK file:
Surface Name and ID Conversion Functions
SPICE Toolkit DSK Utility Programs
Non-SPICE Toolkit DSK Utility Programs
DSK ConceptsShapes and Surfaces
The term ``surfaces'' is also used to refer to DSK data sets themselves, particularly when there are multiple data sets, differing in some aspects, that provide data for a given body. For example, Mars topography data sets based on MGS MOLA data might be referred to as the ``64 pixels/degree surface'' or the ``128 pixels/degree surface.'' Surface IDs
At run time, calls from user applications to Mice functions can restrict the DSK data used to those from specified surfaces. For example, a user application might direct the Mice sub-observer point function cspice_subpnt to to use a high-resolution surface for a spacecraft altitude computation, versus a low-resolution surface for plotting the spacecraft's ground track. Because surface IDs enable SPICE applications to select data from among those available in loaded DSK files, it is not necessary for applications to repeatedly load and unload DSK files to control which shape data are used for a given body and computation. Applications normally can load at start-up all of the DSK data for a given body, then select the data to be used on a per-computation basis. Avoiding repetitive DSK loading tends to improve an application's computation speed. This is because after any change to the set of loaded DSK files, the DSK subsystem must perform some bookkeeping computations before DSK-based computations can be performed. Degradation of overall execution speed due to these computations is slight as long as they're performed infrequently. SPICE surface IDs are associated with surface names; these associations are made via assignments in SPICE text kernels. Surface name-ID associations are made for specific bodies: the combination of a body name or body ID and surface name can be mapped to a surface ID code, and the combination of a body name or body ID and a surface ID code can be mapped to a surface name. A given surface ID code can be re-used for different bodies without ambiguity. For a given body, it's important for users to coordinate assignment of surface names and surface IDs. The Mice functions for converting between surface IDs and surface names are listed in the section ``Surface Name and ID Conversion Functions'' above. Defining Surface Name-ID Mappings
NAIF_SURFACE_NAME += ( <surface name 1>, ... ) NAIF_SURFACE_CODE += ( <surface code 1>, ... ) NAIF_SURFACE_BODY += ( <body code 1>, ... )Above, the Ith elements of the lists on the assignments' right hand sides together define the Ith surface name/ID mapping. The same effect can be achieved using assignments formatted as follows:
NAIF_SURFACE_NAME += <surface name 1> NAIF_SURFACE_CODE += <surface code 1> NAIF_SURFACE_BODY += <body code 1> NAIF_SURFACE_NAME += <surface name 2> NAIF_SURFACE_CODE += <surface code 2> NAIF_SURFACE_BODY += <body code 2> ...Note the use of the
+=operator; this operator appends to rather than overwrites the kernel variable named on the left hand side of the assignment. Segments
Each DSK segment contains data for some or all of the surface of a single body object. This object is called the ``body,'' ``central body,'' or ``center,'' even though it need not be a natural solar system body. Within a segment, the data have the following attributes in common:
When DSK files are loaded via one or more calls to cspice_furnsh, all segments from those files become available to the DSK subsystem for use in computations. At run time, when a request for shape data for a specified body is made to the DSK subsystem, all segments for that body can be considered as possible sources of data to satisfy the request. For small DSK data sets, such as low-resolution shape models for asteroids, a single segment can suffice to store all of the data for the model. Large DSK data sets typically consist of tens or hundreds of segments distributed over multiple DSK files. Normally all segments for a given body can be loaded at one time. The limit on the total number of DSK segments for all bodies that can be loaded is given in Appendix B. DSK utilities typically create or operate on segments:
DLA and DSK Descriptors
The DLA descriptor of a DSK segment indicates the location of the segment's data in the DSK file containing that segment. DLA descriptors contain DAS base addresses and sizes of the double precision and integer components of the associated segments. DLA descriptors are integer arrays. User applications can locate all segments in a DSK file by calling the DLA ``begin forward search'' routine cspice_dlabfs, then repeatedly calling the DLA ``find next segment'' routine cspice_dlafns. See the API documentation of those functions for details and code examples. The DSK descriptor of a DSK segment contains the segment's attribute information; these are the attributes listed above. User applications can determine attributes of a DSK segment by obtaining the DLA descriptor of the segment, then calling the Mice function cspice_dskgd to obtain the segment's DSK descriptor. See the chapter ``DSK Files'' for details. Reference Frames
Within a DSK segment, all shape data are expressed relative to that segment's reference frame. For example, if a segment containing data for Phobos uses the IAU_PHOBOS body-fixed frame, and if the segment contains vertices of triangular plates, the coordinates of those vertices are expressed in the IAU_PHOBOS reference frame. The set of DSK segments to be used in a computation for a given body need not be associated with a single reference frame, but using data from mixed frames should be done cautiously. It is up to the user to combine data in ways that make sense. For example, Mars data expressed in the Mars-centered IAU_MARS frame can be used together with Mars data expressed in one or more Mars topocentric frames. On the other hand, it doesn't make sense to combine earth data expressed in the ITRF93 frame with data expressed in the IAU_EARTH frame, because those frames have some relative rotation. The same is true for data expressed in the IAU_MOON and MOON_ME frames: even though these are realizations of the same reference frame, the approximation error in the IAU_MOON frame is time-dependent, so these frames have relative rotation. Coordinate Systems and Spatial Coverage
The supported coordinate systems are:
Planetodetic coordinates should be used only for large bodies having surfaces well approximated by spheroids. Rectangular coordinates may be appropriate for data sets expressed in topocentric reference frames, for artificial structures, and for extremely irregular natural bodies. A segment's coordinate system is used to represent the segment's coverage bounds. For example, a DSK segment that uses the Phobos planetocentric coordinate system and IAU_PHOBOS reference frame might contain surface data for Phobos within the spatial region
Planetocentric latitude: -90 to +90 degrees Planetocentric longitude: -180 to +180 degrees Radius: 0 to 10 kmHere the planetocentric coordinate system's equatorial plane is the X-Y plane of the IAU_PHOBOS frame. The prime meridian of the coordinate system lies in the frame's X-Z plane and intersects the +X axis of the frame. Another example: a DSK segment that uses a Mars planetodetic coordinate system might contain surface data for Mars within the spatial region
Planetodetic latitude: -30 to +30 degrees Planetodetic longitude: +60 to +90 degrees Altitude: -10 to +20 kmHere the planetodetic coordinate system's equatorial plane is the X-Y plane of the segment's reference frame, for example the IAU_MARS frame. The prime meridian of the coordinate system lies in the frame's X-Z plane and intersects the +X axis of the frame. The altitude is measured relative to a reference spheroid, the size and shape parameters of which are contained in the segment. A third example: a DSK segment that contains data for a horizon mask for a tracking station might use rectangular coordinates and a topocentric frame having axis directions
X: north Y: west Z: upThe region covered by the segment might be
X: -0.5 to +0.5 km Y: -0.5 to +0.5 km Z: -0.2 to +0.2 kmIn this case the horizon mask need not model the topography surrounding the station; it can simply model obscuration due to the topography. So the coverage region need not extend to the horizon; it can be contained in a small box enclosing the station. Spatial coverage: Dimensions
For many applications, it is more natural to consider the spatial coverage of a segment to be two-dimensional. This is true when the surface represented by the segment can be expressed as a function that maps a two-dimensional region to radius or height values. For example, surface height relative to a reference spheroid can be a function of planetodetic longitude and latitude. In a topocentric frame, the Z coordinate of a surface can be a function of the X and Y coordinates. In cases where a surface is viewed as a function of two coordinates, those coordinates are called the ``domain coordinates.'' In some DSK documentation, the terms ``horizontal'' or ``tangential'' coordinates may be used as synonyms. The DSKBRIEF summary utility displays spatial coverage in three dimensions for individual segments. It treats spatial coverage as two-dimensional for the purpose of displaying combined coverage of multiple segments, and for displaying gaps within that combined coverage. For such displays, coverage and gaps will be displayed as longitude-latitude rectangles in the planetocentric or planetodetic systems, or as X-Y rectangles in the rectangular system. Spatial coverage: Gaps and Padding
Spatial coverage gaps also can occur due to the way data are grouped in segments by a DSK file's creator. Normally DSK file creators should ensure that segments don't have coverage gaps that users would not expect. Coverage gaps can cause geometric computations to fail at run time. The concept of spatial coverage gaps normally applies to a segment's domain coordinates, such as longitude and latitude. It is also possible for a surface's maximum or minimum height, radius, or Z coordinate to be, respectively, strictly less than or strictly greater than the corresponding upper or lower bound. The term ``gap'' usually does not apply to such differences; these differences usually have no impact on computations. Data for a segment need not be confined to the spatial region delimited by the spatial bounds. DSK creators can include in DSK segments ``padding'' data that extend slightly beyond the segments' spatial bounds. Padding data can ensure that coverage implied by a segment's domain coordinate bounds is really present. Time Bounds
For a surface having a shape that evolves over a time span of interest, multiple versions of the surface corresponding to different time intervals can be created. When a computation is performed for a particular time, only segments providing data for time intervals that include that time will be considered. In many cases the surface represented by a DSK segment is considered to be constant with respect to time, so the start and stop time bounds may be set, respectively, to values far in the past and future (for example, plus or minus one century) relative to the time range for which the segment is expected to be used. Data Types
DSK data type 2 represents body shapes using collections of triangular plates. Another DSK data type, not yet implemented, will represent surfaces as digital elevation models (DEMs). The Mice system's high-level geometry functions operate without reference to the data types of DSK segments providing shape data to these routines. These routines require lower-level, type-dependent routines to provide functionality that is common across all DSK data types, such as ``find the intercept of a ray with the surface defined by a segment,'' or ``return the unit length outward normal vector at a specified point on the surface defined by a segment.'' Some Mice functions perform functions specific to particular data types. For example, the functions cspice_dskv02 and cspice_dskp02 return, respectively, vertices and plates from a type 2 segment. Data Classes
Data Competition and Priority
Unlike the other SPICE binary kernel systems, the DSK subsystem does not necessarily make use of segment priority for a given computation. Instead, a user application can specify that a computation is ``unprioritized.'' This means that all loaded data for the given body and a specified list of surfaces are to be used together to represent the shape to be used in the computation. When DSK data for different surfaces for one body are loaded concurrently, surface lists, which are inputs to Mice API functions that use DSK data, can be used to ensure that the correct set of DSK data are used for a given computation, and that none of the data compete. It is not necessary to load or unload DSK files to give the desired data top priority. See the API documentation for any high-level Mice geometry function, for example cspice_sincpt, for a discussion of surface lists. In the N0066 Mice Toolkit, all high-level geometry functions that work with DSK data support only unprioritized computations. Although not currently used, the DSK subsystem does have a priority scheme: as in the SPICE SPK, CK, and binary PCK subsystems, when two segments from the same file compete, the one located later in the file (at higher addresses) takes precedence. When two segments from different files compete, the one from the file loaded later takes precedence. Greedy Algorithms
The possibility of false negatives, at a minimum, complicates the design of user applications that depend on DSK data. Aside from errors in DSK files themselves, the main cause of false negative results is round-off error. Round-off error can cause a ray that should hit the common edge between two plates to be determined, according to double precision arithmetic, to miss both plates. Similarly, round-off error can cause a ray that should hit the common longitude boundary or latitude boundary shared by two DSK segments to hit neither segment boundary. The DSK subsystem uses several techniques to avoid false negative results for ray-surface intercepts. These fall into the category of ``greedy algorithms'': they effectively treat segments and data as though they occupy not only the spatial regions implied by their boundaries, but the surrounding regions as well. (An examination of the default DSK ``greedy'' parameters will reveal that the greediness of DSK algorithms is a mild case. See ``Access to DSK Tolerances and Margin Values'' below.) For example, when a ray-surface intercept computation is attempted, an intercept is considered to exist if the ray passes sufficiently close to the target---not only if it hits. Greedy Ray-Segment Boundary Intercepts
By default, when the ray's intersection with a segment's tangent surface is computed, if that intersection is close to the spatial region indicated by the segment's boundaries, an intersection with the segment is considered to exist. In the example we're using, a ray's intersection with the sphere of radius 6400 km that has longitude slightly greater than 30 degrees and latitude slightly greater than 45 degrees could be considered an intersection with the segment's boundary, if the longitude and latitude excursions are within margins. The goal is to ensure that any segment that the ray might hit is considered for a more detailed intercept computation. DSK Type 2 Plate Expansion
The default plate expansion fraction is 1e-10. The expansion factor is
1 + expansion_fraction Additional Greedy Algorithms
DSK Tolerances
Drawbacks
For example, if a ray hits the edge of an expanded plate, and that plate has a maximum edge length of 1 km, then the ray might have missed the original plate by as much as 0.1 millimeters. After missing the original plate, the ray might hit the surface far from that plate, or it might miss the target altogether. This issue, while it may appear serious, is a normal consequence of using finite precision arithmetic. A comparable difference in results might be observed were the computation without plate expansion performed on two different computer systems. Access to DSK Tolerances and Margin Values
The parameters used for greedy algorithms are user-adjustable. Applications can call the functions cspice_dskgtl or cspice_dskstl to fetch or reset these parameters at run time. It is recommended that the parameters be reset only by expert users. DSK Files
The DSK file format is based on two lower-level SPICE file formats: the DSK format is a special case of the SPICE DLA format, which in turn is a special case of SPICE DAS format. DAS Files
DLA Files
DLA files indicate the DAS addresses and sizes of their segments' character, double precision, and integer components using data structures called ``DLA descriptors.'' The DLA segment descriptor members are:
+---------------+ | BACKWARD PTR | Linked list backward pointer +---------------+ | FORWARD PTR | Linked list forward pointer +---------------+ | BASE INT ADDR | Base DAS integer address +---------------+ | INT COMP SIZE | Size of integer segment component +---------------+ | BASE DP ADDR | Base DAS d.p. address +---------------+ | DP COMP SIZE | Size of d.p. segment component +---------------+ | BASE CHR ADDR | Base DAS character address +---------------+ | CHR COMP SIZE | Size of character segment component +---------------+The ``base address'' of a segment component of a given data type is the address, in the DAS address space of that type, preceding the first element of that component. All DAS addresses are 1-based. DLA descriptors are used in the DSK subsystem to identify locations of the components of DSK segments within DSK files. See the DLA Required Reading, dla.req, for details concerning the DLA subsystem and file format. DSK File Format
+----------------------------------+ | File Record | +----------------------------------+ | Comment Area | +----------------------------------+ | Segment 1 | +----------------------------------+ -+ | ... | | +----------------------------------+ | Optional | Segment N | | +----------------------------------+ -+That is, a DSK file contains some identification and bookkeeping information called a ``file record,'' it has a comment area, and it has one or more DSK segments containing shape data. The segments are connected to each other as a doubly linked list, and the list can be traversed in forward or backward order. (In the N0066 Mice and Icy Toolkits, only forward traversal is supported.) Each DSK segment has integer and double precision components. These components occupy, respectively, contiguous ranges of DAS integer and double precision addresses:
+----------------------------------+ | Segment I | = +----------------------------------+ +--------------+ +------------------+ | | | | | Segment I: | | Segment I: | | | | | | Integer | + | Double | | Component | | Precision | | (optional) | | Component | | | | | +--------------+ | | | | +------------------+The double precision component of a segment can be further expanded as:
+------------------+ | | | Segment I: | | | | Double | | Precision | = | Component | | | | | +------------------+ +--------------+ +------------------+ | Segment I: | | Segment I: | | | | | | DSK Segment | + | Double | | Descriptor | | Precision | +--------------+ | Data | | (optional) | | | | + Bookkeeping | | Information | | (optional) | | | +------------------+The base addresses and sizes of a DSK segment's integer and double precision components are given by the segment's DLA descriptor. The DAS integer address range of a DSK segment is
integer base address+1 : integer base address+ integer component sizeSimilarly, the DAS double precision address range of a DSK segment is
d.p. base address+1 : d.p. base address+ d.p. component sizeLow-level details of the general DSK file format, if not discussed in this document, can be obtained from the DAS Required Reading, das.req, and from the DLA Required Reading, dla.req. An abstract view of a DSK segment---a view that ignores physical file layout and numeric data types---is
DSK segment = +-------------------------------------+ | DSK Descriptor | +-------------------------------------+ | Type-specific shape data | +-------------------------------------+ | Type-specific ancillary information | +-------------------------------------+DSK segments of all data types contain DSK descriptors. Further details of the DSK segment's structure are data type-dependent. Currently there is just one DSK data type: type 2. It is discussed below. DSK Type 2: Triangular Plate Model
Type 2 Shape Data
Each triangular plate has three vertices: type 2 data consist of a set of vertices and a set of ``plates'' to which the vertices belong. Vertices
The components of a vertex are expressed in the body-fixed reference frame of the DSK segment to which the vertex belongs. Each vertex represents an offset from the center of that reference frame. The center of a type 2 segment's reference frame need not coincide with the body for which the segment provides data. For example, vertices for a DSK segment representing Mars topography might be expressed in a Mars topocentric frame; the vertices would then represent offsets from the Mars surface point at the center of that frame. Within a type 2 segment, vertex components are always expressed in units of km, regardless of the units associated with the input data from which the segment was constructed. Each vertex has an associated integer ID; vertex IDs range from 1 to NV, where NV is the number of vertices in the segment. This 1-based numbering scheme is used for all language versions of SPICE, so the vertex IDs in a DSK file match those used in SPICE DSK code on all platforms. Plates
As a data structure, a plate is a 3-tuple of integer vertex IDs that indicate which vertices belong to that plate. Each plate has an associated ``outward normal'' direction: this direction is perpendicular to the plate. For surfaces that constitute boundaries of solid objects---for example, a sphere---the outward normal direction has the usual meaning: it points toward the exterior of the object. For other surfaces, for example a single plate, the outward normal direction may be an arbitrary choice. The order of a plate's vertices implies the outward normal direction: if the vertices are
V(1), V(2), V(3)then the outward normal direction is
( V(2) - V(1) ) x ( V(3) - V(2) )where ``x'' denotes the vector cross product operator. DSK creators must take vertex order into account when they define the plates of a DSK type 2 segment. As the formula above shows, the outward normal direction is undefined if two or three vertices of a plate coincide; in this case the ``plate'' is actually a line segment or a point. Plates having these characteristics are termed ``degenerate.'' Even if all of a plate's vertices are distinct, the normal direction vector suffers great loss of precision if the angle between two plate edges is very close to zero. Degenerate and nearly degenerate plates are allowed in type 2 segments, but it is strongly recommended that DSK creators exclude them from input data sets. Such plates can cause run-time failures of user applications performing functions that require outward normal directions to exist, for example computing emission and solar incidence angles. Each plate has an associated integer ID; plate IDs range from 1 to NP, where NP is the number of plates in the segment. This 1-based numbering scheme is used for all language versions of SPICE, so the plate IDs in a DSK file match those used in SPICE DSK code on all platforms. Type 2 Ancillary Information
A DSK type 2 spatial index consists of a ``voxel-plate mapping'' and optionally, a ``vertex-plate mapping,'' as well as various associated parameters. All DSK type 2 segments contain a voxel-plate mapping. This mapping enables DSK type 2 software to rapidly determine which plates are near a specified ray or point. Pointers and Offsets
In a DSK type 2 segment, pointers and offsets are expressed relative to the DAS base addresses of that segment, or relative to the DAS addresses of other members of the segment. This ensures that the segment is ``relocatable'': it has no dependence on its absolute DAS addresses and can be moved or copied without corrupting its contents. DSK Type 2 Segment Parameters
A subset of these parameters refer to the segment's voxel grids. They are listed here; they are explained later in context.  A segment's fine voxel grid contains all vertices in the segment (and therefore all plates); a small margin is used so that no plate contacts the grid's boundary. Thus no point on or outside of the grid's boundary can touch a plate. The fine voxel grid is fully characterized by
The diagram below shows the position of the fine voxel grid relative to its origin, the orientation of the grid relative to the reference frame's axes, and the relationship between the grid extents and the dimensions of the fine voxel grid. In this diagram
.------------. ^ fine voxel count = / /| | VGREXT(3) / / | | / / | | length = / / | | VGREXT(3) * VOXSIZ (km) ^ +Z / / . . v | . .------------. / / | / | | / / | /+Y | | / / fine voxel count = VRGEXT(2) | / | | / / |/ | |/ / length = *-------> O------------* * VGREXT(2) * VOXSIZ (km) +X <------------> fine voxel count = VGREXT(1) length = VGREXT(1) * VOXSIZ (km) Fine Voxel Scale
A plate's ``extent'' in the direction of coordinate axis i is the maximum value of coordinate i, taken over the plate's three vertices, minus the minimum value of coordinate i, also taken over the plate's three vertices. The average extent of a segment's plate set is the average of all the the plates' extents in the X, Y, and Z directions. The fine voxel scale maps the plate set's extents to a voxel size by:
VOXSIZ = file_voxel_scale * average_plate_extent Coarse Voxel Grid
The voxels of the coarse grid are cubes of identical size. The edge length of the coarse voxels is an integer multiple of the fine voxels' edge length. Let CGRSCL represent this multiple; then each coarse voxel contains
3 CGRSCLfine voxels. We use the term ``parent'' to refer to the unique coarse voxel that contains a specified fine voxel. Each extent of the fine voxel grid is
CGRSCLtimes the corresponding extent of the coarse grid. The diagram below shows the relationship between the coarse voxel grid's extents and edge lengths. The integer array VGREXT, as above, contains the extents of the fine voxel grid. The parameter VOXSIZ contains the fine voxels' edge length.
.------------. ^ coarse voxel count = / /| | VGREXT(3) / CGRSCL / / | | / / | | length = / / | | VGREXT(3) * VOXSIZ (km) / / . . v .------------. / / | | / / coarse voxel count = VRGEXT(2)/CGRSCL | | / / | | / / length = | |/ / VGREXT(2) * VOXSIZ (km) *------------* * <------------> coarse voxel count = VGREXT(1) / CGRSCL length = VGREXT(1) * VOXSIZ (km)In the description below, the term ``integer'' refers to an element of the DAS integer address space. The DSK integer array representing the coarse voxel grid has one element for each coarse voxel. If any plates intersect the spatial region corresponding to a coarse voxel, the corresponding coarse voxel grid array element contains a pointer into the voxel-plate pointer array. If no plates intersect that spatial region, the voxel contains the value zero, which represents a null pointer. (Caution: for reasons of backward compatibility, the values zero and -1 are used in different parts of DSK type 2 segments indicate null pointers.) Note that during the construction of a spatial index, plate-voxel ``intersection'' may be determined using a margin so that plates very near a voxel are considered to intersect it. This is the case for DSK type 2 segments created by cspice_dskw02 and by MKDSK. A non-null pointer in a given coarse voxel is a 1-based index of a pointer set within the voxel-plate pointer array. The pointer set indicates the locations of plate lists associated with the fine voxels having the coarse voxel as a parent. The maximum coarse voxel count within a segment, SPICE_DSK02_MAXCGR, is set to
100000This value cannot be changed in any future version of SPICE. The value is small enough to make it practical for DSK type 2 software to buffer the entire coarse voxel grid in memory. In all DSK type 2 segments, SPICE_DSK02_MAXCGR integers are allocated for the coarse voxel grid, even if the grid is smaller. Purpose of the Coarse Voxel Grid
The coarse voxel grid allows type 2 segments to avoid storing pointers for all fine voxels, since only fine voxels belonging to non-empty coarse voxels require pointers. Since in many practical cases, the majority of coarse voxels are empty, this often greatly reduces the required number of pointers. The coarse voxel grid also tends to reduce the number of physical file reads necessary to determine the plate set relevant to a given computation, since DSK type 2 software often can use it to quickly determine that a given fine voxel is empty, without looking up a voxel-plate pointer and then a plate list for that voxel. Any fine voxel that belongs to an empty coarse voxel is empty as well, and typically the majority of empty fine voxels do belong to empty coarse voxels. Voxel-Plate Pointer Array
The pointer set for a given coarse voxel contains one pointer for each fine voxel having that coarse voxel as a parent, so there are
3 CGRSCLpointers in each set. Let NNECVX indicate the number of non-empty coarse voxels. Then the voxel-plate pointer array has the form:
+---------------------+ | pointer set 1 | +---------------------+ ... +---------------------+ | pointer set NNECVX | (number of non-empty coarse voxels) +---------------------+The mapping from the coarse voxel grid to pointer sets in the voxel-plate pointer array is determined by the segment's data, the voxel grid parameters, and the order in which the data are processed. As indicated in the following diagram, no particular relationship should be assumed to exist between a non-empty coarse voxel's coordinates in the coarse grid and the position of its pointer set in the voxel-plate pointer array:
Coarse voxel grid Voxel-plate pointer array +--------------------------------+ .->| pointer set for coarse voxel v | / +--------------------------------+ / +----------------+ / | NULL | / +----------------+ / | coarse voxel u |--./ ... +----------------+ /\ | coarse voxel v |-* \ +----------------+ \ ... \ +--------------------------------+ +----------------+ *--> | pointer set for coarse voxel u | | NULL | +--------------------------------+ +----------------+ ... | coarse voxel w |--. +----------------+ \ +--------------------------------+ | NULL | *-----> | pointer set for coarse voxel w | +----------------+ +--------------------------------+Above, the letters
u, v, windicate arbitrary voxel indices. The positions of the null values were selected for this example. They're not representative of an actual DSK segment. Within the voxel-plate pointer array, each pointer set has the form:
+-----------+ | pointer | voxel 1 +-----------+ ... +-----------+ | pointer | voxel CGRSCL**3 +-----------+Each pointer corresponds to a fine voxel in the coarse voxel associated with the pointer set. Treating the fine voxels in this coarse voxel as a 1-dimensional array, the first fine voxel maps to the first pointer, and so on. The ordering of the fine voxels is Fortran-style, so a fine voxel with 1-based indices (I, J, K) relative to its parent coarse voxel has the one-dimensional index
2 I + (J-1)*CGRSCL + (K-1)*CGRSCLThe fine voxel with coordinates (1, 1, 1) relative to the parent coarse voxel is located in parent voxel's corner having minimum X, Y, and Z values in the Cartesian coordinate system associated with the segment's reference frame. Voxel-Plate Association Array
Let NNEFVX be the total number of non-empty fine voxels in the fine grid. Let
v_1, v_2, ..., v_NNEFVXindicate NNEFVX indices of non-empty fine voxels in arbitrary order. The voxel-plate association array has the form:
+-------------------------+ | List for voxel v_1 | +-------------------------+ | List for voxel v_2 | +-------------------------+ ... +-------------------------+ | List for voxel v_NNEFVX | (number of non-empty fine voxels) +-------------------------+Let N be the number of plates in the plate list for voxel v_i. Let
p_1, p_2, ..., p_Nbe the plate IDs of these plates. The plate list for the fine voxel at index v_i has the form
+--------------------+ | List count = N | +--------------------+ | Plate ID p_1 | +--------------------+ ... +--------------------+ | Plate ID p_N | +--------------------+The mapping from a pointer in the voxel-plate pointer array to a plate list in the voxel-plate association array is determined by the segment's data, the voxel grid parameters, and the order in which the data are processed. As indicated in the following diagram, no particular relationship should be assumed to exist between the position of a pointer in the voxel-plate pointer array and the position of the corresponding plate list in the voxel-plate association array:
Voxel-plate Voxel-plate association array pointer array +-------------------------------+ .->| plate list for voxel u_2 | / +-------------------------------+ / / pointer set u / +----------------+ / | voxel u_1 |--./ ... +----------------+ /\ | voxel u_2 |-* \ +----------------+ \ ... \ +-------------------------------+ +----------------+ *--->| plate list for voxel u_1 | | NULL | +-------------------------------+ +----------------+ ... | voxel u_n |--. +----------------+ \ +-------------------------------+ | NULL | *------>| plate list for voxel u_n | +----------------+ +-------------------------------+ 3 CGRSCL elementsAbove, the letter ``u'' indicates an arbitrary pointer set in the voxel-plate pointer array, which contains NNECVX such sets. The positions of the null values were selected for this example. They're not representative of an actual DSK segment. Size of the Voxel-Plate Association Array
Other than the optional vertex-plate association array, the voxel-plate association array is the largest ancillary data structure in a DSK type 2 segment. The size, in units of integers, of this array is affected by the fine voxel scale, which is a user-selectable parameter. For a given plate and vertex set, the size of fine voxels varies in proportion to the fine voxel scale. Let NVOXPL be the size, in units of integers, of the voxel-plate association array; as above, let NNEFVX be the total count of non-empty fine voxels; let NP be the segment's plate count. A lower bound on NVOXPL is
NNEFVX + NPThis number reflects the plate counts for the plate lists of each non-empty fine voxel, plus the presence of each plate ID on at least one list. Normally, a large number of plates cross voxel boundaries and so have their IDs on multiple lists. Hence NVOXPL is normally larger than the lower bound shown above. Reducing the fine voxel size improves the discrimination of the fine grid, which can improve the efficiency of algorithms that must operate on plates associated with a specified spatial region. For example, in the ray-surface intercept computation, the count of plates associated with voxels intersected by the ray will usually decrease as the voxel size is reduced. However, as the fine voxel size is reduced, more plates cross voxel boundaries---such plates are on the plate list of each voxel they touch---and NVOXPL increases. The memory required to hold the spatial index increases as well; it may become too large to allow a program calling cspice_dskw02 (the utility MKDSK is one such program) to run successfully. If a DSK segment with a very large value of NVOXPL is successfully created, its large size may have a detrimental effect on disk access time. Spatial Index: Vertex-Plate Mapping
Currently (as of the time of release of the N0066 SPICE Toolkit) there are no Mice routines that rely on the vertex-plate mapping. Creation of this mapping is therefore optional. Both the DSK type 2 writer function cspice_dskw02 and the utility program MKDSK enable users to indicate whether to create a vertex-plate mapping in an output DSK segment.  Then the vertex-plate pointer array contains NV elements, and the ith element indicates the plate list associated with vertex i. The vertex-plate association array contains a plate list for each vertex:
+----------------------+ | List for vertex v_1 | +----------------------+ | List for vertex v_2 | +----------------------+ ... +----------------------+ | List for vertex v_NV | +----------------------+Let N be the number of plates in the plate list for vertex i. Let
p_1, p_2, ..., p_Nbe the plate IDs of these plates. The plate list for vertex i has the form
+--------------------+ | List count = N | +--------------------+ | Plate ID p_1 | +--------------------+ ... +--------------------+ | Plate ID p_N | +--------------------+The mapping from a vertex to a plate list in the vertex-plate association array is determined by the segment's data, the voxel grid parameters, and the order in which the data are processed. No particular relationship should be assumed to exist between a vertex ID and the position of the corresponding plate list in the vertex-plate association array. Size of the Vertex-Plate Mapping Array
Let NV be a DSK type 2 segment's vertex count, and let NP be the segment's plate count. Then the size, in units of integers, of the vertex-plate pointer array is
NVand the size of the vertex-plate association array is
NV + 3*NPThe latter value is due to the facts that
Layout of DSK Type 2 Segments
DSK Type 2 Integer Segment Component
+-----------------+ | NV | number of vertices +-----------------+ | NP | number of plates +-----------------+ | NVXTOT | total number of voxels +-----------------+ | VGREXT | voxel grid extents, 3 integers +-----------------+ | CGRSCL | coarse voxel grid scale +-----------------+ | VOXNPT | size of voxel-plate pointer list +-----------------+ | VOXNPL | size of voxel-plate association list +-----------------+ | VTXNPL | size of vertex-plate association list +-----------------+ | PLATES | NP 3-tuples of vertex IDs +-----------------+ | VOXPTR | voxel-plate pointer array, variable size +-----------------+ | VOXPLT | voxel-plate association list, variable size +-----------------+ | VTXPTR | vertex-plate pointer array, 0 or | | NV integers +-----------------+ | VTXPLT | vertex-plate association list, | | 0 or NV + 3*NP integers +-----------------+ | CGRPTR | coarse grid pointers, | | SPICE_DSK02_MAXCGR integers +-----------------+The sizes of all variable-size items are stored at known locations, so the starting position of any item can be calculated. Parameters specifying offsets of the items from the segment's base integer address are declared in DSKMice02.m. The segment's base integer address is available from the segment's DLA descriptor. Mice provides the low-level utility function cspice_dski02 to fetch any of the items shown above. Plates and the plate count may be fetched more conveniently using the routines cspice_dskp02 and cspice_dskz02. DSK Type 2 Double Precision Segment Component
+-------------------+ | DSK descriptor | SPICE_DSK_DSCSIZ d.p. values +-------------------+ | Vertex bounds | 6 d.p. values (min/max for each component) +-------------------+ | Voxel grid origin | 3 d.p. values +-------------------+ | Fine voxel size | 1 d.p. value +-------------------+ | Vertices | 3*NV d.p. values +-------------------+The parameter SPICE_DSK_DSCSIZ is declared in DSKMice02.m. Mice provides the low-level utility function cspice_dskd02 to fetch any of the items shown above. Vertices and the vertex count may be fetched more conveniently using the routines cspice_dskv02 and cspice_dskz02. The DSK segment descriptor layout is:
+---------------------+ | Surface ID code | +---------------------+ | Center ID code | +---------------------+ | Data class code | +---------------------+ | Data type | +---------------------+ | Ref frame code | +---------------------+ | Coord sys code | +---------------------+ | Coord sys parameters| 10 d.p. values +---------------------+ | Min coord 1 | +---------------------+ | Max coord 1 | +---------------------+ | Min coord 2 | +---------------------+ | Max coord 2 | +---------------------+ | Min coord 3 | +---------------------+ | Max coord 3 | +---------------------+ | Start time | +---------------------+ | Stop time | +---------------------+The DSK descriptor of a DSK segment may be fetched using the function cspice_dskgd. Coordinate System Parameters
The contents of this section are dependent on the coordinate system. For planetodetic coordinates, the contents are:
+------------------------+ | Equatorial radius (km) | +------------------------+ | Flattening coefficient | +------------------------+ | <undefined> | 8 d.p. values +------------------------+These parameters define the axes of a reference ellipsoid. The length of the polar axis is
polar_axis = (1 - flattening_coefficient) * equatorial_axisFor planetocentric latitudinal and rectangular coordinates, all elements are undefined. DSK subsystem computations involving a DSK segment always use the coordinate parameters stored in that segment. These parameters may differ from those specified in a text PCK used by the same application program, or from those specified in a different segment for the same body. It is not necessarily an error for different sets of coordinate parameters to be used in a computation, but DSK users should be aware of which parameters are used for which purpose. Common ProblemsSlow DSK Computations
SPICE users can speed up DSK computations by several means:
Non-Portable and Unstable Results
These problems are best avoided at the time application software is designed: software developers must account for the effects of round-off error. Non-Convex and Multi-Valued Surfaces
Even a slight deviation from convexity can change numerical results considerably from those obtained using a triaxial ellipsoid model. For example, depending on whether there is a mountain in the foreground or whether the intercept lies in a valley (oriented in the general direction of the ray's projection on the surface), the range from an observer to a ray-surface intercept point can be much shorter or longer than the distance to the ray's intercept on the target body's reference ellipsoid. Non-convex surfaces can, in some cases, render some geometric quantities undefined or unusable. For example, the nearest surface point to a given point, not on the surface, can have multiple solutions, all in substantially different directions from the given point. Another example: the origin of a body-fixed reference frame for an object may be outside of the object--- a surface modeling a planetary ring would have this property. Multi-valued surfaces are those for which, for a given latitude and longitude, or for a given (X,Y) value, there are multiple radius or height values. These surfaces can occur due to presence of topographic features such as cliffs, caves, and arches. They can also occur due to the large-scale shape of an object, as is the case for the nucleus of the comet Churyumov-Gerasimenko. Multi-valued surfaces invite new categories of errors not possible with single-valued, non-convex surfaces. For example, for a given observer position, the sub-observer point can vary depending on the observer's altitude. Software meant for use with single-valued surfaces, for example the function cspice_latsrf, may yield incorrect results for such cases. Multi-valued surfaces can yield discontinuities in derived quantities that are well-behaved when an ellipsoid is used to model the target's shape. For example, when an observing spacecraft overflies a cliff, the observer's altitude can change discontinuously. If the sub-spacecraft point is corrected for light time, the light time algorithm may converge slowly or not at all. Again, these problems are best solved by designing application software to avoid assumptions appropriate only for ellipsoids. DSK File Creation Errors
MKDSK Setup File Errors
Data Errors
Segment Coverage Errors
This is an easy error to make when a large data set is distributed across multiple DSK files. The DSK creator may assume that the original plate set, partitioned among various files, will yield the same coverage as if all plates were stored in a single segment. Not so---each segment can only provide the coverage its DSK descriptor claims it has, so if a plate needed by a segment to provide coverage near, but within, that segment's boundary is allocated to a different segment, the first segment's coverage will have a gap. An artificial, but simple, example of this is a tessellation of a sphere, using triangular plates. Suppose that the surface is partitioned into a 6 x 12 grid of segments, each covering a 30 degree by 30 degree region of planetocentric longitude and latitude. Suppose each segment contains 225 pairs of plates such that each pair covers a longitude-latitude rectangle having angular extent 2 degrees by 2 degrees, so each segment is ``covered'' by 450 plates. Consider the segment covering the coordinate rectangle
Planetocentric longitude (deg): 0 to +30 Planetocentric latitude (deg): +30 to +60For each plate having two vertices on the segment's southern boundary, the edge of that plate connecting those vertices has latitude greater than 30 degrees everywhere but at the vertices themselves. At the midpoint of that edge, the latitude is actually about 30.00378 degrees. A ray aimed from an exterior vertex to the center of the sphere will miss the surface if the longitude of the vertex is 15 degrees and latitude of the vertex is above 30 degrees but less than the latitude of the edge's midpoint. The solution is to create each segment using ``padding''---additional plates extending slightly beyond the segment's southern boundary, so no ray emanating from the origin and hitting the sphere within the segment's longitude-latitude coverage can miss all of the segment's plates. The same problem exists for all southern segment latitude boundaries having positive latitude, and for all northern segment latitude boundaries having negative latitude. All of these boundaries require padding in order to achieve the intended coverage. Poor Data Distribution Across Segments
A seemingly attractive choice that can lead to this problem is partitioning a large data set into a small number of files, each of which contains a large number of plates. Type 2 segments can contain 10000000 or more plates (see Appendix B), but as a segment's plate count increases, the speed of DSK ray-surface intercept computations decreases. Experience indicates that DSK ray-surface intercepts exhibit an ``economy of small scale'' phenomenon, whereby spreading data across multiple, small segments tends to improve performance. This is true only up to a point: as the number of segments grows, the amount of time spent reading new data when switching from one segment to another grows. At some point this overhead becomes a significant drag on performance. Appendix A --- Revision History2017 APR 05 by N. J. Bachman.
Appendix B --- DSK Subsystem Limits
See the file
DSKMice02.mfor declarations of public parameters defining DSK limits. General Limits
DSK Type 2 Segment Limits
PC-64BIT-MS_C PC-CYGWIN-64BIT-GCC_C PC-CYGWIN-64BIT-GFORTRAN PC-CYGWIN-GFORTRAN PC-CYGWIN_C PC-MS_C PC-WINDOWS-64BIT-IFORT PC-WINDOWS-IFORT SUN-SOLARIS SUN-SOLARIS-64BIT-GCC_C SUN-SOLARIS-64BIT-NATIVE_C SUN-SOLARIS-GCC_C SUN-SOLARIS-NATIVE_Cthe following limits apply:
|


UX/UI Design, Visual Design,
Interaction Design, Information Architecture
Research, Prototyping, Usability Testing
Kaus is a leading the way in the insurance industry. With over 30 years of business, they have been working through regional agents, selling the policies to them instead of directly to customers. However, with the rise of internet and personal devices, Kaus has been losing ground. See what I did to help them catch up.
To gain an understanding of the current state of insurance and our users, I conducted interviews, created an competitive analysis document, and an empathy map. These documents helped me gain insights about what our users need and want from this product. I then created an Empahy map to synthesize my findings and developed my persona, Justin Lopez, to represent my target audience.
Once I determined what Justin's needs and goals were, I created a site map, user flow, task flow, and card sorting document to begin strategizing how information would be laid out for this website.
Once I had the information I needed, I created wireframes to help lay it out. I then designed a brand style tile, new logos and UI kit to bring out the messsage of what KAUS is about.
Bringing all of my design documents together, I created a high fidelity prototype to test my design desicions with users. I used an Affinity Map to create pull out common problems users had with my designs and applied revisions to the new version.
After updating my previous designs, I would re test my prototype again to new users. Once it is in a good place and ia approved by our stakeholders, I can start handing off the design to the engineering team.


 Makes me feel all smug about using Linux, although I have lots of Mac using Geek friends who are definitely not wallies. Mind you if it's a choice between Windows and OS/X I think I'll "take a Mac please Bob". And I know lots of you don't have a choice and are stuck on Blue-Screen-of-Death-Ville.
powered by performancing firefox


Order(order_number, product_name, email)
Our table consists of 3 columns to capture the order details.
We created the following query:
SELECT Customer.*, Order.Order_number, Order.Product_name FROM Customer INNER JOIN [Order] ON Customer.email = Order.email where product_name='Apples';
The above query displays the customer details along with one of the customer order detail where the product that was ordered is "Apples". We link the two tables based on the email address field and ask the query to fetch all fields of customer table and the order_number and product name field of order table.


14 June 2005
On 14 June 2005, five new polio cases were confirmed in Indonesia, bringing the total number of cases to 39. Three of these cases are from the same district as the index case (Sukabumi district), and two are from a neighbouring district (Bogor district).


Are you sure you want to purchase this coupon?
The Coupon was purchased Successfully!
Please choose a coupon first


Christmas Countdown
0
0
0
Days
0
Hour
0
Minutes
0
Seconds
He who has not Christmas in his heart will never find it under a tree.
Roy L. Smith


Sharethat!
Social Share Alternative!
Share to Facebook
Tweet it!
Share to Google+
Share to Likedin
Pin to Pinterest!


public interface RawGridSource extends DataSource
RawGridElements
as well as the RawGridElements
container as well from different data
sources e.g. .csv files or databases.| Modifier and Type | Method and Description |
|---|---|
java.util.Set<Transformer2WInput> |
get2WTransformers()
Returns a unique set of
Transformer2WInput instances. |
java.util.Set<Transformer2WInput> |
get2WTransformers(java.util.Set<NodeInput> nodes,
java.util.Set<Transformer2WTypeInput> transformer2WTypes,
java.util.Set<OperatorInput> operators)
Returns a set of
Transformer2WInput instances. |
java.util.Set<Transformer3WInput> |
get3WTransformers()
Returns a unique set of
Transformer3WInput instances. |
java.util.Set<Transformer3WInput> |
get3WTransformers(java.util.Set<NodeInput> nodes,
java.util.Set<Transformer3WTypeInput> transformer3WTypeInputs,
java.util.Set<OperatorInput> operators)
Returns a set of
Transformer3WInput instances. |
java.util.Optional<RawGridElements> |
getGridData()
Should return either a consistent instance of
RawGridElements wrapped in Optional or an empty Optional . |
java.util.Set<LineInput> |
getLines()
Returns a unique set of
LineInput instances. |
java.util.Set<LineInput> |
getLines(java.util.Set<NodeInput> nodes,
java.util.Set<LineTypeInput> lineTypeInputs,
java.util.Set<OperatorInput> operators)
Returns a set of
LineInput instances. |
java.util.Set<MeasurementUnitInput> |
getMeasurementUnits()
Returns a unique set of
MeasurementUnitInput instances. |
java.util.Set<MeasurementUnitInput> |
getMeasurementUnits(java.util.Set<NodeInput> nodes,
java.util.Set<OperatorInput> operators)
Returns a set of
MeasurementUnitInput instances. |
java.util.Set<NodeInput> |
getNodes()
Returns a unique set of
NodeInput instances. |
java.util.Set<NodeInput> |
getNodes(java.util.Set<OperatorInput> operators)
Returns a set of
NodeInput instances. |
java.util.Set<SwitchInput> |
getSwitches()
Returns a unique set of
SwitchInput instances. |
java.util.Set<SwitchInput> |
getSwitches(java.util.Set<NodeInput> nodes,
java.util.Set<OperatorInput> operators)
Returns a set of
SwitchInput instances. |
java.util.Optional<RawGridElements> getGridData()
RawGridElements
wrapped in Optional
or an empty Optional
. The decision to use Optional
instead of
returning the RawGridElements
instance directly is motivated by the fact, that a RawGridElements
is a container instance that depends on several other entities. Without being
complete, it is useless for further processing.
Hence, whenever at least one entity RawGridElements
depends on cannot be provided,
Optional.empty()
should be returned and extensive logging should provide enough
information to debug the error and fix the persistent data that has been failed to processed.
Furthermore, it is expected, that the specific implementation of this method ensures not
only the completeness of the resulting RawGridElements
instance, but also its validity
e.g. in the sense that not duplicate UUIDs exist within all entities contained in the returning
instance.
RawGridElements
optional or Optional.empty()
java.util.Set<NodeInput> getNodes()
NodeInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided NodeInput
which has to be checked manually,
as NodeInput.equals(Object)
is NOT restricted on the uuid of NodeInput
.
NodeInput
entitiesjava.util.Set<NodeInput> getNodes(java.util.Set<OperatorInput> operators)
NodeInput
instances. This set has to be unique in the sense of object
uniqueness but also in the sense of UUID
uniqueness of the provided NodeInput
which has to be checked manually, as NodeInput.equals(Object)
is NOT
restricted on the uuid of NodeInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of OperatorInput
entities, the NodeInput
instances depend on.
Doing so, already loaded nodes can be recycled to improve performance and prevent unnecessary
loading operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesNodeInput
entitiesjava.util.Set<LineInput> getLines()
LineInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided LineInput
which has to be checked manually,
as LineInput.equals(Object)
is NOT restricted on the uuid of LineInput
.
LineInput
entitiesjava.util.Set<LineInput> getLines(java.util.Set<NodeInput> nodes, java.util.Set<LineTypeInput> lineTypeInputs, java.util.Set<OperatorInput> operators)
LineInput
instances. This set has to be unique in the sense of object
uniqueness but also in the sense of UUID
uniqueness of the provided LineInput
which has to be checked manually, as LineInput.equals(Object)
is NOT
restricted on the uuid of LineInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of NodeInput
, LineTypeInput
and OperatorInput
entities,
the LineInput
instances depend on. Doing so, already loaded nodes, line types and
operators can be recycled to improve performance and prevent unnecessary loading operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesnodes
- a set of object and uuid unique NodeInput
entitieslineTypeInputs
- a set of object and uuid unique LineTypeInput
entitiesLineInput
entitiesjava.util.Set<Transformer2WInput> get2WTransformers()
Transformer2WInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided Transformer2WInput
which has to be checked
manually, as Transformer2WInput.equals(Object)
is NOT restricted on the uuid of Transformer2WInput
.
Transformer2WInput
entitiesjava.util.Set<Transformer2WInput> get2WTransformers(java.util.Set<NodeInput> nodes, java.util.Set<Transformer2WTypeInput> transformer2WTypes, java.util.Set<OperatorInput> operators)
Transformer2WInput
instances. This set has to be unique in the sense
of object uniqueness but also in the sense of UUID
uniqueness of the provided
Transformer2WInput
which has to be checked manually, as Transformer2WInput.equals(Object)
is NOT restricted on the uuid of Transformer2WInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of NodeInput
, Transformer2WTypeInput
and OperatorInput
entities, the Transformer2WInput
instances depend on. Doing so, already loaded nodes,
line types and operators can be recycled to improve performance and prevent unnecessary loading
operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesnodes
- a set of object and uuid unique NodeInput
entitiestransformer2WTypes
- a set of object and uuid unique Transformer2WTypeInput
entitiesTransformer2WInput
entitiesjava.util.Set<Transformer3WInput> get3WTransformers()
Transformer3WInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided Transformer3WInput
which has to be checked
manually, as Transformer3WInput.equals(Object)
is NOT restricted on the uuid of Transformer3WInput
.
Transformer3WInput
entitiesjava.util.Set<Transformer3WInput> get3WTransformers(java.util.Set<NodeInput> nodes, java.util.Set<Transformer3WTypeInput> transformer3WTypeInputs, java.util.Set<OperatorInput> operators)
Transformer3WInput
instances. This set has to be unique in the sense
of object uniqueness but also in the sense of UUID
uniqueness of the provided
Transformer3WInput
which has to be checked manually, as Transformer3WInput.equals(Object)
is NOT restricted on the uuid of Transformer3WInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of NodeInput
, Transformer3WTypeInput
and OperatorInput
entities, the Transformer3WInput
instances depend on. Doing so, already loaded nodes,
line types and operators can be recycled to improve performance and prevent unnecessary loading
operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesnodes
- a set of object and uuid unique NodeInput
entitiestransformer3WTypeInputs
- a set of object and uuid unique Transformer3WTypeInput
entitiesTransformer3WInput
entitiesjava.util.Set<SwitchInput> getSwitches()
SwitchInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided SwitchInput
which has to be checked
manually, as SwitchInput.equals(Object)
is NOT restricted on the uuid of SwitchInput
.
SwitchInput
entitiesjava.util.Set<SwitchInput> getSwitches(java.util.Set<NodeInput> nodes, java.util.Set<OperatorInput> operators)
SwitchInput
instances. This set has to be unique in the sense of
object uniqueness but also in the sense of UUID
uniqueness of the provided
SwitchInput
which has to be checked manually, as SwitchInput.equals(Object)
is
NOT restricted on the uuid of SwitchInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of NodeInput
and OperatorInput
entities, the SwitchInput
instances depend on. Doing so, already loaded nodes, line types and operators can be recycled
to improve performance and prevent unnecessary loading operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesnodes
- a set of object and uuid unique NodeInput
entitiesSwitchInput
entitiesjava.util.Set<MeasurementUnitInput> getMeasurementUnits()
MeasurementUnitInput
instances.
This set has to be unique in the sense of object uniqueness but also in the sense of UUID
uniqueness of the provided MeasurementUnitInput
which has to be checked
manually, as MeasurementUnitInput.equals(Object)
is NOT restricted on the uuid of
MeasurementUnitInput
.
MeasurementUnitInput
entitiesjava.util.Set<MeasurementUnitInput> getMeasurementUnits(java.util.Set<NodeInput> nodes, java.util.Set<OperatorInput> operators)
MeasurementUnitInput
instances. This set has to be unique in the sense
of object uniqueness but also in the sense of UUID
uniqueness of the provided
MeasurementUnitInput
which has to be checked manually, as MeasurementUnitInput.equals(Object)
is NOT restricted on the uuid of MeasurementUnitInput
.
In contrast to getNodes()
this interface provides the ability to pass in an already
existing set of NodeInput
and OperatorInput
entities, the MeasurementUnitInput
instances depend on. Doing so, already loaded nodes, line types and
operators can be recycled to improve performance and prevent unnecessary loading operations.
If something fails during the creation process it's up to the concrete implementation of an empty set or a set with all entities that has been able to be build is returned.
operators
- a set of object and uuid unique OperatorInput
that should be used for
the returning instancesnodes
- a set of object and uuid unique NodeInput
entitiesMeasurementUnitInput
entities


{{ readable_exception }}
Refresh
the page to try again
If it persists, please
email
someone in the Tech dept and summarize what you were trying to do. You don't need to email us this page.


This page shows information about a particular order retrieved through the
/orders
endpoint.
At the left hand side there is payment information and a link to its corresponding invoice.
Next to it there is a form to update its
custom tags
At the bottom the order items are displayed. They cointain basic information about the product, its
fulfillments and
a form to update its attributes .


---
layout: post
title: Isogeometric Analysis special issue
tags: publications
author: Clemens Verhoosel
---
Two Nutils-powered research articles have been submitted for publication in
the Isogeometric Analysis special issue of Computer Methods in
Applied Mechanics and Engineering.
- C.V. Verhoosel, G.J. van Zwieten, B. van Rietbergen and R. de Borst.
Image-based goal-oriented adaptive isogeometric analysis with application
to the micro-mechanical modeling of trabecular bone
- T.M. van Opstal, E.H. van Brummelen and G.J. van Zwieten. A
finite-element/boundary-element method for large-displacement fluid-structure
interaction
Download links will be posted after the review process has been
completed.


WITNESS LIST Business & Industry Committee August 5, 2003-11:00A TWCC Implementation HB 2600 On: Nemith, William (TWCC) Shipe, Robert (TWCC)


{% include get_project_from_slug.liquid slug=include.slug %} {% include get_project_image.liquid project=project %}
{{ project.description }}
{% assign image_filenames = '' %} {% for image in project.images %} {% assign image_filenames = image_filenames | append: image.filename %} {% if forloop.last == false %} {% assign image_filenames = image_filenames | append: "," %} {% endif %} {% endfor %} {% include project_images_inline.liquid slug=project.slug filenames=image_filenames group="screenshots" %}| System Requirements | |
|---|---|
| Version: | {{ project.version }} |
| Updated: | {{ project.updated }} |
| Platform(s): | {{ project.platforms | join: ", " }} |
| Homepage: | {% include url_domain_extract.liquid url=project.homepage %}{% if project.homepage %}{{ domain }}{% else %}N/A{% endif %} |
| Open Source: | {{ project.open_source }} |
| License: | {{ project.license }} |
| Downloads | |
|---|---|
| {{ download.name }} {{ download.description }} |
Download |
| Examples | |
|---|---|
| {{ example.name }} {{ example.description }} |
View |
| Latest Blog Posts About {{ project.name }} | |
|---|---|
| {{ post.title }} | {{post.date | date: '%B %d, %Y' }} |
| No blog posts found :( |


Singularity and Docker¶
Singularity can be used with Docker images. This feature was included because developers use and really like using Docker, and scientists have already put much resources into creating Docker images. Thus, one of our early goals was to support Docker. What can you do?
You don’t need Docker installed
You can shell into a Singularity-ized Docker image
You can run a Docker image instantly as a Singularity image
You can pull a Docker image (without sudo)
You can build images with bases from assembled Docker layers that include environment, guts, and labels
TLDR (Too Long Didn’t Read)¶
You can shell, import, run, and exec Docker images directly from the Docker Registry.
singularity shell docker://ubuntu:latest
singularity run docker://ubuntu:latest
singularity exec docker://ubuntu:latest echo "Hello Dinosaur!"
singularity pull docker://ubuntu:latest
singularity build ubuntu.img docker://ubuntu:latest
Import a Docker image into a Singularity Image¶
The core of a Docker image is basically a compressed set of files, a set
of .tar.gz
that (if you look in your Docker image folder on your host
machine, you will see the files). The Docker Registry, which you probably interact
with via Docker Hub, serves these layers. These are the layers that
you see downloading when you interact with the docker daemon. We are
going to use these same layers for Singularity!
Quick Start: The Docker Registry¶
The Docker engine communicates with the Docker Hub via the Docker Remote API, and so can Singularity. The easiest thing to do is create an image, and then pipe a Docker image directly into it from the Docker Registry. You don’t need Docker installed on your machine, but you will need a working Internet connection. Let’s create an ubuntu operating system, from Docker. We will pull, then build:
singularity pull docker://ubuntu
WARNING: pull for Docker Hub is not guaranteed to produce the
WARNING: same image on repeated pull. Use Singularity Registry
WARNING: (shub://) to pull exactly equivalent images.
Docker image path: index.docker.io/library/ubuntu:latest
Cache folder set to /home/vanessa/.singularity/docker
[5/5] |===================================| 100.0%
Importing: base Singularity environment
Importing: /home/vanessa/.singularity/docker/sha256:9fb6c798fa41e509b58bccc5c29654c3ff4648b608f5daa67c1aab6a7d02c118.tar.gz
Importing: /home/vanessa/.singularity/docker/sha256:3b61febd4aefe982e0cb9c696d415137384d1a01052b50a85aae46439e15e49a.tar.gz
Importing: /home/vanessa/.singularity/docker/sha256:9d99b9777eb02b8943c0e72d7a7baec5c782f8fd976825c9d3fb48b3101aacc2.tar.gz
Importing: /home/vanessa/.singularity/docker/sha256:d010c8cf75d7eb5d2504d5ffa0d19696e8d745a457dd8d28ec6dd41d3763617e.tar.gz
Importing: /home/vanessa/.singularity/docker/sha256:7fac07fb303e0589b9c23e6f49d5dc1ff9d6f3c8c88cabe768b430bdb47f03a9.tar.gz
Importing: /home/vanessa/.singularity/metadata/sha256:77cece4ce6ef220f66747bb02205a00d9ca5ad0c0a6eea1760d34c744ef7b231.tar.gz
WARNING: Building container as an unprivileged user. If you run this container as root
WARNING: it may be missing some functionality.
Building Singularity image...
Cleaning up...
Singularity container built: ./ubuntu.img
The warnings are reminding you that you are creating the image on the fly from layers, and if one of those layers changes, you won’t produce the same image next time.
The Build Specification file, Singularity¶
Just like Docker has the Dockerfile, Singularity has a file called
Singularity that (currently) applications like Singularity Hub know to
find. For reproducibility of your containers, our strong
recommendation is that you build from these files. Any command that you
issue to change a container sandbox (building with --sandbox
) or to a build with --writable
is by default not recorded, and your container loses its
reproducibility. So let’s talk about how to make these files. First,
let’s look at the absolute minimum requirement:
Bootstrap: docker
From: ubuntu
We save this content to a file called Singularity and then issue the following commands to bootstrap the image from the file:
sudo singularity build ubuntu.img Singularity
A particular tag or version can be added to the docker uri:
Bootstrap: docker
From: ubuntu:latest
Note
Note that the default is latest
. If you want to customize the Registry or
Namespace, just add those to the header:
Bootstrap: docker
From: ubuntu
Registry: pancakes.registry.index.io
Namespace: blue/berry/cream
The power of build comes with the other things that you can do. This means running specific install commands, specifying your containers runscript (what it does when you execute it), adding files, labels, and customizing the environment. Here is a full Singularity file:
Bootstrap: docker
From: tensorflow/tensorflow:latest
%runscript
exec /usr/bin/python "$@"
%post
echo "Post install stuffs!"
%files
/home/vanessa/Desktop/analysis.py /tmp/analysis.py
relative_path.py /tmp/analysis2.py
%environment
TOPSECRET=pancakes
HELLO=WORLD
export HELLO TOPSECRET
%labels
AUTHOR Vanessasaur
In the example above, I am overriding any Dockerfile ENTRYPOINT
or CMD
because I have
defined a %runscript
. If I want the Dockerfile ENTRYPOINT
to take preference, I would remove
the %runscript
section. If I want to use CMD
instead of ENTRYPOINT
, I would again remove the
runscript, and add IncludeCmd to the header:
Bootstrap: docker
From: tensorflow/tensorflow:latest
IncludeCmd: yes
%post
echo "Post install stuffs!"
You can commit this Singularity file to a GitHub repo and it will automatically build for you when you push to Singularity Hub?. This will ensure maximum reproducibility of your work.
How does the runscript work?¶
Docker has two commands in the Dockerfile
that have something to do with
execution, CMD
and ENTRYPOINT
. The differences are subtle, but a good description
I’ve found is the following:
A
CMD
is to provide defaults for an executing container.
and
An
ENTRYPOINT
helps you to configure a container that you can run as an executable.
Given the definition, the ENTRYPOINT
is most appropriate for the Singularity %runscript
, and
so using the default bootstrap (whether from a docker://
endpoint or a Singularity
spec file)
will set the ENTRYPOINT
variable as the runscript. You can change this behavior by
specifying IncludeCmd: yes
in the Spec file (see below). If you provide any sort of %runscript
in
your Spec file, this overrides anything provided in Docker. In summary,
the order of operations is as follows:
If a
%runscript
is specified in the Singularity spec file, this takes prevalence over allIf no
%runscript
is specified, or if theimport
command is used as in the example above, theENTRYPOINT
is used as runscript.If no
%runscript
is specified, but the user has aSingularity
spec withIncludeCmd
, then the DockerCMD
is used.If no
%runscript
is specified, and there is noCMD
orENTRYPOINT
, the image’s default execution action is to run the bash shell.
How do I specify my Docker image?¶
In the example above, you probably saw that we referenced the docker
image first with the uri docker://
and that is important to tell Singularity that
it will be pulling Docker layers. To ask for ubuntu, we asked for docker://ubuntu
. This
uri that we give to Singularity is going to be very important to choose
the following Docker metadata items:
registry (e.g., “index.docker.io”)
namespace (e.g., “library”)
repository (e.g., “ubuntu”)
tag (e.g., “latest”) OR version (e.g., “@sha256:1234…)
When we put those things together, it looks like this:
docker://<registry>/<namespace>/<repo_name>:<repo_tag>
By default, the minimum requirement is that you specify a repository name (eg, ubuntu) and it will default to the following:
docker://index.docker.io/library/ubuntu:latest
If you provide a version instead of a tag, that will be used instead:
docker://index.docker.io/library/ubuntu@sha256:1235...
You can have one or the other, both are considered a “digest” in Docker speak.
If you want to change any of those fields and are having trouble with the uri, you can also just state them explicitly:
Bootstrap: docker
From: ubuntu
Registry: index.docker.io
Namespace: library
Custom Authentication¶
For both import and build using a build spec file, by default we use
the Docker Registry index.docker.io
. Singularity first tries the call without a
token, and then asks for one with pull permissions if the request is
defined. However, it may be the case that you want to provide a custom
token for a private registry. You have two options. You can either
provide a Username
and Password
in the build specification file (if stored locally and
there is no need to share), or (in the case of doing an import or
needing to secure the credentials) you can export these variables to
environmental variables. We provide instructions for each of these
cases:
Authentication in the Singularity Build File¶
You can simply specify your additional authentication parameters in the
header with the labels Username
and Password
:
Username: vanessa
Password: [password]
Again, this can be in addition to specification of a custom registry
with the Registry
parameter.
Authentication in the Environment¶
You can export your username, and password for Singularity as follows:
export SINGULARITY_DOCKER_USERNAME=vanessasaur
export SINGULARITY_DOCKER_PASSWORD=rawwwwwr
Testing Authentication¶
If you are having trouble, you can test your token by obtaining it on
the command line and putting it into an environmental variable, CREDENTIAL
:
CREDENTIAL=$(echo -n vanessa:[password] | base64)
TOKEN=$(http 'https://auth.docker.io/token?service=registry.docker.io&scope=repository:vanessa/code-samples:pull' Authorization:"Basic $CREDENTIAL" | jq -r '.token')
This should place the token in the environmental variable TOKEN
. To test that
your token is valid, you can do the following
http https://index.docker.io/v2/vanessa/code-samples/tags/list Authorization:"Bearer $TOKEN"
The above call should return the tags list as expected. And of course you should change the repository(repo) name to be one that actually exists that you have credentials for.
Best Practices¶
While most docker images can import and run without a hitch, there are some special cases for which things can go wrong. Here is a general list of suggested practices, and if you discover a new one in your building ventures please let us know.
1. Installation to Root¶
When using Docker, you typically run as root, meaning that root’s home
at /root
is where things will install given a specification of home. This situation is
fine when you stay in Docker, or if the content at /root
doesn’t need any
kind of write access, but generally it can lead to a lot of bugs because
it is, after all, root’s home. This leads us to best practice #1.
Don’t install anything to root’s home, /root
.
2. Library Configurations¶
The command ldconfig is used to update the shared library cache. If you have software that requires symbolic linking of libraries and you do the installation without updating the cache, then the Singularity image (in read only) will likely give you an error that the library is not found. If you look in the image, the library will exist but the symbolic link will not. This leads us to best practice #2:
Update the library cache at the end of your Dockerfile with a call to ldconfig.
3. Don’t install to $HOME or $TMP¶
We can assume that the most common Singularity use case has the $USER
home being automatically mounted to $HOME
, and $TMP
also mounted. Thus, given
the potential for some kind of conflict or missing files, for best
practice #3 we suggest the following:
Don’t put container valuables in $TMP
or $HOME
Have any more best practices? Please let us know!
Troubleshooting¶
Why won’t my image build work? If you can’t find an answer on this site, please send us an issue. If you’ve found an answer and you’d like to see it on the site for others to benefit from, then post to us here.


UKCloud Limited (“UKC”) and Virtual Infrastructure Group Limited (“VIG”) (together “the Companies”) – in Compulsory Liquidation
On 25 October 2022, the Companies were placed into Liquidation with the Official Receiver appointed as Liquidator and J Robinson and A M Hudson simultaneously appointed as Special Managers to manage the liquidation process on behalf of the Official Receiver.
Further information regarding the Liquidations can be found here: https://www.gov.uk/government/news/virtual-infrastructure-group-limited-and-ukcloud-limited-information-for-creditors-and-interested-parties
Contact details:
For any general queries relating to the Liquidations please email<EMAIL_ADDRESS>For customer related queries please email<EMAIL_ADDRESS>For supplier related queries please email<EMAIL_ADDRESS>Partitioning projects or end customers using UKCloud accounts
Overview
When you request your first service on UKCloud, you're given a single account. An account can represent an organisation, a customer contract or a specific project and contains one or more UKCloud services, such as UKCloud for VMware, Cloud Storage or UKCloud for OpenStack. Within an account, Portal administrators can set permissions for users so that they can access only those services and features that they are allowed to view and use. This is a simple way to manage smaller accounts, however the more projects or end customers you have, the more complicated and confusing the account can become without some degree of separation.
Multiple accounts are very useful when managing separate customer workloads, for example billing and organisation. They can help when different teams are working on separate projects within the same business by separating the projects into different accounts enabling easier identification and management of projects and personnel. This gives the correct level of access to each team to ensure their view of the environments is specific to their work.
If you decide that you would like to bring additional workloads to UKCloud, you should consider whether to stay with a single account or choose to have multiple accounts.
UKCloud account options
There are two options that you can choose from to manage your projects and end customers. The table below discusses the advantages and disadvantages of each option:
| Option 1: Multiple accounts | Option 2: Single account | |
|---|---|---|
| Use cases |
|
|
| Advantages | Enables administrators to set permissions for each account user so that they can access only the services that they are authorised to view and use. | |
| Enables easy identification of which services and users are associated with each account. | Provides easy access to all your projects in one place. | |
| Facilitates greater visibility of users within each account and better security with multiple end customers by reducing the risk of human error, ensuring that each user has the correct permissions associated with their UKCloud services within the accounts. | Enables easy tracking of billing for all your services in one place without the need to switch between accounts. | |
| Provides the ability to tighten and loosen security requirements based on the specifics of that workload. | Reduces the risk of human error, for example, raising a ticket in the wrong account. | |
| Provides the ability to increase or decrease security requirements on an account by account basis. For example, with our Two Factor Authentication, Portal administrators can set the optional extra security for some or all accounts. | ||
| Makes it easier to view individual account tickets without the need of a filter. | ||
| Disadvantages | Necessitates switching view in the Portal to see the services and tickets within each account. | Shows all tickets in a single list, making it more difficult to locate tickets for a particular project. Similarly with users for different workloads. |
| Introduces risk of human error, for example, raising a ticket in the wrong account. | Limits granularity of authentication; cannot set individual authentication methods for different workloads. |
Creating multiple accounts
When you bring a new workload to UKCloud, your Service Delivery Manager (SDM) will discuss your requirements and whether you want to create an additional account. If you decide that an additional account is best for your setup, UKCloud will create it for you. Once the additional account is created, the Portal administrator for the account can then add existing UKCloud Portal users to the account by raising a Service Request via the My Calls section of the UKCloud Portal or add new users to the UKCloud Portal onto the new account, which the administrator can add themselves.
Related articles
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to feedback@ukcloud.com.


---
layout: default
title: Julien Beaulieu's Blog on Data Science and Productivity
---
My name is Julien and I am a Data Scientist.
Ex digital marketer, manager, and a web analytics specialist. In 2018 I transitioned careers into machine learning to follow my passion for data analysis and optimization.
Today I am building machine learning projects in Python with a focus on NLP and software engineering.
I also have a passion for learning and education - I teach at Le Wagon's data science bootcamp and have built the Open Curriculai project.
It's goal is to democratize data science learning outside of the traditional education route by curating and organizing top resources found online in the form of a curriculum and a resource hub. It is linked below and has been viewed by thousands of people.
I decided to create this website to have somewhere to write about my projects and ideas related to learning data science.
I have a passion for traveling, taking pictures, chess, and food.
Add me on LinkedIn if you're interested to chat.
Thanks for reading!
Open Curriculai Project:
- Curriculum & resource hub for learning data science
Technical Articles:
- Building a Flexible Configuration System for Deep Learning Models
- Model Interpretation With Random Forests And Going Beyond Simple Predictions
- Applying Fastai Best Practices To A Kaggle Competition
Non-technical Articles:
- Lesser Known Facts About Learning & How to get Better at Studying
- Comprehensive Project Based Data Science Curriculum
- Transitioning into Data Science from a Non-Technical Background
- A Framework for Setting and Attaining Your Personal Goals
{% include subscription-form.html %}