Open Collections

UBC Theses and Dissertations

UBC Theses Logo

UBC Theses and Dissertations

A lower jurassic ammonite image database and its applications Liang, Bo 1994

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Item Metadata

Download

Media
831-ubc_1995-983825.pdf [ 63.48MB ]
Metadata
JSON: 831-1.0052912.json
JSON-LD: 831-1.0052912-ld.json
RDF/XML (Pretty): 831-1.0052912-rdf.xml
RDF/JSON: 831-1.0052912-rdf.json
Turtle: 831-1.0052912-turtle.txt
N-Triples: 831-1.0052912-rdf-ntriples.txt
Original Record: 831-1.0052912-source.json
Full Text
831-1.0052912-fulltext.txt
Citation
831-1.0052912.ris

Full Text

A LOWER JURASSIC AMMONITE IMAGE DATABASE AND ITS APPLICATIONS by BO LIANG B.Eng., Xiangtan Mining Institute, 1984 M.Eng., China University of Geosciences, 1987 A THESIS SUBMITTED IN PARTIAL FULFILMENT OF THE REQUIREMENTS FOR THE DEGREE OF DOCTOR OF PHILOSOPHY in THE FACULTY OF GRADUATE STUDIES GEOLOGICAL SCIENCES We accept this thesis as conforming to the required standard  THE UNIVERSITY OF BRITISH COLUMBIA May 1994 © B o Liang, 1994  In presentin g thi s thesi s i n partia l fulfilmen t o f th e requirement s fo r a n advance d degree a t th e Universit y o f Britis h Columbia , I agre e tha t th e Librar y shal l mak e i t freely availabl e fo r referenc e an d study . I furthe r agre e tha t permissio n fo r extensiv e copying o f thi s thesi s fo r scholarl y purpose s ma y b e grante d b y th e head . o f m y department o r b y hi s o r he r representatives . I t i s understoo d tha t copyin g o r publication o f thi s thesi s fo r financia l gai n shal l no t b e allowe d withou t m y writte n permission.  (Signature)  Department o f  fodlojifftil fatWA  The Universit y o f Britis h Columbi a Vancouver, Canad a Date  DE-6 (2/88 )  fldb.iV r99 f  ii  -  Abstract Amnion is the first computerized image database for ammonites that allows automated measurement o f morphologica l parameter s from images . Th e databas e contain s 779 0 specimens representing 1 5 families, 17 9 genera an d 131 9 species . Eac h specime n ha s 10 2 descriptors coverin g taxonomy , quantitativ e morphology , qualitativ e morphology , stratigraphy, locality information and general comments. Species density diagrams ar e plotted wit h respec t t o basi c shel l geometry. Th e dat a show stron g correlation s amon g basi c geometri c parameter s whic h ma y b e relate d t o restrictions imposed by whorl shape and size. Buckman's Law of Covariation is shown to be applicable to Lower Jurassic ammonite stocks and new covariations are demonstrated amon g tuberculation, ribbing , whor l shap e an d ventra l features , al l o f whic h hav e functiona l implications. Morphological an d stratigraphica l dat a from Amnion sugges t a possibl e correlatio n between basi c shel l geometry , morphologica l variabilit y an d tax a duration . Lo w within population morphological variabilities and short durations are associated with taxa that inhabit the most densely populated geometric region. Away fromthis peak, there is a steady increase in both morphological variability and taxa longevity implying a decrease in selective pressure. The taxonomic diversity of Lower Jurassic ammonites peaks first at the family level in the Ibex Zone, followed by generic data one zone later, and finally species in the Margaritatus Zone implying a delay in radiation for lowe r levels of ammonite taxa. Th e Late Sinemuria n and Earl y Pliensbachia n hav e hig h famil y originatio n rate s an d relativel y lo w specie s diversities; species reach their highest diversity level in the Late Pliensbachian which also has the highest family extinction rate and an almost zero origination rate. Two morphologica l diversit y indexe s ar e use d t o stud y change s throug h time . Th e range index describes the range of the morphospace occupied . Th e Shanno n index measures both the rang e and the evenness of the occupation. Bot h indexe s indicate a simila r pattern . There i s a rapi d ris e t o a n Earl y Sinemuria n maximu m throug h morphologica l radiation ,  ill  especially in terms of the basic shell geometry, followed b y a pronounced fal l i n the middle Sinemurian with diversity remaining relatively high and stable thereafter. It i s eviden t b y comparin g taxonomi c an d morphologica l diversit y change s throug h time tha t initia l morphologica l diversificatio n i n Lowe r Jurassi c ammonite s exceede d th e proliferation o f lower-level taxa. For example, th e morphological diversit y of the Bucklandi Zone with 46 species is slightly higher than that of the Margaritatus Zone with 17 7 species. It demonstrates that morphological diversit y and taxonomic diversity are not simpl y correlate d but that taxa initially occupy discrete positions within a broad morphospac e followe d b y the occupation of intervening areas. It i s observe d tha t al l Lowe r Jurassi c ammonit e familie s radiatin g int o numerou s species in th e firs t zon e o f their occurrenc e hav e duration s o f les s tha n 4 zones ; i n othe r words, rapid origination is associated with short duration.  Table of Contents Abstract i  i  Table of Contents i  v  Acknowledgments vi  i  Chapter 1 Introductio 1.1 Introductor 1.2 Previou  y Statement 1 s Work 2  1.3 Purpos Chapter 2 Th  n1  e and Scope 3 e Lower Jurassic Ammonite Image Database ~ Ammo n 5  2.1 Introductio  n5  2.2 Th  e Database Structure 6  2.3 SQ  L -- The Query Language 1  2.4 Dat  8  2.3.1 Dat a entry 1  9  2.3.2 Updatin g the database 1  9  2.3.3 Queryin g the database 2  0  2.3.4 Changin g the structure of the database 2  3  a Sources 2  Chapter 3 Imag  e Analytical Techniques 2  4 7  3.1 Introductio  n2  7  3.2 Digitizatio  n2  7  3.3 Interactiv  e Image Measurement Module 2  8  3.4 Automati  c Image Measurement 3  3  3.4.1 Preprocessin g 3  4  3.4.2 Edg e detection 3  4  3.4.3 Thinnin g and line tracing 3  5  3.4.4 Locatin g coiling axis 3  5  3.4.5 Classificatio n o f coiling curves and ribs 3  6  t  V  3.4.6 Derivin g morphological parameters 3 3.5 Fourie  r Analysis of Whorl Shape 3  Chapter 4 Morphologica 4.1 Introductio 4.2 Lowe  l Variatio n and Covariation 4 n4  8 8 5 5  r Jurassic Ammonite Shell Morphology 4  5  4.2.1 Backgroun d 4  5  4.2.2 Th e Sample of Observations 4  6  4.2.3 Basi c Shell Geometry 4  7  4.2.4 A n interpretation of Buckman's Law of Covariation 5  1  4.2.5 Morphologica l Variability and Taxon Longevity 5  4  4.2.6 Correlatio n between Basic Shell Geometry and Other Morphological Features 6  0  4.3 Covariatio  n6  9  4.3.1 Introductio n 6  9  4.3.2 Buckman' s Law 7  1  4.3.3 Volutio n 7  4  4.3.4 Whor l Shape 7  7  4.3.5 Rib s 8  0  4.3.6 Tuberculatio n 8  2  4.3.7 Vente r 8  4  4.3.8 Summar y & Speculations 8  6  4.4 Ontogeneti c Variation 8 4.4.1 Umbilical  Ratio (U) 8  9 9  4.4.2 Shel l Expansion Rate (W) 9  1  4.4.3 Rati o of Whorl Width to Whorl Height (WWWH) 9  2  4.4.4 Primar y Rib Density (PRHW) 9  4  4.4.5 Superfamil y 9  5  Chapter 5 Change  s through Time 9  6  5.1 Introductio  n9  6  5.2 Stratigraphi  c Division 9  7  5.3 Choic  e of Characters 9  7  5.4 Geometr  y through Time 9  8  5.5 Taxonomi  c Diversity 10  1  5.6 Morphologica  l Diversit y 10  4  5.6.1 Morphologica l Range Diversity Index (MRDI) 10  4  5.6.2 Shanno n Diversity Index (SDI) 10  8  5.7 Discrepancie  s between Morphological and  Taxonomic Diversities 11 5.8 Othe  r Interesting Observations 11  Chapter 6 A  n Aid to Identification 11  6.1 Introductio 6.2 Use 6.3 Example Chapter 7 Summar  n 11  3 4 9 9  r Interface 12  1  s 12  8  y and Conclusions 15  1  References 15  4  Appendix 1 Variou  s Morphological Paramete r Value Combination s  and their Abundance in the Database Ammon 16  4  Appendix 2 Sourc  e Code for the Graphics Interface of Ammon 20  0  Appendix 3 Sourc  e Code for the Program—imageEdit 25  9  Appendix 4 Sourc  e Code for the Interactive Image Measurement Module.. 276  Appendix 5 Sourc e Code for the Automated Image Measurement Module. 321 (without the Canny edge detector and the Pavlidis thinning algorithm) Appendix 6 Sourc e Code for Fourier Analysis 40 7 Appendix 7 Sourc  e Code for the Animation of Whorl Shape Changes 42  2  vii Acknowledgments The completio n o f thi s thesi s i s mad e possible , i n larg e part , t o th e guidance , encouragement an d financial suppor t of my thesis advisor Dr. P. L. Smit h whose hel p ofte n extended beyond research. His comments and suggestion s o n the earlier drafts hav e greatl y improved th e manuscript . I n addition , hi s researc h librar y i s th e majo r sourc e o f dat a making up the database Ammon. Special thank s ar e du e t o Dr . R . J . Woodha m (Compute r Scienc e Department , UBC) who kindly provided the program implementation o f the Canny edge detector i n th e initial stag e o f this project an d mad e valuable suggestion s a s a member o f my supervisor y committee. I wish to thank Dr. T . H. Brown fo r hi s critical comment s o n Chapte r 4 whic h le d to a majo r improvement . I woul d als o lik e t o than k Dr . W . C . Barne s fo r hi s encouragement an d detailed review of the manuscript. This study was supported b y a University Graduat e Fellowship fro m th e Universit y of British Columbi a an d grant s t o P . L . Smit h fro m th e Natural Scienc e an d Engineerin g Research Council, which are gratefully acknowledged . I owe a great deal to my fellow graduate students at the Paleontology Lab o f UBC. Giselle Jakobs helped updating the information fo r Toarcia n ammonites in the database an d provided som e reference material . Geng a Nadaraju an d Jozse f Palfy wer e alway s ther e t o help wit h m y word-processin g relate d questions . Jozse f Palf y als o provide d advic e wit h Sinemurian ammonite s an d th e thesi s layout . I benefite d fro m discussion s wit h Gar y Johannson. A grea t dea l o f thank s mus t g o t o Toma s Clem o an d Joan n Bessle r fro m Hydrology Lab of UBC for their help. Dr. H. W. Tipper of the Geological Surve y of Canada at Vancouver kindl y sen t m e a well preserved specime n o f Fanninoceras fannini fo r study . He als o helpe d updatin g th e information fo r Hettangian ammonite s from North America . I am indebted to Mr. Stewar t Kingdon (Computer Scienc e Department, UBC ) wh o provided th e progra m implementatio n o f th e Pavlidi s thinnin g algorith m an d helpe d digitizing a fe w ammonit e images . I than k Dr . Andre-Pierr e Benguerre l (UBC ) fo r hi s encouragement, suppor t an d valuable advice. My sinceres t thank s go to P . L. Smit h an d K. Gordanier-Smit h fo r makin g m e fee l at home as I adapted to a different environment . Finally I woul d lik e t o than k m y wif e Cind y an d m y parent s fo r thei r dedicate d support that I can always count on.  Introduction 1  Chapter 1 Introductio 1.1 Introductor  n  y Statemen t  Jurassic ammonite s ar e commonl y regarde d a s excellen t inde x fossils , evolvin g rapidly an d bein g geographicall y widespread . Th e Earl y Jurassi c i s a 3 0 M a interva l an d rocks of this age are widespread i n Western North America both in allochthonous sequence s and o n th e craton . "Th e hig h resolvin g powe r o f ammonit e biochronolog y offer s th e bes t method of correlating betwee n the suspect terranes an d comparing thei r disparat e geologica l histories" (Smit h 1988) . Obtainin g biochronologi c informatio n require s th e recognitio n o f associations o f ammonit e shel l morphologie s (species) , association s whic h ca n b e demonstrated t o maintai n thei r superpositiona l relationship s throughou t thei r entir e geographic distribution . Eac h specie s show s variation withi n th e population an d als o durin g ontogeny, variatio n whic h mus t b e documente d an d understoo d befor e a specie s ca n b e identified wit h confidence . Th e descriptio n o f morpholog y an d th e documentatio n o f variation can be approached in three ways: (a) The use of geometric models to describe morphology quantitativel y (theoretically capable of producing a universal set of all possible morphologies). (b) The use of images of specimens to obtain quantitative data and qualitative descriptors (determining which parts of the universal set are actually occupied) ; a computerized image database is best suited for this task . (c) The use of a database management system to manipulate the data from (b ) to recognize species. In addition, the data from (b ) can be used to test hypotheses o n evolution suc h as the claim fo r greate r earl y disparit y (Whittingto n 1985 ; Goul d 1989) , t o explor e possibl e correlations betwee n taxo n longevit y an d morphologica l variability , t o detec t subtl e link s between morphological features , to more rigorously document extinction events and so on.  Introduction 2 Continuing advance s i n compute r hardwar e an d softwar e technologie s hav e mad e i t feasible t o store and manipulate fossi l image s digitally. Access speed s an d storag e capacitie s are progressivel y increasin g whil e cost s decrease . A n imag e scanne r wit h 25 6 gra y shade s that cos t $500 0 when thi s project starte d i n 1990 , now cost s les s tha n $100 0 (1994) . Imag e databases fo r othe r fossi l group s ar e likel y t o emerg e which , whe n networke d b y th e "Information Superhighway" , will make a huge impact on the way that paleontologists work .  1.2 Previou  s Wor k  The first attemp t to mathematically describ e coiled shell s was made in the nineteent h century b y Mosele y (1838 ) wh o establishe d a geometri c model fo r mollus k shell s based o n the logarithmic spiral. Raup (1966, 1967 ) reexamined and modified Moseley' s model and was able to express the basic forms o f most mollusc shells using four geometri c parameters. Raup (1967) showed that ammonoids occupy only a portion of the theoretical range of possibilities for shel l geometry , an d tha t som e geometri c combination s hav e bee n utilize d mor e tha n others. Raup' s approac h wa s subsequentl y use d b y War d (1980 ) t o compar e th e shel l geometry o f Jurassi c an d Cretaceou s ammonoid s t o Mesozoi c an d Cenozoi c nautiloids . Chamberlain (1981 ) wen t furthe r an d relate d ammonoi d an d nautiloi d shel l geometr y t o hydrodynamic efficiency b y showing that species with coiled shells cluster on adaptive peaks that optimize streamlining and stability. More recently, Saunders and Swa n (1984,1987) hav e used Raup' s parameter s t o analyz e th e morphologi c diversit y o f mid-Carboniferou s ammonoids. These studies demonstrated the usefulness o f Raup's approach i n evaluating an d graphically portraying the distribution of ammonoid shell geometry. During th e pas t twent y year s progres s ha s bee n mad e toward s storin g fossi l information o n compute r databases . Pric e (1984 ) describe d ho w a hierarchica l databas e management syste m wa s designe d fo r materia l i n the Sedgewic k Museum , Cambridge . Th e prototype Amnio n was initiate d t o systematicall y handl e dat a accruin g fro m stratigraphi c studies o f Jurassi c sedimentar y basin s i n Nevada , Orego n an d Britis h Columbi a (Smit h  Introduction  3  1986). GONIAT , a compute r databas e fo r Paleozoi c ammonoid s wa s develope d b y Kullmann, Korn, Kullmann and Petersen (1991). Images ar e o f grea t importanc e i n paleontology . Fo r example , th e Paleontologica l Cataloging Syste m Developmen t Committe e o f th e America n Associatio n o f Stratigraphi c Palynologists an d Micropaleontolog y Pres s have bee n workin g togethe r t o desig n a n imag e database (Huber 1990) . Similarly a major oi l company has been developing a textual database with an image library (Rich 1989) . Fossil images in these systems are for visual comparison s only, a big step forward woul d be to derive morphologcal parameters directly from image s in the database. Numerous attempt s hav e bee n mad e t o interpret image s sinc e th e adven t o f digita l computers. Mos t progres s ha s bee n mad e i n system s tha t perfor m a particula r tas k i n a controlled environment which provides stron g constraints o n the recognition process . On the other hand, less progress has been made in the areas where computers have been called upo n to extrac t ill-define d informatio n fro m image s (Hor n 1985) . Th e majo r element s i n a n ammonite imag e ar e lin e features , suc h a s rib s an d th e coilin g curve . Severa l attempt s t o extract lin e wor k fro m natura l image s hav e bee n published . Cleynenbreuge l e t a l (1988 ) described initia l experienc e wit h a syste m tha t extract s road network s fro m SPO T satellit e images for example , and a knowledge-based syste m was used fo r automati c segmentatio n o f coronary vessels from digita l angiograms (Stansfield 1986) .  1.3 Purpos  e and Scop e  This thesis focuses o n Lower Jurassic ammonites and the primary objectives are : 1. To incorporate images into the textual Ammon database and expand the database to give a comprehensive coverage of Lower Jurassic ammonites.  Introduction 2. To design a computer system for measuring morphological parameters fro m images in the Amnion database and to assess the feasibility o f a fully automate d approach. 3. To quantify th e description of whorl shape so that intraspecific variation s can be documented objectively an d comparisons can be made among different taxa . 4. To quantify an d document intra-taxon variation in morphology which serves to define taxa more objectively . 5. To map the distribution of Lower Jurassic ammonites in terms of basic shell geometry so that relative densities of occurrence in different geometri c regions can be evaluated and functional factor s governing the distribution can be explored. 6. To detect covariations among morphological features an d give interpretation s whenever possible. 7. To explore possible correlation between taxon longevity and morphological variability. 8. To quantitatively document taxonomic diversity changes and morphological diversity changes through geological time, and study the relation between the two. 9. To design a computer system to aid in the identification o f Lower Jurassi c ammonites which may also serve as an education tool.  The Ammon Image Database 5  Chapter 2 Th e Lowe r Jurassic Ammonite Imag e Database - Ammo n 2.1 Introductio  n  Ammonite specie s normall y sho w variatio n withi n th e populatio n whic h mus t b e determined befor e a specie s ca n b e identifie d wit h confidence . Th e retrieva l o f informatio n for an y specie s require s searchin g a large literatur e whic h limit s th e spee d o f identificatio n and makes direct comparison of specimens difficult . During the last two decades there is increasing need to evaluate global bioti c patterns in time. Plat e tectonic and paleobiogeographic research require paleontological input , and yet our established practices are hardly appropriate for integrating an d evaluating fossi l dat a on a global scale , particularl y fo r narro w tim e interval s (Spice r 1986) . Maintainin g u p t o dat e revisions o f taxa based o n specimen s an d literature fro m differen t geographica l area s i s als o time consuming. Computerized databases have the potential to solve these problems. Durin g the past twenty years progress has been made towards storing fossil catalogu e information o n computer databases. Pric e (1984) described how a hierarchical database management syste m was designed for material in the Sedgewick Museum, Cambridge. GONIAT, a computer database for Paleozoic ammonoids was introduced at the International Cephalopo d Symposium in 1990. GONIA T utilizes Dbase software supplemente d with additional programming which provides a simplified user interface (Kullmann , Korn, Kullmann and Petersen 1991) . Image s are of great importance in paleontology. For example, the Paleontological Catalogin g Syste m Development Committee of the American Association of  The Amnion Image Database  (•  Stratigraphic Palynologists and Micropaleotology Press have been working together to design a paleontological catalog database where, according to Huber (1990): "Palynologist s are evaluating systems that can capture images of fossils as digital data directly from a microscope, and then store, manipulate and retrieve them from a n image database stored on optical disk". Similarl y a major oi l company has been developing a textual database and an image library in a system that allows one or more images of a particular fossil type to be combined with textual information (Ric h 1989) . Klapper and Foster (1993) described a shape analysis system that identifies conodon t species with its digitized outline. The research that leads to this thesis is a continuation of Ammon, a Lower Jurassic ammonite database which was initiated to systematically handle data accruing from stratigraphic studies of Jurassic sedimentary basins in Nevada, Oregon, and British Columbia (Smith 1986) . The computerization o f paleontological dat a is not without difficulty. Conventionall y descriptions ar e prepare d i n a forma t whic h ha s evolve d ove r man y year s o f taxonomi c practice. Withi n this framework presentatio n ma y var y and , fo r eac h individua l description , authors ar e free withi n limit s t o choos e whateve r phraseolog y seem s mos t appropriate . Fo r information-retrieval purpose s al l elements o f description s shoul d b e strictl y comparabl e requiring tha t terminolog y b e use d consistently . Othe r area s o f difficult y includ e characte r selection, standardization of data and amount of data that needs to be entered into database.  2.2 Th  e Database Structur e  The Ammo n was originall y designe d b y Smit h (1986 ) o n a mainfram e compute r using TAXIR as the database management program. Subsequently it was transferred t o a  The Ammon Image Database Item\Descriptor  Descriptor 1  Descriptor 2  Descriptor 3  Iteml  State 1  State 3  State 2  Item 2  State 3  State 2  State 1  Item 3  State 2  State 4  State 5  Figure 2-1 A table in the relational model workstation (SparcStationl ) an d converte d t o wor k unde r Oracl e Relationa l Databas e Management System . In the relationa l model , dat a ar e represented i n tabular for m (Fig . 2-1) . Eac h ro w o f the tabl e i s referre d t o a s a n ite m an d eac h colum n i s calle d a descriptor . Th e row s o f th e table link together related values, and different table s may be linked implicitly i f they includ e values of a common item, e.g. specimen number. "The firs t ste p i n designin g a databas e i s t o establis h a lis t o f descriptor s tha t wil l describe the items in every possible way that might be useful no w and i n the future but with a minimum of information redundancy. I n the database Ammon described below, an item is an ammonoid an d th e descriptor s ar e categorie s o f informatio n describin g thos e ammonoids " (Smith 1986) . Ther e were 96 descriptors proposed by Smith (1986) and the author has added another 1 1 descriptors whic h includ e relativ e locatio n o f image file an d scal e o f illustration . These descriptor s ar e divide d int o si x categories , viz. , taxonomy , quantitativ e morphology , qualitative morphology , stratigraphy , localit y (includin g catalogu e information ) an d genera l comments (Fig. 2-2). The following note s describing the states of these descriptors are taken from Smith' s original paper (1986) with a few modifications .  8  The Ammon Image Database  Taxonomy  1 SUBORDE R 4 SUBFAMILY  2 SUPERFAMILY 5 GENUS  3 FAMIL Y 6 SUBGENU S  7 QUALIFIE R  8 SPECIES  9 SUBSPECIE S  10TAXAUTHYEAR  11 REFAUTHYEAR  12 SYNONYMY  13SYNSPECIES  Quantitative Morphology Qualitative Morphology  Stratigraphy  14DMAX 20 WH  15DPHRAG 21 WHMAX  16 D 22WHD  17 UD 23 WW  18U 24WWD  26 PRH W  27 RIBWIDTH  28 SRHW  29THW  30 BISPAC E  31 FURCPOSO  32 UNITUBPOS 0  33 CHW  34 SF  35 VOLUTION0  36 AH  37 APPROX  38 VOLUTION 44 USHOUL D  41 UWALL 47 VENTPROF  42 UWALLH T 48 KEEL  43 UWALLAN G 49 SULCI  50 PRIBD  39 WHORL SHAPE 4 0 EXPANSIO N 46 VENTER 45 FLANKS 52 PFORM 51 PTREND  53 PPROF  54 FURC  55 FURCPO S  56 SRIBD  57 STREND  58 SFORM  59 SPROF  60 TUBERC  61 UNITUBPO S  62 CONSTRD  63 CTREND  64 CFORM  65 APERTURE  66 SUTURE  67 ONTOGENY  68 STAGE 74 HORIZO N  69 SUBSTAGE 75 FORMATION  70 EURZONE 76 MEMBER  71 EURSUBZONE 72 ZONE 78 DATU M 77 LITHOLOG Y 85 LONG 91 OTHERNO  80 SITU  81 ASSOCSPEC  Locality an d Catalogue Information  82 AREA 88 SECTNAME  83 COUNTRY 89 SECTNO  84 PROVINCE 90 LOCNO  94 REPOSITOR Y  95 TYPE  96 COLLECTORYR  99 IMAGE  100 SCALE  Others  101 SPECFEATURE  Figure 2-2 Th  19W 25WWWH  73 SUBZONE 79 RELDATU M  86LAT 92 SUBLOCNO  87 Q 93 SUPERLOCN O  97 GENERALOC  98 SPECNO  102 REMARKS  e descriptors of the database Ammon (modified fro m Smit h 1986 )  Taxonomic descriptors. ~ Ammonoi d taxonom y ha s bee n th e subjec t o f a prolifi c literature culminatin g i n th e Treatis e o n Invertebrat e Paleontolog y (Arkell , Kumme l an d Wright, 1957 ) an d subsequen t attempt s t o updat e thi s informatio n (fo r th e Jurassi c se e Donovan and Forsey, 1973 , and Donovan, Callomon and Howarth, 1981) . Descriptors 1-  4 (SUBORDERS  , SUPERFAMILIES  , FAMILIE  S AN  D  SUBFAMILIES) ar e self explanatory. Sinc e this database concerns only the Ammonoidea i t is not necessary to go above the sub-ordinal level. Descriptors 5 , 6, 8 and 9 should be the names used by the author o f the publication i f the information i s derived from the literature. Descriptor 7 (QUALIFIER) : 1 . CF (confer) ; 2 . AFF (affinis) ; 3. ? (uncertai n generi c assignment); 4. EX GR (ex grupo); 5. SS (sensu stricto); 6. SL (sensu lato); 7. SP? (uncertain species assignment).  The Amnion Image Database  9  Descriptor 1 0 (TAXAUTHYEAR) i s the author of the taxon together with the year of publication (all in parentheses if the species has been transferred from the original genus). Descriptor 1 1 (REFAUTHYEAR ) i s th e referenc e (autho r an d year ) i n whic h th e figure of the specimen appears (if applicable). Descriptor 1 2 (SYNONYMY) an d descripto r 1 3 (SYNSPECIES) are , o f course , th e valid genus and species name as judged by the person designing the database. Quantitative morphology. - Quantitativ e approache s t o morpholog y wer e ignore d i n the Treatise (Arkeli, Kummel and Wright, 1957 ) and it has been left t o individual worker s to define thei r ow n variable s wit h eac h publicatio n s o tha t a lack o f consistenc y ha s resulted . The primary variable s use d i n Amnion ar e descriptor s 14-17 , 19-21 , 23 , 26-33, 35-36 . Th e variables derive d from the m coul d b e calculate d bu t th e advantag e o f improve d storag e efficiency woul d be offset b y slower retrieval. Descriptor 1 4 (DM AX) is the maximum diameter measurable for that specimen. If the specimen i s matur e thi s wil l b e indicate d b y informatio n recorde d i n REMARK S (e.g. , approximated sutures ) o r i t wil l b e reflecte d i n th e informatio n fo r th e APERTUR E (descriptor 65). Descriptor 1 5 (DPHRAG) is the shell diameter at the adoral end of the phragmocone. Descriptor 16-18 , 20, 22-29 and 33 are illustrated and explained in Fig. 2-3.  The Amnion Image Database  10  Descriptor 19 : W = (LR/L) 27t/r wher e LR an d L ar e th e sam e linea r featur e separate d by an angular distance about the coiling axis of r radians (a version o f the expansion rate o f Raup, 1966, 1967) . Thi s variabl e ca n b e use d t o extrapolate linea r measurement s (D , UD , etc. ) backwards o r forward s i n ontogeny , assumin g Figur e 2-3 Th e quantitative descriptor s used in Ammon (from Smit h 1986) . D that th e expansio n rat e remain s constan t durin g (Descriptor 16 ) = the diameter at which all measurements and qualitative observation s growth. are recorded. UD (Descriptor 17 ) = the Descriptor 2 1 (WHMAX ) i s th e umbilica l diameter. U (Descriptor 18 ) = UD/D. WH (Descriptor 20) = whorl height. WHD (Descriptor 22) = WH/D. WW specimen. Thi s descripto r wa s not include d i n (Descripto r 23) = whorl width. WWD (Descriptor 24) = WW/D. WWWH the origina l Ammo n but adde d b y th e autho r t o ,-. . _ ' „.„ 7mrTT _ . , , , (Descriptor 25) = WW/WH. The shaded deal with fragmentary specimens . half-whor l represent s the interval at diameter D over which counts of primary Descriptor 3 0 : BISPACE = Y/D , wher e r i b S j secondar y ribs, tubercles and ,, . A l , .x , . constriction s are made (Descriptors PRHW A, , Y i s th e distanc e betwee n tubercle s i n (26), SRHW (28), THW (29) and CHW bituberculate ammonoids. (33 ) respectively). Descriptor 3 1 : FURCPOSO = FD/WH, wher e FD i s the distanc e betwee n furcatio n maximum whor l heigh t measurabl e fo r th e  point an d umbilica l seam . FURCPOS O i s th e quantitativ e equivalen t o f FURCPO S an d i s added by the author.  11  The Ammon Image Database '  WH  1wh  1  Descriptor 3 2 : UNITUBPOS O = TD/WH , wher e  •>  ,i  TD is the distance between tubercles and umbilical sea m in  LP  o  unituberculate ammonoids. UNITUBPOSO is the quantitat-ive equivalen t o f UNITUBPO S an d i s adde d b y th e  -  author.  Figure 2-4 Descriptor s 35, 36  Descriptor 3 4 (SF ) i s th e sutura l formul a fo r th e  VOLU11ON0 = LP/wh.  specimen at that diameter. A specimen may be entered into  AH = LJP/WH.  the compute r severa l time s a t differen t shel l diameter s s o  that the ontogenetic development of a sutural pattern may be recorded. Descriptor 35 : VOLUTIONO = LP/w h wher e L P i s the whor l overla p an d w h i s th e inner whorl heigh t (Fig . 2-4) . This descripto r i s the quantitativ e equivalen t o f VOLUTIO N  WHORL SHAP E 1 ROUNDE D 1 ADVOLUT E  0  3 MIDVOLUT E  5 OCCLUDE D  7 HETEROMORP H  Figure 2-5 Th  Q  2 EVOLUT E  C^> 2 ELLIPSOI D  3 W ELLIPSOI D  4 INVOLUT E  o  5 LANCEOLAT E  7 RECTANGULAR  6 ELLIPTICA L 8 W RECTANGULA R  8 HELICOSPIRA L  e states for the descriptor  VOLUTION (38 ) (from Smit h 1986 )  11 W TRIANGULA R  Figure 2-6 Th  9 QUADRAT E  R  12 TRAPEZOI D  10 TRIANGULAR  ^=7 13 CORONAT E  e states for the descriptor  WHORL_SHAPE (39 ) (from Smit h 1986 )  The Amnion Image Database 1  1 CONCAVE  2  and is not included in the original Amnion. Descriptor 36: AH = LP/WH wher e  iilllllll  fr—1  2  FLAT  3  CONVEX  4  INFLATED  LP i s th e whor l overla p an d W H i s th e outer whor l heigh t (Fig . 2-4) . Thi s descriptor seem s importan t i n interpretin g the covariatio n betwee n W an d U (se e  5  ANGULAR  section 4.2.4).  Figure 2-7 State s used for describing profiles Descripto of the UWALL, the FLANKS, the primar VENTPROF, the PPROF, the SPROF. l i s t e (from Smit h 1986 ) eliminate  r 3 7 (APPROX) : Thos e  y variable s tha t ar e approximat e ar e d i n  descripto r 3 0 s o tha t the y ca n b e d fro m subsequen t analyse s whe n  necessary. Qualitative morphology. — Descriptor 3 8 (VOLUTION ) : I n th e descriptiv e term s illustrated i n Fig . 2-5 , the umbilical sea m o f the whorl progresse s fro m barel y touchin g th e preceding whorl (advolute ) to overlapping the upper (evolute) , middle (midvolute) an d lowe r (involute) thir d o f th e flan k o f th e precedin g whorl , whe n th e shel l i s occluded , th e oute r whorl completel y cover s th e inne r whorls . State s 6 to 8 describe th e situatio n whe n growt h deviates fro m a regular, logarithmicall y accretin g planispire . Som e ammonoids , particularl y in the Paleozoic, show an elliptical growt h pattern throughout ontogeny . More commonly th e mature whor l wil l egres s t o th e elliptica l patter n o r eve n los e contac t wit h th e precedin g regular whorl s altogethe r an d becom e heteromorphi c (stat e 7) . Som e ammonoid s hav e a  The Amnion Image Database 1  n  n n  ri  n  A  n  A  1 2  3  3  PLAIN  1 RURSIRADIAT E  4/  2  \  ^ T  ___/ 5 2 GRURSIRADIAT E  CARINATE  1/  \ 3 RECTIRADIAT E | 20  °  3  SULCATE  4  CARINATE-SULCATE  5  BICARINATE  6  BICARINATE-SULCATE  7  TRICARINATE  translational componen t t o thei r growt h an d  8  TRICARINATE-SULCATE  appear gastropod-lik e (stat e 8) . State s 7 an d 8  Figure 2-8 State  4 GPRORSIRADIAT E  s for the descriptor  5 PRORSIRADIAT E  Figure 2-9 State s for the descriptors PTREND and CTREN D (from Smit h 1986 )  neve  r occu r i n Lower  VENTER (from Smit h 1986) ~ v  ' Descripto  .  . ~  Jurassi c ammonites. n  OTTA™-  \  r 3 9 (WHORL_SHAPE) : se e  Fig. 2-6. Descriptor 4 0 (EXPANSION ) describe s ho w fas t th e shel l expand s i n th e followin g terms: slow, moderate and rapid. Descriptor 4 1 (UWALL ) describe s th e profil e o f th e umbilica l wal l usin g th e term s shown in Fig. 2-7. Descriptor 42 (UWALLHT) is the height of the umbilical wall (low; high). Descriptor 4 3 (UWALLANG ) describe s th e slop e o f a fla t umbilica l wal l i n th e following terms: undercut, vertical, steep and shallow. Descriptor 4 4 (USHOULD ) i s th e profil e o f th e umbilica l shoulde r (rounded ; angular).  14  The Amnion Image Database Descriptor 4 5 (FLANKS ) describe s  1 UWAL L (umbilica l wall )  the profil e o f th e whor l flanks i n th e  2 USHOULDE R  >  •5  II  terminology of Fig. 2-7.  N 1  Descriptor 4 6 (VENTER ) describe s  3 LOWFLAN K 4 MIDFLAN K 5 UPPERFLAN K 6 VLSHOULDE R ( v e n t r o - l a t e r a l shoulder) 7 VENTE R  the appearance o f the venter as shown in Fig. Figur 2-8. o  -4  e 2-10 State s for describing position  n the profile of a whorl. Used in PFORM, Descriptor 4 7 (VENTPROF ) i s th e FURCPOS  , UNITUBPOS an d CFORM  profile of the venter in cross-section as shown in Fig. 2-7. Descriptor 4 8 (KEEL ) refer s t o carinat e form s an d describe s th e prominenc e (high , low) and profile (flat-topped , rounded , angula r o r crenulate) of the keel a s well as noting th e presence of a floor. Descriptor 4 9 (SULCI ) describe s sulc i (descripto r 47 , state s 3 , 4 , 6 , 8 ) b y th e term s deep or shallow. Descriptor 50 (PRIBD) describes the ribbing density by the terms distant or dense. Descriptor 5 1 (PTREND ) describe s th e averag e tren d o f th e primar y rib s acros s th e flank of the whorl (Fig . 2-9). Descriptor 5 2 (PFORM ) : The for m o f the primar y ribbin g ha s bee n describe d b y a number o f term s (e.g. , Schlegelmilch , 1976 , fig. 7 , Arkell, Kumme l an d Wright , 1957 , fig. 132, Smith , 1986 , fig. 11) . Th e term s use d i n th e Treatis e (Arkell , Kumme l an d Wright , 1957, fig. 132) are adopted here for simplicit y  The Ammon Image Database  15  1 RURSIRADIAT E VENTRAL VIE W  T X X  'Si  ^P^  6 VIRGATOTOM E  2 GRURSIRADIAT E  3 RECTIRADIAT E  >  4 GPRORSIRADIAT E  APERTURE  5 PRORSIRADIAT E  Figure 2-12 State s for the descriptor STREND showing the trend of secondary ribs across the venter of a coronate Figure 2-11 State s for the descriptor FURC ammonoi d (from Smit h 1986) . Descriptor 5 3 (PPROF) indicate s the cross-sectional profile o f the primary rib s in the terms shown in Fig. 2-7. Descriptor 54 (FURC) describes the pattern of rib furcation a s shown in Fig. 2-11. Descriptor 55 (FURCPOS) indicates the position of the furcation (descripto r 54 , states 2-6; th e first furcatio n i s indicate d fo r state s 5 and 6 ) usin g th e terminolog y o f Fig . 2-10 . Fasciculation can be described using a combination of descriptors 54 and 55. Descriptor 56-5 9 describ e character s o f th e secondar y ribbin g i n th e terminolog y  1 UN I  28 1  IT 3 TR I  applied t o th e primar y rib s (analogou s descriptors 50-53  ) wit  h th  e followin  g  modifications: descripto r 5 7 (STREND ) i s shown in Fig. 2-12 and descriptor 5 8 (SFORM)  4 MULT I  5 CLAVAT E  6 BULLAT E  are prefixe d wit h a n I whe n th e rib s ar e intercalated.  Figure 2-13 State s for the descriptor TUBERC (from Smit h 1986 )  The Ammon Image Database 1 Descriptor 6 0 (TUBERC ) an d 6 1 (UNITUBPOS) describ e th e tuberculatio n  APERTURE  (Fig. 2-13) and the position o f the tubercles i n  6  a 1 SIMPL E  unituberculate form s i n th e terminolog y o f Fig. 2-10.  a  2 CONSTRICTE D  Descriptors 62-6 4 describe the density , trend an d for m o f constriction s i n th e sam e terminology applie  dt  o primar  y rib  s  4 SINUOU S  (descriptors 50-52). Descriptor 6 5 (APERTURE ) describe s the apertur e usin g th e state s illustrate d i n Fig . _ 1 . Figur  6 ROSTRU M i  3 FLARE D  a  5 LAPPET S  7 HOR N  e 2-14 State s for the descriptor APERTURE (from Smit h 1986 )  Descriptor 6 6 (SUTURE ) i s a field fo r comments on features o f the suture. Descriptor 6 7 (ONTOGENY ) indicate s whethe r ther e i s a distinc t chang e i n morphology durin g ontogen y (ye s o r no). This descripto r i s used t o tell th e user t o sca n the database a t a variet y o f shel l diameter s t o loo k fo r multipl e entrie s o f dat a fo r th e sam e specimen a t different diamete r (eac h entr y wil l hav e th e sam e specime n numbe r (descripto r 98) ) and to check the general remarks. Stratigraphy. -- The descriptors for stratigraphy are largely self explanatory. Descriptors 7 0 (EURZONE ) an d 7 1 (EURSUBZONE ) ar e standar d zone s an d subzones of the Northwest European Province (Dean, Donovan and Howarth, 1961) .  The Amnion Image Database 1  7  Descriptors 72-74 record a zonation other than that of northwest Europe. Descriptor 78-79 : Fo r ammonit e localitie s fro m measure d sections , th e poin t o f reference suc h a s th e contac t betwee n tw o formation s i s liste d i n descripto r 7 8 wit h measurements i n meters abov e o r below (negative ) tha t datu m show n i n descriptor 79 . This information permit s th e rapi d compilatio n o f th e stratigraphi c rang e o f a specie s i n an y section. Descriptor 8 1 (ASSOCSPEC ) : Th e numbe r o f specimen s o f thi s specie s a t thi s locality that are not entered separately into the database. Locality and catalogue information. — Descripto r 8 2 (area ) divide s th e worl d int o a few broad geographic regions such as the Western Pacific, Wester n Tethyan, North America, South America, Northwest Europe . Descripto r 8 4 (PROVINCE) : Province , state , o r county . Descriptors 85-8 7 giv e th e geographi c locatio n o f th e specime n i n term s o f longitud e an d latitude wit h descripto r 8 7 givin g th e positio n relativ e t o th e equato r ( N o r S ) an d th e Greenwich meridian (E or W). Descriptors 88-91 are the section name, section number, locality number (may include letters) and an y other number, e.g. , a field numbe r that is associated wit h the specime n apar t from it s official catalogu e number (descriptor 98). Descriptor 9 2 (SUBLOCNO ) an d 9 3 (SUPERLOCNO ) recor d th e subjacen t an d superjacent localitie s i n a measure d sectio n s o tha t a worke r ca n retriev e informatio n i n stratigraphic order . Descriptor 95 (TYPE) has the following states : holotype, paratype, syntype, lectotype, paralectotype, neoholotype, newparatype, topotype, hypotype.  The Ammon Image Database 1  8  Descriptor 9 6 (COLLECTORYR) list s the collector and year of collection to facilitat e retrieval of information fro m fiel d notebooks. Descriptor 9 7 (GENERALOC ) give s non-standardize d localit y information , e.g. , Graham Island, Silvies River, etc. Descriptor 98 (SPECNO) is the unique label that characterizes this specimen. Descriptors 99 (IMAGE) and 10 0 (SCALE) give the relative path of image files i n the file syste m and the scale of the illustration. Th e absolute path of the image is determine d b y combining the relative path with a base directory checked at run time which enables the user to move the image file to the desired location without modifying th e user interface describe d in Chapter 6. Descriptor 10 1 i s adde d b y th e autho r fo r th e followin g reason : Som e taxonomi c groups have uniqu e featur e tha t i s important fo r th e identificatio n o f th e grou p ye t doe s no t justify a separat e descripto r i n th e database , fo r example , Hildoceras an d Hildaites hav e strong media n latera l groove ; Amaltheus, Aegoceras, an d Pleuroceras hav e serrate d keel ; they ar e lumpe d int o SPECFEATUR E whic h ca n b e scanne d fo r a specifi c featur e whe n needed. Descriptor 10 2 (REMARKS) i s a free forma t tex t field, remark s that does not fit into any of the descriptors can be put here. 2.3 SQ  L — The Quer y Languag e  The Oracl e relationa l databas e managemen t syste m allow s th e operato r t o us e th e industry standar d languag e SQ L to store , retrieve an d manipulat e data . SQ L i s a n English -  The Ammon Image Database 1  9  like languag e consistin g o f severa l "layers " o f increasin g complexit y an d capability . En d users with little or no experience with databases can learn SQL' s basic features ver y quickly , yet SQ L provides informatio n professional s wit h th e powerful an d complet e se t o f facilitie s required (Anonymous 1990a) . 2.3.1 Dat a entry The use r add s ne w specimen s t o Ammo n b y issuin g th e INSER T command , fo r example, INSERT INTO Ammon (genus, species, zone, specno, d) VALUES ("Badouxia", "canadensis" , "Bucklandi", "C-201453", 4.2); inserts a new specimen of Badouxia canadensis with a specimen number o f C-201453 fro m Bucklandi zone. I f more than one specimen need to be entered, a more efficient wa y is to use one's favorit e wor d processin g progra m o r tex t edito r an d sav e th e dat a int o a n ASCI I file , then use SQL*Loade r t o loa d dat a in external file s int o Ammo n (se e Anonymous 1990 b fo r detail). In fact, most of the data in Ammon are entered using SQL*Loader . 2.3.2 Updatin g the database The UPDAT E comman d change s value s store d i n Ammon . Descriptor s suc h a s WWWH, U, WWD in Ammon are represented as ratios but some ammonite workers prefer t o present thes e parameter s a s percentages . Thi s ca n b e achieve d b y issuin g a n UPDAT E command: UPDATE Ammo SET www  n h = wwwh*100, u = u*100, wwd = wwd*100  The Ammon Image Database 2  0  which convert s WWWH , U , WW D o f all specimen s i n Ammo n int o percentag e values . A WHERE claus e ca n b e use d t o specif y specimen s tha t nee d t o b e updated . Th e imag e measurement modul e describe d i n Chapte r 3 can als o b e used t o update morphologica l dat a in Ammon. The DELETE command removes specimens from Ammon . 2.3.3 Queryin g the database Retrieving dat a fro m th e databas e i s th e mos t commo n SQ L operation . A databas e retrieval is called a query and to issue a query the operator uses the SELECT command. Th e basic SELECT command has three parts: SELECT som FROM a  e descriptors table (such as Ammon) or some tables  WHERE searc  h condition  A questio n lik e "wha t specie s ar e involute , hav e a carinat e vente r o r mor e tha n 3 0 primar y ribs per half whorl" is addressed by SELECT synonymy , synspecie s FROM Ammo n WHERE volution = 'involute  ' AND (venter='carinate' OR prhw>30);  The user can also select items that do not meet search conditions. For example, the followin g query retrieves all species that are not involute: SELECT synonymy , synspecie s FROM Ammo n WHERE volutio  n ! = 'involute';  != means not equal. Th e user may combine AND, OR and ! = in the same query to connect as many search conditions as are necessary to retrieve the data.  The Ammon Image Database 2  1  The IN operator let s the user select items that contain a value that matches one of the values in a list. For example, the following quer y list s all species with a carinate venter, or a carinate-sulcate venter or sulcate venter: SELECT synonymy FROM Ammo WHERE vente  , synspecie s n  r IN ('carinateVcarinate-sulcateVsulcate') ;  Because som e specie s ma y hav e man y specimen s i n th e databas e an d eac h specime n i s a n independent item in the database, there would be lots of duplicate specie s names in the query result which can be eliminated by specifying DISTINC T in the SELECT clause: SELECT DISTINC  T synonymy, synspecie s  The user can also select items that match a specified pattern o f characters or numbers. For examples, the user may want to find all species that have "der" in their names: SELECT DISTINC FROM Ammo WHERE synspecie  T synonymy, synspecie s n s LIK E '%der%' ;  the SQ L operato r LIK E mean s tha t specie s nam e contain s th e strin g "der " an d th e percen t sign (%) signifie s an y string of zero or more characters. This feature allow s multiple state s in the sam e entry. Fo r example , for a specimen that has both bi-furcate an d tri-furcat e ribs , the value of the descriptor FURC can be input as "bi,tri" which will meet the search condition fo r specimens with bi-furcate rib s as well as specimens with tri-furcate ribs . SQL als o support s th e following arithmeti c operators , strin g manipulatio n an d grou p functions:  The Amnion Image Database  22  Arithmetic Operators  String  Function  Group  Function  +  Add  1  Concatenation  AVG  Average  ~  Subtract  DECODE  Translate  SUM  Sum  *  Multiply  LENGTH  String Length  MAX  Maximum  /  Divide  SUBSTR  Substring  MIN  Minimum  POWER  Exponentiation  INSTR  Instring  STDDEV  ROUND  Rounding  UPPER  Upper Case  VARIANCE Variance  TRUNC  Truncation  LOWER  Lower Case  COUNT  ABS  Absolute Value  SOUNDEX  Sound Matching  Standard Deviatio n  Number of Items  This i s onl y a partia l list , mos t relevan t t o Amnion . Th e SQ L Languag e Referenc e Manual (Anonymous 1990c ) has a complete set of the operators and functions . Group function s whic h le t th e use r selec t summar y informatio n fro m group s o f item s demonstrate th e powe r o f SQL . Suppose , fo r instance , tha t th e use r want s t o kno w th e average shell expansion rate (W) and degree of intraspecific variatio n o f W for ever y specie s that has at least 6 specimens in the Ammon database, the user can issue the following query : SELECT synonymy,synspecies,AVG(w),STDDEV(w FROM Ammo  n  GROUP by synonymy,synspecie HAVING COUNT(*  )  s  ) >= 6;  In the example above, every species is a group, average and standard deviation values of W are calculated for each species. Just as specify searc h conditions for individual item s using  The Ammon Image Database  23  the WHERE clause, the SQL clause HAVING is used to specify search conditions for groups of items. One of the reasons that SQL is so powerful is that complex queries can be built out of several simple queries. A WHERE clause of one query may contain another query called a subquery. Suppose that the user wants to retrieve all specimens (specno) collected from the same zone as specimen X with a specimen number of GSC20122 : SELECT  specno  FROM  Ammon  WHERE  zone = (SELECT  zone  FROM  Ammon  WHERE  specno = 'GSC20122');  Subqueries may be just as complex as main queries — they may contain subqueries of their own. 2.3.4  Changing the structure of the database  The SQL command ALTER can be used to add new descriptors to Ammon or make columns of existing descriptors wider to accommodate long text strings. ALTER TABLE Ammon ADD (specfeature CHAR (100)); In this command a new descriptor specfeature is added to Ammon with data type (CHAR) and maximum number of characters in the descriptor (100). Oracle will not waste storage by reserving space for the maximum number of characters allowed for each descriptor. For example, even though the maximum length of a value in descriptor specfeature is 100, most specimens do not have any entry for this descriptor therefore occupy no storage space at all.  The Ammon Image Database  24  SQL is the industry standard relational database language which assures compatibility across different database systems including IBM's DB2 and SQL/DS. In addition, Oracle runs on an impressive range of computers, from PCs to minis to mainframes. All versions of Oracle are identical which enables the application be moved across hardware and software boundaries with virtually no modifications. More importantly, SQL commands can be embedded in standard programming languages such as C, FORTRAN or Pascal. For example, a graphics user interface has been implemented for Ammon using C, embedded SQL, Sunview and a graphics library called Pixrect. This graphics user interface gives easy access to the database as well as image display and manipulation capabilities (see Chapters 3 and 6 for details). 2.4  Data Sources  The following references were used in compiling the Ammon image database: Arkell, Kummel and Wright, 1957 Arthur, 1985, 1987 Blasco, 1978 Blasco, Levy and Nullo, 1978 Crickmay, 1925, 1928 Dagis, 1968, 1974, 1976 Dean, Donovan and Howarth, 1961 Erben, 1956 Frebold, 1951,1958,1959,1960, 1964,1966,1967, 1970,1975 Frebold, Mountjoy et al., 1967 Gabb, 1869 Gabilly, 1976a, 1976b Geczy, 1976 Geyer, 1974, 1979 Guex, 1980,1981,1989  The Ammon Image Database  Hall, 1987 Hall and Howarth, 1983 Hall and Westerman, 1980 Hillebrandt, 1973,1981,1982, 1987, 1989, 1990 Hirano, 1971, 1973 Imlay, 1968,1981 Jakobs, 1992 Kalacheva, 1980 Mclearn, 1932 Meister, 1986 Novedades, 1988 Obrien, 1985 Palfy, 1991 Poulton, 1987,1991 Poulton and Tipper, 1991 Quinzio, 1987 Repin 1974,1968 Riccardi and Westermann, 1991a, 1991b Sanborn, 1960 Schlatter, 1991 Schlegelmilch, 1976 Smith, 1976, 1981 Smith and Tipper, 1986, 1988 Stankevich, 1964 Taylor, 1988 Thompson and Smith, 1988, 1992 Tilmann, 1917 Tipper and Richards, 1976 Tipper, Smith et al., 1991 Tozer, 1982 Wang and Smith, 1986 Westermann, 1972 Westermann and Riccardi, 1972, 1979 White, 1889 Whiteaves, 1884  25  The Ammon Image Database  26  Wiedenmayer, 1977, 1980 Willard, 1963 The prototype Ammon had information on about 1400 specimens; the present greatly expanded version has 7790 specimens from over 25 countries. The number of specimens sampled from each country is not uniform; the vast majority are from the following countries in descreasing order of abundance: Canada, Russia, United States, Switzerland, Argentina, France, Chile, Germany, Britain, Hungary, Austria, Mexico and Japan.  Image Analytic Techniques  Chapter 3  4.1  27  Image Analytic Techniques  Introduction  A number of interesting hypotheses in paleobiology can only be addressed using quantitative morphological data. Claim for greater early disparity, for example, cannot be confidently established until we develop quantitative techniques for the characterization of morphospace and its differential filling through time (Gould 1991). Subtle links between morphological features can hardly be recognized without the power of the computer to isolate and quantify all aspects of variation and covariation (Smith 1986). Some ammonite morphological parameters such as shell expansion rate and volution show continuous spectra, quantification of which is needed to differentiate intraspecific variations from interspecific variations. Although quantification is highly desired, deriving data from actual specimens is time consuming. Even for qualitative morphological characters, typing numerous character states into the computer is a slow and tedious process. The following computer image analytic techniques are used to alleviate the problem. 4.2  Digitization  Illustrations of selected ammonites from published literature are scanned into a Sun SparcStation using a MicroTek image scanner with 256 gray shades. The highest resolution available from the scanner is 400 dpi (dots per inch), but after some experiments, it is found that 300 dpi resolution gives the best results for illustrations on good quality paper and 200 dpi resolution is enough for illustrations on old and poor quality paper. To make images displayed on screen (with 100 dpi resolution) the same size as their original forms on paper, a program was written to shrink scanned image to one half original size (for illustrations scanned with 200 dpi resolution), or one third of original size (for illustrations scanned with 300 dpi resolution) by averaging adjacent pixels. This greatly reduces storage requirements since a half sized image only occupies one fourth of the original disk space.  Image Analytic Techniques  28  Fossil plates in journal articles normally have multiple specimens figured in each plate. To speed up the digitization process, a whole plate is scanned into the computer and the program "imageEdit" (Appendix 3) is used to pick up individual specimens, clear irrelevant components and save the selected part of the image as a separate file. An image is saved as a Sun raster file which is named after the author, year and abbreviation of the publication followed by plate and figure number. For example, plate 1, figure 1 of Hall 1987 (Canadian Journal of Earth Science) is named as: hall87cjesl-l.ras (lateral view), hall87cjesl-l.l.ras (ventral view), the corresponding descriptor IMAGE in the Ammon is coded as hall87cjesl-l|l.l. "|" is a separator which indicates the start of another image with the same base name as the preceding one. 3.3  Interactive Image Measurement Module  A front-end user interface is built on top of the Ammon database to facilitate measurement of morphological characters from images of specimens. The interface is implemented in C, embedded SQL, Sunview and a graphics library called Pixrect (see Appendix 4). The basic idea of this module is to derive morphological characters by combining the human ability to visually locate features with the computer ability to memorize and compute. When a specimen is entered into the database for the first time, morphological data are often not available and have to be measured from images of the specimen. Suppose a specimen with a SPECNO of 43252a is entered into the Ammon without morphological data. Later it is called to screen (Fig. 3-1, see Chapter 6 for detail of query by user interface) to calculate the shell expansion rate (W) and the umbilical ratio (U), a procedure requiring four control points: the coiling axis (O), two points (P3, P4) on the outer coiling curve and one point on the inner coiling curve (P2), another point (Pi) is given to enable simulation of the inner whorl spiral and to help in locating the coiling axis more precisely since fitting the inner curve relies even more heavily on correct location of the coiling axis. P] and P2 are separated by one whorl. By definition (Fig. 3-1)  Arnmon Image Database  Figure 3-1  Interactive image measurement program  Display Image Window  '  Image Analytic Techniques  30  W = (OP 3 /OP 4 ) 27l/r where OP3 and OP4 are separated by an angular distance of r radians which must be less than 7i to make coiling direction unequivocal to the program. U = OP 2 /OP 3 For rare ammonites that have an undercut umbilical wall, the umbilical shoulder rather than the umbilical seam is taken as the edge of the umbilicus (Smith 1986). An equivalent measurement of W for inner whorl is WI - OP 2 /OP! where OP2 and OPj are separated by one whorl. WI can be used to simulate the inner whorl spiral. The diameter of the shell and the whorl height at point P3 are D = OP3 + OP3/JW,  WH = P2P3  The absolute values for D and WH in centimeters is computed by combining the image scale recorded in the Ammon and monitor resolution coded in the program. The whorl overlap ratios (Fig. 2-4) with respect to the inner whorl and the outer whorl are (Fig. 3-1): VOLUTION0 = P2X/P1P2, AH = P2X/P2P3 To calculate the above parameters, all the user needs to do is to mark the five control points with the middle mouse button then press one of the "W(out)-', the "W(in)=" or the "U=" command buttons in the top window, the program will superimpose the simulated inner and outer coiling curves on the image and show the parameter values in the text fields following the command buttons. If a specimen has parts broken or damaged and the control points cannot be located with confidence, the user can proceed with "try and see". If the fitting is not satisfactory the operation can be undone by pressing the "Reset image" button in the left window. After the locations of the control points have been adjusted the user can try fitting again. Once the location of the coiling axis is settled, the primary rib density (PRHW) can be counted by clicking on a number of consecutive ribs with the middle mouse button. Suppose that N ribs are marked then PRHW = N*7t/r  Image Analytic Techniques  31  where r is the angular distance between the first and last ribs which must be less than n to avoid ambiguity about coiling direction yet large enough to justify extrapolation of the number of ribs for half whorl (PRHW). This can be a handy tool for exploring primary rib density change during ontogeny; the user simply clicks on a few ribs and the program does the counting and extrapolation. Fig. 3-1 shows that the PRHW for this specimen gradually increases from 10 in the innermost whorl to 12 in the middle whorl to 15 in the last whorl. The secondary rib density (SRHW) if applicable can be determined in a similar way. Another group of parameters which are related to whorl width can be measured from a cross-section (Fig. 3-1, left): WW = AB = 2.5cm, WWWH = AB/DD1 = 0.88, WWD = AB/CD = 0.27 To measure WW the user clicks on points A and B then press the "Distance" button in the left window; to measure WWWH and WWD the user clicks on the four control points A through D and then press the "Ratio" button. For most specimens, cross-sections are not available so the above parameters have to be derived from ventral view images.  Since the ventral view image is subject to  photographic distortion at both ends, the two control points for whorl width (A' and B' in Fig. 3-1, right) are located in the center of the view and line A'B' is perpendicular to the plane of bilateral symmetry. To determine the shell diameter and whorl height of the specimen at this locality: first, find a point on the lateral view where the shell diameter is equal to CD', suppose that the point is P3; second, find a point Y on the line OP3 so that P3Y is equal to the distance between point D' and line A'B'; finally draw a line  from Y which is  perpendicular to OP3 and the line intercepts the ventral edge at two points, the point which is closer to P3 along the venter is the projection of A' and B' where the shell diameter and whorl height can be measured appropriate for the whorl width A'B'. The above process is done by the Interactive Image Measurement program, the user only needs to click on the four control points (A1, B', C, D') then press the "WWD=" button in the top window. The text fields show the same results as given by the cross section : WWD = 0.27 and WWWH = 0.88. To  l» "  Coiling curve simulation and shell reconstruction  Rema  Display Image Window 9S Returned: 3 lc  Figure 3-2  Taxonomv = >  Retrieve by  Amnion Image Database  Image Analytic Techniques  33  evaluate the effect of possible photographic distortion on the WWD and the WWWH values, the program has been used to process 46 specimens with both cross-sections and ventral views. The average difference between the two sources is 4.3% of the measurements from cross-sections and the differences are usually well within 10% of the measurements therefore the alternative method to derive the WWD and the WWWH from ventral views are considered reliable. The icon panel in Fig. 3-1 is designed to facilitate the input of qualitative morphological data into Amnion. It is evident from the images of the specimen that it has strong, straight and gently prorsiradiate ribs; a steep umbilical wall; a quadrate to rounded whorl section (the Ammon database allows multiple states for any character of a specimen) and a plain venter. The user clicks on the corresponding icons which the program highlights. Finally press the "Save" button in the left window and all qualitative, as well as quantitative, morphological data are put into the database without the user typing a single word or having to memorize any character states. The interactive measurement module can also be used to detect subtle changes of parameters during growth, or to reconstruct a shell from a fragment. Fig. 3-2 (left) shows that the shell expansion rate from A to B is below the average of the entire whorl since the coiling curve of the actual shell lags behind the hypothetical curve. From B to C, the shell expands rapidly to close the gap and surpass the hypothetical curve followed by a slowing down from C to D to complete the cycle. Fig. 3-2 (right) shows reconstruction of a shell from a fragment with five control points : coiling axis (O), Pj ,P2 , P3 and P4. The vast majority of morphological data of the Ammon are gathered using this interactive image measurement module. 3.4  Automatic Image Measurement  To explore the possibility of a fully automatic approach, a program (Appendix 5) was written to measure shell expansion rate and rib density from lateral view images of specimens without human intervention. Other morphological features such as tuberculation and rib  Image Analytic Techniques  34  furcation are ignored to make the task tractable. The morphology of ammonites has a high degree of regularity, e.g. the coiling curve usually follows a logarithmic spiral; ribs and other ornamentation occur periodically following the coiling curve. This regularity is the basis of image interpretation. The program involves six steps: 3.4.1  Preprocessing Images are cleared of irrelevant components such as text labels and remnants of other  images using the program imageEdit. To focus the subsequent analyses on the ammonite in the image, the average (X) and standard deviation (S) of the background brightness intensity are estimated from a three-pixel wide margin of the image (assuming each image has a background margin around it) and the program reassigns brightness intensity value to each pixel in the 256 gray shades image: CO Z = | 256 ^•Z  Z < X+S and X < 128 (black background) Z > X-S and X > 128 (white background) Otherwise  where Z is the brightness intensity of the pixel. 3.4.2  Edge detection The major elements in an ammonite image are coiling curve and ribs, both are edges  where brightness shows significant changes. Edge detection serves to simplify the analysis of images by drastically reducing the amount of data to be processed, while at the same time preserving useful structural information about object boundaries. The Canny (from John Canny) operator was chosen for this purpose. Canny based his design on the following criteria (Canny 1986): 1. Good detection: there should be a low probability of failing to mark real edge points and a low probability of falsely marking non-edge points; 2. Good localization: the points marked as edge points by the operator should be as close as possible to the center of the true edge; 3. Only one response to a single edge;  Image Analytic Techniques  Figure 3-3 An output from Canny operator Locate coiling axis using possible rib and coiling curve segments.  35  Une  segment  has  three  parts  .  orientation, length in terms of number of edge points in the  segment and coordinates of these points. Before line tracing, a thinning algorithm (Pavlidis 1982) is used to skeletonize edge segments potentially wider than one pixel into one-pixel wide segments. 3.4.4  Locating coiling axis The most important feature of ammonite morphology is that ribs distribute around  coiling axis radially and coiling curves follow a logarithmic spiral starting from coiling axis. Assume P is the angle made by the radius vector to any tangent to the spiral which describes how rapidly coiling curves move away from coiling axis. Lower Jurassic ammonites have P values between 75° and 90° even when there are changes during ontogeny. A statistical parameter (SC) based on this observation is used to locate the coiling axis : m  n  SC = ]T CoilingLen[i\ + ]T RibLen[i] i=l  i=l  where CoilingLenfi] is the length of the ith line segment which has an P value between 75° and 90° with respect to the hypothetical coiling axis O (Fig. 3-3); RibLenfiJ is the length of  Image Analytic Techniques  36  the ith line segment with a < 15° so the line segment is in a radial position to the hypothetical coiling axis, a is calculated from the middle point of the segment (Fig. 3-3). The SC value provides a measurement of support that the hypothetical coiling axis gets from all line segments in the image using the underlying geometric pattern. Coiling axis is practically always located within a central region in the image which is half of the image size in terms of width and height. The program samples this region from left to right, top to bottom computing the SC values with an increment of 4 pixels which corresponds to 1 mm if the image scale is 1 and the monitor resolution is 100 dpi. The pixel which has the highest SC value is considered to be the location of the coiling axis. This algorithm gives very robust results. 3.4.5  Classification of coiling curves and ribs This is the most challenging part of the program since coiling curves and ribs often  are broken by various kinds of noise and there may be lots of line segments resulting from local brightness changes which are not related to coiling curves and ribs (Fig. 3-3). Again the underlying geometric constraints are used to eliminate non-rib and non-coiling-curve : 1. Ribs distribute radially around coiling axis; 2. Coiling curves are nearly normal to radius vectors (p > 75°); 3. The distance between adjacent ribs should not change abruptly, otherwise there must be missing ribs or false ribs between them; 4. The length of each rib should be consistent with its neighboring ribs; 5. The "white to black" rib edges should be sandwiched by two "black to white" rib edges and vice versa; 6. Empirically, the range of shell expansion rate (W) for Lower Jurassic ammonites is between 1.2 and 5, possible coiling curve segments and geometric relations among them should meet this constraint; Generally speaking, statistical data on geometric features are  more robust than  individual measurements. The image is therefore divided into 12 equiangular sectors around  Figure 3-$iJ- Automatic image measurement Computer classified and simulated ribs and coiling curve on original image  -4  Image Analytic Techniques  38  the coiling axis. Rib and coiling curve segments are verified in each sector and then rechecked during the final assembling stage according to the above constraints. 3.4.6 Deriving morphological parameters Once the coiling axis, coiling curves and ribs are determined, shell expansion rate (W), rib density (PRHW), volution (VOLUTIONO), AH and their changes during ontogeny can easily be computed. Nonlinear regression can be used to formulate rib forms. Fig. 3-4 shows ribs and coiling curves simulated by the program superimposed on the original image; ribs were matched using the least squares technique. This program can be a handy tool to explore ontogenetic changes. A user may determine the shell expansion rate between any two points by clicking on them with the mouse. Similarly, a user may determine the rib density between any two points by clicking on them; the program will display how many ribs between the two points and how many ribs there would be for half a whorl. By working from the inner to the outer whorls, the user can get a clear picture of how the shell expansion rate and rib density change during growth. In this example (Fig. 3-4) the rib density gradually increases from 28 -> 30 ->34 -> 36 -> 44 from the visible innermost whorl to the outer whorl then start to decrease to 42->39->34 in the last half whorl. Unfortunately the accuracy demonstrated in this example cannot be achieved in most cases. It is very difficult to classify all ribs and coiling curve segments correctly and locate coiling curve accurately. 3.5  Elliptic Fourier Analysis of Whorl Shape  Whorl shape is an important aspect of ammonite shell morphology. A simple descriptor in the Ammon database is the ratio of whorl width to whorl height (WWWH) which does not define the shape uniquely since a circle and a square would give the same ratio. Another descriptor WHORL_SHAPE uses descriptive terminology such as "quadrate", "rounded", "subrounded" etc, but workers do not necessarily agree on the exact meaning of a given descriptive phrase such as "subrounded" and it is difficult to compare variations across different taxonomic groups. These considerations create a need for a method like Fourier analysis which has been successfully used in many paleontological studies for the  Image Analytic Techniques  39  characterization of closed curves (Kaesler and Waters, 1972; Anstey and Delmet, 1973; Christopher and Waters, 1974; Younker and Ehrlich, 1977; Canfield and Anstey 1981; Foote 1989). One commonly used Fourier method, polar Fourier analysis (Kaesler and Waters, 1972), is limited to simple curves without multiple reentrants and is therefore not considered here. The more sophisticated elliptic Fourier analysis (Kuhl and Giardina, 1982) and perimeter-based Fourier analysis (Foote 1989) were compared in a preliminary study. Experiments with whorl shape data show that the elliptical Fourier analysis gives better results, and there is also the advantage that there is no need to determine an artificial centroid for the shape. The Elliptical Fourier analysis is therefore used in the following study. Whorl shape outline is approximated by a continuous sequence of digitized points in an X-Y coordinate system. The outline can be considered to be generated by a point moving around the boundary. Suppose / is the arc length along the curve, U is the arc length at point p; L is the total perimeter length and K is the total number of points on the curve. The elliptical Fourier series are (Kuhl and Giardina, 1982):  x(/) = ^o + | ] ( ^ c o s ^ + Z > „ s i n ^ ) n=\  y{l) = Co + JT {en cn2rat/ o s ^ , +j dn^„2rmh sin^/) where an and bn are the nth harmonic:  L On =  6  c  ^AxP  Irrnlp  r~^y >  2n2%2p?lAlp L ^AxP  =  * ^v^ =  L  ,  L  rf =  L . 2n%lP  [sl,  v^Aypr  " ^v^  ^-  -^-  ^.Aypp . 2mdp  [sm  —  J  L 2n%lp-u  •  sm  2nnlp  [cos  " 2^Vp?1^  Axp=Xp-  Irmlp-u  [COS—=-^ - COS  -T-] 2n%lP-u  cos .  -^ ]  2rmlp-u  i sm  "T - -~i^]  Xp.^ Ay p = yp - yp_]  p = l,2,.... K  The constant components in these Fourier series are as follows:  40  Image Analytic Techniques  1  K AJC  ^ = L- i2Al H—riil - /2 ,) + WP - lp - 0 p=  P  K  Co  AKP 2 2 (/ P-/ PP-i)  2AV  + W^-^-0  where P'1 7=1 pP - 1l  ~  Z< 7=1  AXvP'1 A/iP j=\  AvD,P~l P~L A/p  y=i  and  The following normalization procedure results in Fourier descriptors which are invariant with rotation, dilation and translation of the contour and also with the starting point on the contour. The basic idea is to rotate the first harmonic phasor until it is aligned with a semi-major axis of its locus:  a? bZ where 0] = 2nXj/L  cos yn sin y/\ - sin yn cos yn  a„ bn cosn&i -sinnOi _C/j  sinn0  cosnOi  and X] is the displacement of the starting point, V}/^ is the spatial  rotation angle:  6U— arctan 2{a\b\+c\d\) 2. 2 , 2 ,2 2 _a\+c\-b\-d\ _  a* c* _b* d\  Cln_  cos# - sin 0  sin# d\ C\ co 5 0 b\ di  Image Analytic Techniques  41  Figure 3-5 1-, 9-, 12-, and 30- harmonic representations of a geometric shape (from Kuhl and Giardina 1982) The Fourier coefficients can be made independent of size by dividing each of the coefficients by the magnitude of the semimajor axis and independent of translation by ignoring the bias terms Ag and CQ. The first harmonic content of the size-normalized Fourier series is always characterized by af = i-0, bf* = o.o, cf = o.o, df* < 1.0. Elliptic Fourier series can be used to represent very irregular closed contours as demonstrated by Kuhl and Giardina (Fig. 3-5). Whorl shape drawings are scanned into the computer from published work. A thinning algorithm (Pavlidis 1982) is used to skeletonize outline parts potentially wider than one pixel and a contour tracing program (as used in section 3.4) links separate pixels into a continuous outline ready for analysis. Fig. 3-6 shows the ontogenetic variations of Arnioceras ceratitoides. the number of  Image Analytic Techniques  WHORL SHAPE  FOURIER REP  ONTOGENY  1 2 3  4 5  Figure 3-6  Ontogenetic change in whorl shape for Arnioceras ceratitoides  42  43  Image Analytic Techniques -+•  ONTOGENY  ONTOGENY  Figure 3-7 Computer generated hypothetical sequence from interpolation of whorl 1 and 9 in Fig. 3-6.  Figure 3-8 Computer generated hypo-thetical sequence from extrapolation of whorl 6 and 7 in Fig. 3-6.  From top to bottom, numbers of harmonic used in the Fourier series are: 4, 3, 4, 5, 6, 6, 8, 15, 23 (root mean square error < 0.01) harmonics required to reduce root mean square error to 0.01 or less increases with ontogeny. This is consistent with the visual observation of the general increase in whorl shape complexity. The most significant change occurs from whorl 7 to 8 where the number of harmonics increases from 8 to 15 which corresponds to the development of a keel. One of the principal advantages of Fourier analysis is that it allows the construction of intermediate whorl shapes and extensions, or reductions, of morphologic trends beyond the forms available. If the first whorl in Fig. 3-6 is allowed to evenly evolve (in terms of Fourier coefficients) into the last whorl, it produces a hypothetical sequence of whorl shapes which is different from the real sequence (Fig. 3-7). Fig. 3-8 (right) shows an extrapolation sequence of whorl 6 to 7. A program (Appendix 7) has been written to visualize and animate the detail  Image Analytic Techniques  44  of how one whorl shape can gradually evolve into another. All shapes in the sequence are normalized and later whorls are superimposed on the earlier whorls so that subtle change in shape can be detected. These examples demonstrate the potential value of elliptic Fourier analysis in morphologic simulation. In addition, Fourier analysis can detect and quantify whorl shape variations within and among taxa. Ontogeny can be directly compared with phylogeny to gain insight into heterochrony. It would be interesting to map the whorl shape distribution of naturally occurring ammonites with respect to their Fourier representations so the relative density of occurrence can be evaluated, perhaps shedding light on functional factors governing whorl shape. Finally, current models of 3-D simulation of ammonites shells all assume a circular or ellipsoid whorl section. Fourier representation of whorl sections make it possible to model real ammonites. All these are open areas for future research.  Morphological Variation and Covariation  Chapter 4  4.1  45  Morphological Variation and Covariation  Introduction  The diverse shell morphologies of ammonites have promoted much speculation on relationships between shell form and function, shell geometry and taxon duration. In this chapter the Ammon database is used to analyze Lower Jurassic ammonites in terms of shell morphology, possible correlation between taxon longevity and its morphological variability. In addition to documenting the range and diversity of ammonite morphology, I hope to demonstrate the existence of patterns of shell morphology that are independent of taxonomy at the superfamily level. This concerns possible functional relationships between morphological variables. It is well known that the information in paleontological databases is incomplete (Raup 1991): only a fraction of the taxa that ever lived have been sampled, new fossil material is being collected all the time and taxa are subject to revision with new discoveries. Despite many potential sources of error, Sepkoski (1993) demonstrated that errors and changes in paleontological databases are not necessarily impediments to statistical analysis so long as the data are sufficiently numerous. 4.2 4.2.1  Lower Jurassic Ammonite Shell Morphology  Background As is shown in one outstanding paper by Raup (1967), the basic geometry of  planispiral ammonites can be described by three parameters: W (whorl expansion rate), U (umbilical ratio), WWWH (shape of the whorl). Plots of W, U and WWWH can be used effectively to map the distribution of basic shell geometry. Raup (1967) showed that ammonoids occupy only a portion of the theoretical range of possibilities for shell geometry, and that some geometric combinations have been utilized more than others. Raup's approach was subsequently used by Ward (1980) to compare the shell geometry of Jurassic and  Morphological Variation and Covariation  46  Cretaceous ammonoids to Mesozoic and Cenozoic nautiloids. Chamberlain (1981) went further and related ammonoid and nautiloid shell geometry to hydrodynamic efficiency by showing that species with coiled shells cluster on adaptive peaks that optimize streamlining and stability. More recently, Saunders and Swan (1984,1987) have used this approach to analyze the morphologic diversity of mid-Carboniferous ammonoids. These studies demonstrated the usefulness of Raup's approach in evaluating and graphically portraying the distribution of ammonoid shell geometry. By design, the studies of Raup, Ward, and Chamberlain were generalized in their approach; this was necessary in order to assemble the amount of data required for the types of analyses undertaken. However, geometric analysis at the taxonomic level of genus and stratigraphic level of period, while acceptable for a preliminary survey, is increasingly regarded as being too coarse-grained to resolve many critical questions. Database Ammon makes it possible to work at the species and zonal levels. As a result of more detailed analysis, some of Raup's conclusions, particularly concerning geometric trends through time and ontogenetic variations are now subject to revision. 4.2.2  The Sample of Observations The data used in this study comprise observations made on 6784 specimens,  representing 15 families, 179 genera, and 1319 species. This comprises virtually complete coverage for the ammonite genera known to occur in the Lower Jurassic as catalogued by Donovan, Callomon, and Howarth (1981). All species are represented in the sample by averaging the measurements made on specimens with shell diameters (D) larger than 4 cm. This reduces the impact of ontogenetic change on the data since most Lower Jurassic ammonite species that undergo such change do so early in ontogeny. Selected analyses at D > 8 cm show no appreciable differences from analyses conducted at D > 4 cm. Ontogenetic change will be considered as a separate problem with appropriate biometrical data in section 4.5. Variations between each species are also calculated which show that morphological variations between species are much higher than within species, for basic shell geometry even though intraspecific variations are widespread (Table 4-1).  Morphological Variation and Covariation Table 4-1  Between species variance and within species variance  Parameter Mean  F-BSV /WSV  Ftest cc=0.01  U W WWWH  16.99 7.01 8.53  1.32  4.2.3  Between Species Variance Within Species BSV (Num. of Species) Variance WSV (Num. of Species) 0.000915 (817) 0.4192 0.015502(1251) 0.015257(670) 2.0231 0.106973 (1248) 0.009702 (639) 0.8822 0.082893 (1045)  Basic Shell Geometry The W, U, and WWWH data for the whole sample have been plotted as scatter  diagrams with one point for each species. The density of points in the scatter has been contoured and the results shown in Fig. 4-1, where successively higher contours indicate increase in points per unit area on the plot. The shell geometry of these ammonites is restricted to the low W and high U region of the morphological spectrum with the greater portion clustering in the vicinity of W=1.9, U=0.45, which coincides with one of the two peaks of hydrodynamic efficiency determined by Chamberlain (1981). Fig. 4-2 shows that WWWH is strongly correlated with W; as W increases, WWWH decreases. Figures 4-3, 4-4, 4-5 show the standard deviation contours of W, U, and WWWH with respect to W and U, which serve as "error bars" for Fig. 4-1 and Fig. 4-2, only species with at least 6 occurrences in the database are used, the number is chosen somewhat arbitrarily, any fewer than this seems to me to be too small a number for calculating standard deviation for a species. The curved line shown in these figures follows the equation W=l/U which marks the point of minimal whorl contact. The density contour and WWWH contour are strikingly similar to those for Mesozoic ammonoids in general being largely concentrated on a small portion of the theoretical range of possibilities for shell geometry (Fig. 4-6) and suggesting the same geometrical restraints. For example, high values of U tend to be associated with low W and high WWWH, which forms an important part of Buckman's Law of Covariation.  Morphological Variation and Covariation 1.20  1.40  1.59  1.79  1.99  2.18 2.38 2.58 2.77 2.97  "I I I I I I I I I I I I I I I I I I I I I I I I  1.20  1.40  1.59  1.79  1.99  48  3.16 3.36 3.56 3.75 3.95 I I I I I I I I I I I II I I L  2.18 2.38 2.58 2.77 2.97 3.16 3.36  3.56  3.75  3.95  W  Figure 4-1  Density diagram with respect to W and U (whole sample)  1.20 1.37 1.54 1.71 1.89 2.06 2.23 2.40 2,57 2.74 2.91 3.09 3.26 3.43 3.60 3.77 3.94 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I |_  1.20 1.37 1.54 1.71 1.89 2.06 2.23 2.40 2.57 2.74 2.91 3.09 3.26 3.43 3.60 3.77 3.94  W  Figure 4-2  WWWH contour with respect to W and U (whole sample)  Morphological Variation and Covariation 1.20  I  0.00 1.20  1.42  1.63  I  l  I  1.42  I  1.85  I  1.63  I  I  2.06  I  1.85  2.28  2.49  2.28  2.49  l  2.71  I  I  2.06  2.92  I  2.71  I  I  3.14  I  2.92  I  I  49  3.35  I  3.14  I  I  3.57  I  3.35  I  I  3.78  I  3.57  I  I  4.00  I  3.78  I  0.00 4.00  W  Figure 4-3  Standard deviation contours of W with respect to W and U (964 species)  1.20  1.42  1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  3.35  3.57  3.78  1.20  1.42  1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  I I I I I I I I I 3.35 3.57 3.78 4.00  W  Figure 4-4  Standard deviation contour of U with respect to W and U (964 species)  4.00  Morphological Variation and Covariation  50  1 1.20  1.42  1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  3.35  3.57  3.78  .20  1.42  1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  3.35  3.57  3.78  4.00  0.83 0.77 0.70 0.64 0.57 0.51 0.45  Z> 0.38 0.32 0.26 0.19 0.13 0.06 0.00  W  Figure 4-5  Standard deviation contour of WWWH with respect to W and U (780 species)  * } ^ ^ ^ 5 ^  3 bV  N v  $N\ ^  s  f  J  Figure 4-6  W and U density topography (whole sample)  0.00 4.00  Morphological Variation and Covariation 4.2.4  51  An interpretation of Buckman's Law of Covariation Swan and Saunders (1987) made the important observation that the covariation  among W, U, and WWWH may be related to restrictions imposed by the shape and relative size of the whorl. If AH is the ratio of the internal cross sectional height of the whorl (IH) to the external height of the whorl (EH) and W <= 1/U (Fig. 4-7 , inset) then: AH=(1-1/W)/(1-U)  (1)  When the family of curves for successive values of AH is superimposed on the W-U scatter plot, there appears to be a relationship (Fig. 4-7). The actually occurring combinations of W and U appear to be concentrated on AH of between 0.7 and 1, whereas the preferred AH for mid-Carboniferous ammonoids is between 0.5 and 0.7. Swan and Saunders (1987) stated 0.1  0.2  0.3  0.4  0.5  O.G  0.7  0.8  0.9 U  1.5  2.0  2.5  3.0  3.5  4.0  4.5  W  Figure 4-7 Family of curves for AH in terms of W and U  Morphological Variation and Covariation  52  "In terms of function, we speculate that the distinctly U-shaped cross sections that result from low AH values might prohibit the deployment of strong propulsive musculature, and might even restrict ingestion. It is not so obvious why high AH values should have been unfavorable". In contrast, high AH values are popular among Lower Jurassic ammonites. From equation (1) above, it is apparent that as expansion rate (W) increases, U has to decrease if AH is to remain relatively constant as is observed in the Carboniferous and Jurassic samples. Furthermore, if AA is the cross sectional area of the whorl, as a first order approximation that does not consider the overlap area between two successive whorls, then for unit shell radius: AA=K*WWWH*(1-U)2  (2)  1  cross section is rectangular or quadrate  7i/4 rc/4  cross section is circular (Swan and Saunders 1987 equation) cross section is elliptic  1/2  cross section is triangular  (  In real world ammonites, both rectangular and triangular whorl sections have some degree of rounding, the actual range for constant K is somewhere between 0.6 and 0.9 instead of 0.5 and 1, and the most common forms have K values around 7t/4. Assuming K=7t/4, the family of curves for equation (2) in terms of WWWH and U again shows a parallelism with the distribution of Lower Jurassic ammonite data. Fig. 4-8 illustrates a preference for AA values between 0.1 and 0.3 whereas the preferred AA for mid-Carboniferous ammonoids is between 0.5 and 0.7 (Swan and Saunders 1987). From equations (1) and (2), one can infer that, as expansion rate (W) increases, U decreases in order to keep AA constant and consequently WWWH decreases. This explains the previously observed pattern that shells with higher expansion rates tend to be more involute and compressed, and involute shells with low expansion rates tend to be depressed. I can demonstrate the negative correlation between U and WWWH holds, even if the overlap area between two successive whorls is considered.  Morphological Variation and Covariation 0.1  0.2  0.3  0.4  0.5  0.G  0.7  0.8  53 0.9 U  1.6v WWWH  Figure 4-8 Family of curves for AA in terms of WWWH and U  1. If the whorl cross section is rectangular or quadrate, then for unit shell radius: AA=WWWH*(1-U)*(1-U-(1/W-U)/W) Let  F(U)=(1-U-(1/W-U)/W)  (3)  (4)  Combining Eqs (1) and (4), we have F(U)=(AH-AH2)*U2+(2*AH2-3*AH)*U+2*AH-AH2 whose derivative is F'(U)=2*(AH-AH2)*U+2*AH2-3*AH Since U<1, F'(U)<-AH  Morphological Variation and Covariation  54  and AH is always positive, therefore  I—WW —  F'(U)<0 The derivative is negative, so the function F(U)  WH I  AA  U _ _ r=1  1 T lf  I  wh 1  decreases as U increases, Finally, because AA=WWWH*(1-U)*F(U)  (  I conclude as U increases , WWWH decreases in order to  I  u  I  1  h  keep AA constant. 2. If cross section is triangular, then for unit shell radius: AA=0.5*WWWH*((1-U)2-(1/W-U)2) Let  F(U)=(1-U)2-(1/W-U)2  (5)  (6)  Combining Eqs (1) and (6), we have  Figure 4-9 Cross section with unit shell radius, so u equals to U of Amnion, WWWH = WW / WH W = WH /wh  F(U)=(2*AH-AH2)*U2+(2*AH2-4*AH)*U+2*AH-AH2 whose derivative is F'(U)=2*(2*AH-AH2)*U+2*AH2-4*AH Since U<1, F'(U)<0 The derivative is negative, so the function F(U) decreases as U increases, Finally, because AA=0.5*WWWH*F(U) I conclude as U increases , WWWH decreases in order to keep AA constant. 3. Other shapes: since the vast majority of whorl shapes stand between the two extremes, that is between triangular and rectangular shapes, we can reasonably expect the negative correlation between U and WWWH would also hold for them. 4.2.5  Morphological Variability and Taxon Longevity The relative durations of taxa and the possible correlation between morphology and  duration are intriguing puzzles of evolution (Ward 1983). The standard deviation contours of W, U, and WWWH (Figs. 4-3, 4-4, 4-5 respectively) not only serve as the "error bars" of Fig.  55  Morphological Variation and Covariation  4-1 and Fig. 4-2, but also show the morphological variability of species at the corresponding location in the morph space. The magnitude of the standard deviation is at least in part controlled by the magnitude of the mean value; to facilitate the comparison of morphological variability between different species, the direct influence by the magnitude of the mean value is eliminated by calculating the coefficient of variation (Cy) where Cy = standard deviation * 100% / average It is evident from Figs. 4-10, 4-11, 4-12 that the coefficients of variation for W, U, and WWWH show the same pattern of changes (only species with at least 6 occurrences and stratigraphic information are used); small Cy values are associated with the most densely populated region of low W and high U. Moving away from this adaptive peak to less densely populated regions of high W and low U, the coefficients of variation gradually increase, which may indicate that less selective pressure is being applied in these adaptive "lowlands". Jurassic ammonites are commonly regarded as excellent index fossils that offer fine time resolution. To examine whether there is a correlation between basic shell geometry and taxa duration, the range data of Lower Jurassic ammonite species and genera have been assembled. Table 5-1 presents the well-established northwest European zonation scheme used as the primary standard in this study; the Lower Jurassic is divided into 4 stages and 20 zones. In the discussion that follows concerning the duration of taxa in units of zones, the following points should be borne in mind: (1)  In constructing time scales, absolute ages are established for points within sequences and encompassed zones are assumed to be equal in duration for interpolation purpose (Palmer et al 1983; Harland et al 1989).  (2)  If a taxon is found within a zone, it is assumed to range throughout the zone which may inflate the range of some taxa.  (3)  Attention is confined to taxa whose range can be resolved to the zonal level and are well represented in the database (arbitrarily by at least 6 occurrences).  that  Morphological Variation and Covariation 1.20 0.83  1.42 I  I  1.63 I  I  I  1.85 I  I  I  2.06 I  I  I  2.28 I  I  I  2.49 I  I  I  2.71 I  I  I  2.92 I  I  I  3.14 I  I  I  3.35 I I  56 3.57 I  I  3.78 I  I  I  I  4.00 0.83 0.77 0.70 0.64 0.57 0.51 0.45. 0.38 0.32 0.26 0.19 0.13 0.06  I  0.00  1.20  I  1.42  I  I  I  1.63  I  I  I  1.85  I  I  I  2.06  I  I  I  2.28  I  I  I  2.49  I  I  I  2.71  I  I  I  2.92  3.14  I  I  I  3.35  I I  3.57  3.78  0.00 4.00  w Figure 4-10 1.20  1.42  Figure 4-11  The coefficient of variation contours for W 728 species, contour interval = 0.07 1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  3.35  The coefficient of variation contours for U 728 species, contour interval = 0.03  3.57  3.78  4.00  57  Morphological Variation and Covariation 1.20  1.42 1.63 1.85 2.06 2.28 2.49 2.71 2.92 3.14 3.35 3.57 3.78 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I  0.83  4.00 0.83 0.77 0.70 0.64 0.57 0.51 0.45 0.38 0.32 0.26 0.19 0.13 0.06  I  0.00 1.20  I I I I I I I I I I 1.42 1.63 1.85 2.06  2.28  I I I I I 2.49 2.71  I I 2.92  3.14  3.35  3.57  3.78  0.00 4.00  W  Figure 4-12  The coefficient of variation contours for WWWH 728 species, contour interval = 0.015  The duration contour for the same species as in Fig. 4-10 (Fig. 4-13) shows resemblances to the coefficient of variation contour plots (Figs. 4-10, 4-11, 4-12). Ammonites occupying the adaptive peak have low within-population variability and short duration. Away from this peak in faster expanding regions, there is a steady increase in both morphological variability and taxa longevity implying a decrease selective pressure. Patterns at the generic level need not be identical to those at the species level, since long-lived genera, for example, could include many short-lived species. Fig. 4-14 shows the duration contour for 117 genera to whom the above 964 species belong, which is very similar to the one for the species. This result suggests that generic and species longevities of Lower Jurassic were related to their morphology. One possibility is that the correlation between taxa duration and geometric variability could be the result of unequal taxonomic splitting. The concept that taxonomy and ranges are influenced by complexity of hard-part morphology was advocated  Morphological Variation and Covariation  58  by Schopf et al. (1975) who suggested that a fossil with a great deal of describable morphology will normally show a shorter range than a nondescript form because evolutionary change in the nondescript taxon will have less chance of being recognized. Following this reasoning, the least ornamented ammonites should have longer durations. It is interesting to see whether the above observed correlation holds once the influence of ornamentation is eliminated. Subsamples for both species and genera with smooth shells or weak ornamentation were extracted from the whole sample. Figs. 4-15, 4-16 show their duration contours and it is clear that both figures still reflect the trends seen in Figs. 4-13, 414. The analysis presented here is primitive, and the conclusion that taxa duration may be related to morphological variability within the population through selective pressure is tentative. To be more confident with this conclusion, a more refined time scale calibration, a better correlation between different ammonite zonation schemes, and more specimens for under-represented species are needed. 1.20  1.43  1.67  1.90  2.13  2.37  2.60  2.83  3.07  3.30  3.53  3.77  4.00  0.83 0.76 0.69 0.62  0.55 0.48 Z) 0.42  0.35 0.28 0.21 0.14 0.07  J  0.00 1.20  1.43  I  I 1.67  1  I 1.90  I  I 2.13  L  I  2.37  2.60  I  J  I  2.83  3.07  L 3.30  I  3.53  I  I  3.77  n nn  4.00  W  Figure 4-13  Contours of species duration in units of zones, 728 species, contour interval = 0.04  59  Morphological Variation and Covariation 1.20  , 00 I 1.20  1.43  I  I 1.43  Figure 4-14  1.67  I  I 1.67  1.90  I  I 1.90  2.13  I  I 2.13  2.37  I  I 2.37  2.60  I  I 2.60  2.83  I  I 2.83  3.07  I  I 3.07  3.30  I  I 3.30  3.53  I  I 3.53  3.77  I  I 3.77  4.00  l_J 0 0 0 4.00 '  W Contours of genus duration in units of zones, 117 genera, contour interval = 0.2  1.20  1.39  1.59  1.78  1.97  2.17 2.36 2.55 2.74 2.94 3.13 3.32  3.52  3.71  3.90  1.20  1.39  1.59  1.78  1.97 2.17 2.36 2.55 2.74 2.94 3.13 3.32 3.52  3.71  3.90  W  Figure 4-15  Contours of species duration in units of zones for species with weak ornamentation, 258 species, contour interval = 0.06  60  Morphological Variation and Covariation  1.20  1.42  1.63  1.85  2.06  2.28  2.49  2.71  2.92  3.14  3.35  3.57  3.78  4.00 '  w Figure 4-16  4.2.6  Contours of genus duration in units of zones for genera with weak ornamentation, 53 genera, contour interval = 0.15  Correlation between basic shell geometry and other morphological features The analysis thus far has considered only the essentials of overall form and has  ignored ornamentation and ventral features. In the following analyses I explore the correlation between basic geometry (W and U) and 10 variables characterizing ornamentation and ventral features. The most significant correlations with shell geometry involve tubercles, rib-furcation, rib strength and the presence of a keel. The first attempt is related to shell ornamentation, and particularly to the development of tubercles. Three subsamples were extracted from the total sample. Fig. 4-17 shows the WU distribution of ammonites with tubercles on the upper flank, Fig. 4-18 shows the W-U distribution of ammonites with tubercles on the lower flank, neither of which differ substantially from the distribution for the whole sample (Fig. 4-1) except for the general absence of tuberculate forms in the low U region. Fig. 4-19 showing the W-U distribution of  61  Morphological Variation and Covariation  ammonites with two rows of tubercles is more or less a combination of Fig. 4-17 and Fig. 418. Figs. 4-20, 4-21, 4-22 show the W-U distributions of ammonites with simple ribs, ribs furcated on upper flank, and ribs furcated on lower flank respectively. The W-U distribution of ammonites with simple ribs is similar to the distribution for the whole sample (Fig. 4-1), whereas ammonites with ribs furcated on upper flank concentrate on the low W and high U region, and ammonites with ribs furcated on lower flank tend to be more involute and have higher expansion rates. Similar analysis of subsamples was made in relation to the coarseness of ribs. Three subsamples were extracted from the total sample. Figs. 4-23, 4-24, 4-25 show the W-U distribution of ammonites with weak ribs, average ribs, and strong ribs respectively. Ammonites with weak ribs show more diversity in terms of basic shell morphology, as the rib strength increases, the shells tend to be more and more restricted to Chamberlain's (1981) low Cf3 peak region with high hydrodynamic efficiency. It is difficult to explain, 1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77  2.97  3.16  3.36  3.56  3.75  3.95  - l 0.80  0.73 0.66 H 0.58  0.51 - 0.44  0.37 0.29 0.22 0.15 0.07 •II I I i i i i ii i i i i i i i i i i i M i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i r O.00 0.00 1.20 1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95  W  Figure 4-17  Density diagram for ammonites with tubercles on upper flank (208 species)  Morphological Variation and Covariation 1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77  2.97  3.16  62 3.36  3.56  3.75  J I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I l I I l l l I I I I I I I l l ll  -I I l l l l  0.00  1.20  1.40  Figure 4-18 1.20  1.40  I I l l I  1.59  1.79  1.99  2.38  3.95 ll  II I I I I I I I I I I I I I I I I  I I I I I  2.18  ll  2.58 2.77 2.97  3.16  3.36  3.56  3.75  W Density diagram for ammonites with tubercles on lower flank (64 species) 1.59  1.79  1.99  2.18  2.38 2.58 2.77 2.97  3.16 3.36  3.56  3.75  3.95  I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I II  0.00  'I  1.20  l l l I I I l l l I l l I l l l l l l  1.40  Figure 4-19  0.00  3.95  1.59  1.79  1.99  l l I l I I  2.18  2.38  I  2.58  2.77  I l l l l  2.97  3.16  3.36  D  I I I i-  3.56  3.75  3.95  W Density diagram for ammonites with two rows of tubercles (74 species)  0.00  Morphological Variation and Covariation 1.20  1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 I I I I I I I I I I I I I I I I I I II I I I I I II I I I I I I I I I I I I I I I I I I I I I I  1 I I I I I I I I I I I I I I I I II  0.00 1.20  63  1.40  1.59  1.79  1.99  I I I I I I I I I M  2.18  2.38  2.58 2.77  I I I I I I  2.97  3.16 3.36  3.95  ll  3.56 3.75  3.95  0.00  W  Figure 4-20  Density diagram for ammonites with simple ribs (784 species)  1.20 1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95 I I I I I I I I I II I I II I I I I I I II I I I I I I I I I I I I I I I II II I I I I I I I I I I I I I L  0.80 0.73 0.66 0.58 0.51 0.44 0.37 0.29 0.22 0.15 0.07  0.00 ' l l 1.20 1.40  M  1.59  I  1.79  I I I I l I I I I l l I I I I I I I I I I I I I I I I I I I I I I I  1.99  2.18  2.38 2.58 2.77  2.97  3.16 3.36 3.56 3.75  r  0.00  3.95  W  Figure 4-21  Density diagram for ammonites with ribs furcated on upper flank (150 species)  Morphological Variation and Covariation  64  1.20  1.40  1.59  1.79  1.99  2.18 2.38 2.58  2.77  2.97  3.16  3.36  3.56  3.75  3.95  1.20  1.40  1.59  1.79  1.99  2.18 2.38 2.58 2.77  2.97  3.16  3.36  3.56  3.75  3.95  Figure 4-22 1.20  1.40  W Density diagram for ammonites with ribs furcated on lower flank (178 species) 1.59  1.79  1.99  2.18  2.38 2.58 2.77  2.97  3.16  3.36  3.56  3.75  3.95  J I I I I I I I I I I I I I I I I I I I I I II I I I II I I I I I I I I I I I I I I I I I I I I I I I I I  0.00 ~i 1.20  i i i M  1.40  1.59  1.79  i i i r ITM/1 I I / T T T I  1.99  2.18  2.38  i i i i i i i  2.58  2.77  2.97  ii  3.16  i i it  3.36  W  Figure 4-23  Density diagram for ammonites with weak ribs ( 278 species)  i i i i i i i i  3.56  3.75  0.00 3.95  65  Morphological Variation and Covariation 1.20  0.00 i 1.20  1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95 I I I I I I II I I I I I I I I I I I I I I I I II I I I I I I I I I I I I II II I II II I I I I I  i i i i i t i i M  1.40  1.59  i i  1.79  i i i i i i i i  1.99  2.18  2.38 2.58  i i i i i i i  2.77  2.97 3.16 3.36  i i i i i i r  3.56 3.75  3.95  0.00  W  Figure 4-24 1.20  Density diagram for ammonites with average ribs (701 species)  1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I.  0.80 0.73 0.66 0.58 0.51 0.44 0.37 0.29 0.22 0.15 0.07  0 0 0  i:  1.20  11 i i i i 11 M  1.40  1.59  1.79  1.99  i i i  2.18  i i i i i  2.38 2.58 2.77  i i i i i i i i r  2.97 3.16 3.36 3.56  3.75  3.95  w  Figure 4-25  Density diagram for ammonites with strong ribs, X marks low Cj> peak of Chamberlain (1981), 351 species  0.00  Morphological Variation and Covariation  66  considering ammonites with strong ornamentation are generally regarded as poor swimmers (Swan and Saunders 1987). One possibility is that if ribs are coarse for reasons not connected with hydrodynamic efficiency, then it makes sense to offset their detrimental impact on the drag coefficient by adopting the most hydrodynamically efficient shell geometry Since Chamberlain's Cj) contour map was based on shells having circular whorl cross sections (WWWH=1), I used a subsample of specimens with 0.89<=WWWH<=1.11. Fig. 4-26 shows the same phenomenon, namely that shell forms with the coarsest ribs are concentrated around the low CQ peak region. A similar analysis of subsample was made in relation to the presence or absence of a well-defined keel on the venter. Fig. 4-27 shows ammonites with a plain venter are most abundant in the low W and low U region. Fig. 4-28 shows ammonites with a keel are more evenly distributed.  Morphological Variation and Covariation  Rib Width < 0.1  67  0.1 <= Rib Width < 0.2  u  U  0.8  0.8  0.7  0.7  O.G  O.S  0.5  0.5  0.4  0.4  0.3  0.3  0.2  0.2 0.1 i.S  2.0  2.5  3.0  3.5  4.0  4.5  W 1.5  2.0  0.2 <= Rib Width < 0.3  2.5  3.0  3.5  4.0  4.5  W  3.5  4.0  4.5  W  Rib Width >= 0.3  u  **•  0.8 0.7 0.6 0.5 0.4 0.3  0.3  0.2  0.2  0.1  0.1  1.5  2.0  2.5  3.0  3.5  4.0  4.5  W  1.5  2.0  2.5  3.0  Figure 4-26 W and U distribution with respect to rib width X marks low C D peak of Chamberlain (1981)  68  Morphological Variation and Covariation  '  1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77  2.97  3.16  3.36  3.56  3.75  3.95  1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77  2.97  3.16  3.36  3.56  3.75  3.95  W  Figure 4-27  Density diagram for ammonites with plain venter (409 species)  1.20 1.40 1.59 1.79 1.99 2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I LI  0.07 0.00  i i i i i 11; i M i / 1 1 1 i i i i i i i i i i i i i i  •i i i i  1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77  2.97  3.16  3.36  i i i i i i i i i i i r 0.00 3.56 3.75 3.95  W  Figure 4-28  Density diagram for ammonites with carinate venter (540 species)  Morphological Variation and Covariation  4.3 4.3.1  69  Covariation  Introduction Westermann (1966) has observed that several ammonite stocks show a persistent  intercorrelation of morphological features: more involute and compressed forms are less ornate than more evolute and inflated forms. Such a correlation was probably first recognized by Buckman (1892) and was named 'Buckman's Law of Covariation1 by Westermann (1966). Buckman (1892) identified 69 new species from a single bed of the Sowerbyi Zone in the Bajocian (Middle Jurassic) of Dorset, England. Based on covariation and morphologic intergradation, Westermann was able to group 64 of Buckman's species into a single palaeospecies. Subsequently, similar phenomena have been widely documented, for example, by Bayer and McGhee (1984), and Kennedy and Cobban (1976), who cited examples of intraspecific variation in Cretaceous ammonites. In Jurassic ammonites the superfamily has long been used as the principal high level taxon (Donovan, Callomon, and Howarth 1981). There are three superfamilies in the Lower Jurassic. The oldest is the Psilocerataceae which appears at the base of Jurassic and is of uncertain origin. The Eoderocerataceae appears four zones later than the Psilocerataceae and ranges four zones higher. The Hildocerataceae arises from the Eoderocerataceae in the lowest Pliensbachian and persists into the Middle Jurassic where it gives rise to all other Jurassic ammonites (Fig. 4-29). In the following sections, I will try to demonstrate that Buckman's Law of Covariation applies equally well to the three superfamilies of Lower Jurassic ammonites and in so doing, give a more rigorous demonstration of Buckman's Law than has been previously possible. I will then go on to explore other patterns of covariation. To focus on functional rather than phylogenetic constraints, I will test the patterns for each of the three superfamilies independently. To avoid bias by some frequently represented species in the  Morphological Variation and Covariation Lower  Jurassic  Middle  Psilocerataceae  70  Jurassic  Haplocerataceae  3 Eoderocerataceae  Spirocerataceae  Hildocerataceae Stephanocerataceae  X  Perisphinctaceae  Figure 4-29 Ranges and possible phylogenetic relationships of ammonite superfamilies in the Lower-Middle Jurassic (after Donovan, Callomon and Howarth 1981) database, species rather than specimens serve as the basic calculation unit. To incorporate the morphological variation during ontogeny, a species might be represented more than once. For example, the species Haugiajugosa shows strong variation during ontogeny and has four entries in the database: entry  W  V  Diameter  1  2.62  0.59  4.71  2  2.18  0.47  15.47  3  1.87  0.43  23.60  4  1.64  0.36  31.73  When studying how the V values are related to W values, the data are divided into three groups with W <1.8 (group 1), 1.8 <=W< 2.2 (group 2), and W >=2.2 (group 3). Entry 1 falls into group 3 with a V value of 0.59; entries 2 and 3 fall into group 2 with an average V value of 0.45; and entry 4 falls into group 1 with a V value of 0.36 so there are three data points for Haugiajugosa in the covariation analysis. For quantitative morphological parameters, the data are plotted as 3-D bar diagrams.  Morphological Variation and Covariation  71  Table 4-2 Abbreviations for statistical and morphological terms M -- Mean  S — Standard Deviation  Sig. - Significance Level, T Test  F — Frequency  PRHW — Primary Rib Density per half whorl  N — Number of Species  RW - Ratio of Maximum Rib Width to Whorl Height  RF - Rib Form  WWWH -- Ratio of Whorl Width to Whorl Height  D - Shell Diameter  V — Percentage of Interior Whorl being Overlapped  WWD - Ratio of Whorl Width to D  difference between two means is relatively small comparing with the standard deviations yet the means are significantly different due to large number of specimens used in the calculation 4.3.2  Buckman's Law (1) Shells with higher expansion rate (W) tend to be more involute (V).  Superfamil y  Psilocerataceae  Eoderocerataceae  Hildocerataceae  w\v  M 0.173 0.334 0.578  M 0.172 0.218 0.436  M 0.281 0.353 0.449  <1.8 1.8-2.2 >2.2  0.6  S 0.126 0.220 0.239  N Sig. 152 163 0.001 95 0.001  S 0.105 0.136 0.222  N Sig. 145 208 0.001 71 0.001  S 0.134 0.173 0.193  N Sig. 77 321 0.001 217 0.001  /—7|  0.5  •—71  0.4 0.3  y  :v ::  • <1.8 D1.8-2.2 • >2.2  :  0.2 0.1 Psilocerataceae  Eoderoceratace  Hildoceratacea  ae  e  W  This covariation can be explained by equation (1) in section 4.2, that is, the restrictions imposed by the ratio of the interior height of the whorl (IH) to the exterior height of the whorl (EH). (2) Involute shells are more compressed than evolute shells.  Morphological Variation and Covariation  72  (2) Involute shells are more compressed than evolute shells. Superfamily Psilocerataceae N Sig. S VYWWWH M 0.975 0.183 123 <0.3 0.860 0.218 86 0.001 0.3-0.6 >0.6 0.661 0.370 53 0.001  Eoderocerataceae Hildocerataceae N M Sig. M S N S Sig. 0.816 0.154 183 1.091 0.293 217 1.038 0.401 100 0.09 0.731 0.2 206 0.001 0.967 0.379 33 0.10 0.649 0.190 91 0.001  •  <0.3 M 0.3-0.6  WWWH  • Psilocerataceae  Eoderocerataceae  >0.6  Hildocerataceae  V  This covariation can be explained by equation (2) in section 4.2, that is, the restrictions imposed by the relative cross sectional area of the whorl (AA). (3) Compressed shells have finer ribs. Superfamily WWWHXRW <0.8 0.8-1.3 >1.3  Psilocerataceae M N SigS 0.144 0.059 79 0.184 0.057 152 0.001 0.253 0.057 13 0.001  Eoderocerataceae M N Sig. S 0.171 0.056 92 0.191 0.067 216 0.005 0.195 0.073 104 0.15  Hildocerataceae M N Sig. S 0.133 0.047 271 0.182 0.048 165 0.001 0.228 0.076 7 0.001  0.26,^ 0.24 0.22 0.2 RW  0.18  •  0.16  H 0.8-1.3  0.14  •  0.^ 0.1 Psilocerataceae  Eoderocerataceae WWWH  Hildocerataceae  <0.8 >1.3  Morphological Variation and Covariation  73  a* 0 0.4 I  0.6 I  I  w  o  Figure 4-30 Variation in the ratio between internal shell volume and volume of shell material, as a function of W and U assuming a shell thickness equal to 0.0772 of the radius of the generating curve(From Raup 1967). Buoyancy control and carbonate efficiency may have played major roles here. Assume (1) a circular generating curve and (2) no variation in relative shell thickness during ontogeny, Fig. 4-30 shows the distribution of the ratio: internal volume/volume of shell material with respect to W and U (Raup 1967). The buoyancy and relative secretion efficiency of the shell as measured by this ratio decrease toward the region of high W and low U. In a real example, Swan and Saunders (1987) measured the shell thickness on 129 whorl sections from 49 Middle Carboniferous ammonoid specimens and showed that there is an inverse relationship between W and shell thickness: forms with higher W tend to have thinner shells. Three possibilities arise: (a) weak ornamentation could minimize the loss of buoyancy due to the rapidly expanding shell. Fig. 4-22 and 24 in the preceding section also support this reasoning, since ammonites with strong ornamentation are restricted to the low W region whereas ammonites with weak ornamentation could have either slow or fast expanding shells; (b) it may be that shells with high W simply could not afford extra shell ornamentation due to the low carbonate efficiency; (c) weak ornamentation gives compressed and fast expanding shells  74  Morphological Variation and Covariation  better streamlining which may lessen the role of the shell as a protective device. No matter which of these interpretations is correct, covariations (1) and (2) can lead to (3). (4) Conversely from (3), shells with weak ribs are more compressed. Superfamily Rib\WWWH weak medium strong  Psilocerataceae M N Sig. S 0.757 0.253 45 0.854 0.288 139 0.02 0.976 0.219 56 0.002  Eoderocerataceae M N SigS 0.843 0.215 28 1.005 0.311 150 0.004 1.178 0.307 188 0.001  Hildocerataceae M S N Sig. 0.683 0.166 121 0.739 0.201 215 0.004 0.882 0.160 106 0.001  • weak • medium • strong  WWWH  Psilocerataceae Eoderocerataceae Hildocerataceae Ribs  4.3.3  Volution (1) Shells with sinuous ribs are more involute than shells with straight ribs.  Superfamily Rib FormW straight sinuous  Psilocerataceae M N S Sig0.277 0.209 176 0.618 0.231 20 0.001  Eoderocerataceae M S N Sig. 0.233 0.170 279 0.450 0.117 15 0.001  0.7 0.6 0.5 0.4 0.3 0.2 0.1  dJ  Psilocerataceae Eoderocerataceae Hildocerataceae Rib Form  Hildocerataceae M S N Sig. 0.275 0.161 105 0.373 0.177 231 0.001  • straight • sinuous  Morphological Variation and Covariation  75  From (1) and Buckman's law, we can infer: (2) Shells with sinuous ribs are more compressed than shells with straight ribs.  Superfamily Rib\WWWH straight sinuous  Psilocerataceae M N Sig. S 0.938 0.253 137 0.606 0.134 13 0.001  Eoderocerataceae M N S Sig. 1.137 0.300 289 0.692 0.095 17 0.001  Hildocerataceae M S N Sig. 0.935 0.246 93 0.754 0.154 169 0.001  1.2  1.H 1 WWWH  _  0.9  NO  0.8 0.7|.  0.6 0.51*4  •  straight  •  sinuous  Psilocerataceae Eoderocerataceae Hildocerataceae Rib Form  From (1) and Buckman's law, we can also infer: (3) Straight ribs tend to be coarser than sinuous ribs. Superfamily RFXRW straight sinuous  Psilocerataceae M N S Sig. 0.188 0.061 207 0.1 0.042 22 0.001  Eoderocerataceae Hildocerataceae M S N S N Sig M Sig0.188 0.068 325 0.179 0.053 127 0.151 0.056 19 0.1 0.156 0.047 240 0.001  0.19  RW  Psilocerataceae  Eoderocerataceae  •  straight  •  sinuous  Hildocerataceae  Rib Form  (4) Shells with tubercles on the upper flank tend to be more evolute than shells with tubercles on the lower flank.  Morphological Variation and Covariation Superfamily TubercW upper flank lower flank  Psilocerataceae M N Sig. S 0.226 0.162 29 0.401 0.149 4 0.025  Eoderocerataceae N Sig. M S 0.187 0.110 152 0.331 0.175 7 0.001  0.45 0.4 0.35 . 0.3 . 0.25 0.2 0.15 0.1 0.05  76 Hildocerataceae M N Sig. S 0.156 0.102 12 0.368 0.169 60 0.001  D upper flank • lower flank Psilocerataceae Eoderocerataceae Hildocerataceae Tuberc Position  (5) Shells tend to be more involute as whorl shape changes from quadrate, rectangular->rounded->ellipsoid->oval,ogival->triangular. Superfamily WhorlW quadrate rounded ellipsoid oval ogival triangular  Psilocerataceae M N S 0.186 0.137 52 0.227 0.167 73 0.299 0.225 79 0.436 0.214 39 0.618 0.251 20 0.794 0.166 18  Eoderocerataceae M N S 0.184 0.131 96 0.07 0.214 0.165 71 0.01 0.240 0.169 117 0.001 0.308 0.169 26 0.003 0.350 0.166 36 0.008 0.588 0.150 7 Sig.  lildocerataceae M S N 0.306 0.133 152 0.09 0.312 0.151 22 0.12 0.324 0.163 127 0.03 0.442 0.215 75 0.13 0.457 0.182 131 0.001 0.651 0.165 27 Sig.  Sig. No No 0.001 0.2 0.001  77  Morphological Variation and Covariation  Hildocerataceae  tria n g u l a r ogival  P silocerataceae oval Eoderocerataceae  4.3.4  ellipsoid round e d qu a d r a te  Whorl Shape (1) Tuberculate shells are more depressed than nontuberculate shells.  Superfamily Tub\WWWH with without  Psilocerataceae M N sig. S 1.003 0.29 29 0.849 0.246 242 0.001  Eoderocerataceae M N Sig. S 1.125 0.309 226 0.954 0.303 136 0.001  Hildocerataceae M N S Sig. 0.816 0.17 60 0.742 0.203 355 0.004  1.2,/ 1.1 1 WWWH  0.9  • with B without  0.8 0.7 0.6 0.5Ud Psilocerataceae Eoderocerataceae Hildocerataceae with or without tubercles  (2) Conversely the frequency of shells without tubercles is higher in highly compressed forms (WWWH<0.7). Superfamily WWWH\F% WWWH>0.7 WWWH < 0.7  Psilocerataceae M N 89.74 302 94.93 79  Eoderocerataceae M N 36.34 322 66.66 60  Hildocerataceae M N 87.85 288 91.32 219  78  Morphological Variation and Covariation  100 ^ T ^ "  gsgsss  90 80 Nontuberculate  70  Frequency  60  D wwwhX).7  50 40 30  \AP s i l o c e r a t a c e a e  ^ l"l I Eoderocerataceae  H wwwh<0.7  Hildocerataceae  From (1) and Buckman's law, we can infer: (3) Frequency of shells without tubercles is greater in involute forms (V>0.5). Superfamily V\F% V<0.5 V>0.5  Psilocerataceae M N 88.81 286 96.84 95  Eoderocerataceae M N 39.76 337 45 51.11  Hildocerataceae M N 88.99 327 90 180  100 90 80 Nontuberculate  '"  Frequency  gO  DVO.5  a v>o.5  €5535  50 . 40  301^  j _  Psilocerataceae  Eoderocerataceae  Hildocerataceae  (2) and (3) are related by Buckman's law. It is an interesting question to find out which covariation predominates. Take a subsample of rapidly expanding forms (W>2.2) from superfamily Eoderocerataceae, calculate the average WWWH and V against tuberculation: Average Tub ere nontuberculate unituberculate bituberculate  M 0.438 0.282 0.522  V S 0.156 0.164 0.222  N 30 14 27  WWWH M S 0.778 0.241 0.970 0.237 1.114 0.241  N 28 18 27  Morphological Variation and Covariation  79  There is an increase in WWWH as the number of tubercles increases, whereas, a correlation is not evident for V. It seems WWWH is directly correlated with tuberculation, and V is more or less related to tuberculation through Buckman's law. (4) WWD increases if the shells are tuberculate. Superfamily TubYWWD with without  Psilocerataceae M N S Sig. 0.338 0.105 22 0.279 0.091 218 0.002  Eoderocerataceae M N SigS 0.370 0.118 213 0.311 0.081 127 0.001  Hildocerataceae M N Sig. S 0.296 0.072 59 0.281 0.065 321 0.05  WWD  •  with  H without Psilocerataceae  Eoderocerataceae  Hildocerataceae  with or without tubercles  From this covariation, we can infer: (5) Frequency of shells without tubercles increases if the fineness ratio of the shell is small (WWD<0.2). Superfamily WWD\F% WWD > 0.2 WWD < 0.2  Psilocerataceae M N 90.06 352 100 29  Eoderocerataceae M N 365 40.27 17 58.82  Hildocerataceae M N 88.93 488 100 19  Nontuberculate Frequency  • wwd >0.2 H wwd <0.2 Psilocerataceae Eoderocerataceae  Hildocerataceae  Morphological Variation and Covariation  80  (6) WWD decreases as shell diameter(D) increases. Superfamily D(cm)\WWD <3 3-6 6-9 9-15 >15  Psilocerataceae M S N 0.340 0.130 63 0.273 0.073 105 0.260 0.079 53 0.264 0.07 50 0.271 0.065 43  Eoderocerataceae M N S 0.378 0.104 121 0.001 0.348 0.102 184 0.12 0.318 0.109 105 0.299 0.127 56 No 0.269 0.078 20 No Sig.  Hildocerataceae N S Sig- M 0.326 0.086 90 0.006 0.293 0.069 202 0.009 0.267 0.044 136 0.13 0.253 0.055 85 0.14 0.241 0.048 29  Sig. 0.001 0.001 0.02 0.11  This covariation is most significant when shell diameter D is relatively small, which indicates significant change in WWD during the early stage of the growth. 4.3.5  Ribs (1) Simple primary ribs are coarser than primary ribs that furcate.  Superfamily Rib\RW simple furcated  Psilocerataceae M S N Sig0.179 0.059 300 0.105 0.042 34 0.001  Eoderocerataceae M N Sig. S 0.203 0.065 217 0.162 0.061 155 0.001  Hildocerataceae M S N Sig. 0.153 0.056 349 0.142 0.042 153 0.015  Morphological Variation and Covariation  81  RW  D simple • furcated 0.08  Psilocerataceae  Eoderocerataceae  Hildocerataceae  Rib Furcation  The reverse is also evident: (2) Frequency of shells with simple ribs increases if the shells are coarsely ribbed (Rib Width>0.22). Superfamily RW\F% RW < 0.22 RW > 0.22  Psilocerataceae N M 292 90.07 89 97.75  Eoderocerataceae M N 51.38 218 78.94 152  Hildocerataceae M N 428 72.43 81.81 77  •  RW<0.22  H RWX).22  Psilocerataceae  Eoderocerataceae  Hildocerataceae  (3) Frequency of shells with straight ribs increases if whorl shape is rounded. Superfamily Whorl Shape\F% others rounded  Psilocerataceae M N 53.36 298 59.52 84  Eoderocerataceae M N 83.16 297 93.10 87  Hildocerataceae M N 494 22.87 57.69 26  Morphological Variation and Covariation  82  100 90 80 70 60 50 .SZZL 40 . 30 . 20 10 . 0 \A Psilocerataceae Eoderocerataceae Hildocerataceae  Frequency of Straight Rib  • others • rounded  Whorl Shape  (4) Frequency of sparsely ribbed (PRHW<14) forms increases if the shells are depressed (WWWH>1.2). Superfamily WWWH\F% wwwh< 1.2 wwwh> 1.2  Psilocerataceae M N 30.82 318 46.15 26  Eoderocera1taceae M N 45.76 177 51 60.78  Hildocerataceae M N 12.95 363 66.66 6  70 60  • wwwh<1.2 H wwwh >1.2  50 Frequency of PRHW<14  40 3 0  Psilocerataceae Eoderocerataceae Hildocerataceae WWWH  4.3.6  Tuberculatum (1) Frequency of shells with tubercles increases if the whorl shape is quadrate.  Superfamily Whorl Shape\F% others quadrate  Psilocerataceae M N 4.64 345 61.11 36  Eoderocerataceae M N 61.39 303 78 83.54  Hildocerataceae M N 12.94 456 51 27.45  Morphological Variation and Covariation  Psilocerataceae  Eoderocerataceae  83  •  others  •  quadrate  Hildocerataceae  Whorl Shape  (2) Frequency of shells with tubercles increases if ribs furcate. Superfamily Rib\F% non-furcate furcate  Psilocerataceae M N 8.96 346 20 35  Eoderocerataceae M N 58.95 229 76.47 153  Hildocerataceae M N 356 4.49 37.74 151  • Frequency of Tuberculate Form  non-furcate  H furcate  Psilocerataceae Eoderocerataceae Hildocerataceae Ribs  (3) Frequency of shells without tubercles increases if ribs are weak. Superfamily Rib\F% med.-strong weak  Psilocerataceae M N 87.64 267 114 98.24  Eoderocerataceae M N 37.76 339 67.44 43  Hildocerataceae M N 313 85.62 194 95.36  84  Morphological Variation and Covariation  Frequency of Nontuberculate  Forms  100 90 80170 60 50 40 30 20 Psilocerataceae Eoderocerataceae Hildocerataceae  rfl  •  med.-strong  •  weak  Ribs  This positive correlation between tuberculation and rib strength may point to the importance of buoyancy control and shell building material supply during growth. Both tuberculate forms and strongly ribbed forms are concentrated in the low W and high U geometric region which provides high buoyancy and carbonate efficiency, whereas nontuberculate and weakly ribbed forms are concentrated more in the high W and low U region which has low buoyancy and carbonate efficiency. (4) Frequency of shells without tubercles increases if the ribs are projected. Superfamily  Psilocerataceae  Eoderocerataceae  Hildocerataceae  Rib\F%  M  N  M  N  M  N  others  87.89  289  34.53  333  89.20  500  projected  100  92  85.71  49  100  7  Frequency of Nontuberculate Forms  100 90180 70 60 50 40 30 20 l<d  z: •  others  •  projected  Psilocerataceae Eoderocerataceae Hildocerataceae Ribs  4.3.7  Venter (1) Frequency of shells with carinate venters increases if whorl shape is ogival.  Morphological Variation and Covariation Superfamily Whorl Shape\F% others ogival  Psilocerataceae M N 32.23 363 50 26  Eoderocerataceae M N 11.61 353 60.52 38  Hildocerataceae M N 62.72 405 89.13 138  z:  90 80 701. 60 Frequency of Carinate Venter  85  • others  50 40 30 20  H ogival  10 0l*4  Psilocerataceae Eoderocerataceae Hildocerataceae Whorl Shape  (2) Frequency of shells with carinate venter increases if the shells are highly compressed (WWWHO.6), or have small fineness ratios(WWD<0.25). Superfamily Whorl Shape\F% WWD > 0.25 WWD < 0.25 WWWH<0.6  Psilocerataceae M N 30.79 302 42.52 87 44.44 54  Eoderocerataceae M N 10.65 310 38.27 81 62.06 47  90 80|. 70 60 Frequency of Carinate Venter  50 40 30 20  10 0  Hildocerataceae M N 66.67 390 76.47 153 84.67 124  • wwd X5.25 M wwd <0.25 El wwwh <0.6  . • . .  Psilocerataceae Eoderocerataceae Hildocerataceae  (3) Frequency of shells with plain venters increases if the shells have high fineness ratios (WWD>0.5).  Morphological Variation and Covariation  Psilocerataceae N M 382 28.53 7 42.85 18 16.66  Superfamily Condition\F% WWD<0.5 WWD>0.5 WWWH>1.3  Eoderocerataceae M N 76.74 344 100 47 99.08 108  86  Hildocerataceae M N 530 2.80 37.5 8 50 6  100 80 Frequency of Plain Venter  • wwd <0.5 m wwd X).5 IS wwwh >1.3  60 40 20 0  Psilocerataceae Eoderocerataceae Hildocerataceae  One interesting point here is that depressed shells (WWWHM.3) do not show an increase in frequency of plain venters for all three superfamilies, whereas high fineness ratios do. It may be that WWD is directly correlated with ventral morphology, and WWWH is related through WWD. 4.3.8  Summary & Speculations It is generally agreed among ammonite workers that the shell of ammonite served two  prime functions: as a protection for the soft parts and as a hydrostatic device. Ornamentations such as ribs and tubercles were highly functional features of the shell, as is demonstrated by the common covariations documented above. Their significance has been thought of as (Kennedy and Cobban 1976): (1) Mechanical; (2) Protective, serving for both physical protection and as an aid to camouflage; (3) An aid to stability; (4) A means of regulating buoyancy; (5) A means of improving streamlining; (6) Sexually selected display features; (7) Sensory.  Morphological Variation and Covariation  87  The inter-relationships of shell expansion rate, degree of involution, whorl shape, ribs, tubercles, and venter have been studied using Amnion database. The major covariation patterns are: (a) The faster expanding shells tend to be more involute, the involute shells are more compressed than evolute shells, and the compressed shells have finer ribs. Possible interpretations for this covariation, also known as Buckman's Law, are the restrictions imposed by overlap ratio and relative area of the whorl (equations 1, 2 in section 4.2), buoyancy control and carbonate efficiency (Fig. 4-29). (b) Frequency of shells with tubercles increases if ribs furcate. Westermann (1978) suggested that a point of rib division would appear to be a mechanically good location for lateral tubercles which may exert localized stress on the shell, this would explain the repeated pattern of rib furcation and tuberculation during ontogeny that bundling ribs and prominent tubercles on the inner whorls fade to simple ribs at maturity when the wall has gained sufficient thickness. The division of ribs may also be due to the increase of circumference with increasing radius (Westermann 1978). (c) Tubercles of compressed shells tend to be on the lower flank whereas tubercles of depressed shells tend to be on the upper flank, which may be a reflection of Westermann's observation that tubercles are usually situated on the shoulders or the maximal whorl width which are often in the lower flank of compressed shells. This would also explain the fact that the frequency of shells with tubercles increases if whorl shape is quadrate. (d) Shells with sinuous ribs are more involute and more compressed than shells with straight ribs. (e) There is a positive correlation between tuberculation and rib strength which may point to the importance of buoyancy regulation and shell building material supply during growth. Both tuberculate forms and strong ribbed forms are concentrated on low W and high U geometric region which provides high buoyancy and carbonate efficiency whereas  Morphological Variation and Covariation  88  nontuberculate and weak ribbed forms are concentrated more on high W and low U region which has low buoyancy and carbonate efficiency; (f) As expected, the frequency of shells with a keels increases in shells that are compressed, or have a small fineness ratio. It should be noted that the observed covariation patterns may be unique to the data set used except for Buckman's Law which has been recognized in other ammonoid stocks. To be confident that these covariation patterns are due to functional rather than phylogenetic constraints would require examining earlier and later ammonoid records.  Morphological Variation and Covariation  4.4  89  Ontogenetic Variation  The geometric data used in the previous analyses were gathered from specimens with shell diameters larger than 4 cm to reduce the impact of ontogenetic variation. However, the problem of ontogenetic change cannot be ignored and an attempt is made here to describe such changes using measurements from different shell diameters for each species. The sample is restricted to species with at least 6 occurrences in the database and the shell diameters of the specimens have a large enough range to show ontogenetic variations, if present. Because the number of specimens for each species in the database is limited, they are not subdivided into groups based on geographic areas. This may blur true ontogenetic change or create false patterns if morphological variations for different geographic regions are large. The limitations of the data should be kept firmly in mind while interpreting the results of these inquires. 4.4.1  Umbilical Ratio (U) "Ontogenetic variations have been found in practically all ammonoid groups. In some  instances the ontogenetic change has the effect of making the shell more evolute but in the majority of cases the change is toward involute" (Raup 1967). This generalization is probably true for Paleozoic ammonoids, especially goniatites, but Lower Jurassic ammonite data show otherwise: 235 out of 670 species studied become more evolute during ontogeny, only 49 species tend to be more involute and the rest remain more or less constant. Ontogenetic change is determined by (1) visually examining the U-D plots like Fig. 4-31, 4-32; (2) computing the difference between the U value measured at the largest diameter of the species and the one at the smallest diameter. If it is larger than the within species mean standard deviation of U which is 0.043 in this data set, a significant change on U during ontogeny is inferred. The top ten species to undergo significant either increasing (+) or decreasing (-) ontogenetic change in U are: Fanninoceras carlottense (-) , Fanninoceras disciforme (-),  Morphological Variation and Covariation  90  Fanninoceras fannini (-), Hildoceras bifrons (+), Haugia jugosa (+), Psiloceras planorbis (+), Psiloceras johnstoni (+), Vermiceras scylla (+), Aveyroniceras acanthoides (+), Dubariceras silviesi (+). It is noteworthy that increase in U does not necessarily indicate less whorl overlap because it could also be the result of a reduction in shell expansion rate during ontogeny. This is common in the genus Vermiceras.  0.3  • 0.25 as  OH  • •  0.2  •  "(0  •  •^ 0.15 E  3  .  •  • • • • •  0.1  •  •  • •  •  0.05 0 _ 3  4  5  D - Shell Diameter (cm)  Figure 4-31  Plot of ontogenetic change in U for Fanninoceras fannini  0.6 0.5  8  I °-4  s  1  i  8  10  I 0.3 0.2 0.1  4  6 D - Shell Diameter (cm)  Figure 4-32  Plot of ontogenetic change in U for Dubariceras silviesi  12  91  Morphological Variation and Covariation  4.4.2  Shell Expansion Rate (W) Using the same method as described above, it was found that 181 out of 670 species  studied show an expansion rate decrease during ontogeny, only 40 species show increase and the majority remain more or less constant. The top ten species that undergo significant ontogenetic change on W are: Pleuroceras solare (-), Hammatoceras speciosum (-), Dubariceras silviesi (-), Phricodoceras taylori (+), Pseudogrammoceras muelleri (-), Arnioceras ceratitoides (-), Metaderoceras talkeetnaense (-), Vermiceras scylla (-), Vermiceras rursicostatum (-), Haugia variabilis (-). Fig. 4-33 shows that expansion rate decreases during ontogeny for Dubariceras silviesi and the negative correlation between U and W is evident by comparing Fig. 4.33 with Fig. 4-32. Fig. 4-34 shows that expansion rate increases during ontogeny for Phricodoceras taylori.  2.5 • CD  0£  c 1.5 CO CD  X 111  I  0.5  4  6  8  10  D - Shell Diameter (cm)  Figure 4-33  Plot of ontogenetic change in W for Dubariceraas silviesi  12  Morphological Variation and Covariation  92  3.5 3 ro 2.5  CC  c o  2  (0  cCD n X  1.5  111 1  5  1 0.5 0 0  2  4  6  8  10  12  14  D - Shell Diameter (cm)  Figure 4-34 4.4.3  Plot of ontogenetic change in W for Phricodoceras taylori  Ratio of Whorl Width to Whorl Height (WWWH) It is found that 224 out of 623 species studied become more compressed during  ontogeny, only 68 species become more depressed and the rest remain more or less constant. The top ten species in the database that undergo significant ontogenetic change in WWWH are: Amaltheus margaritatus (-), Androgynoceras maculatum (-), Aegoceras luridum (+), Dactylioceras anguinum (-), Phricodoceras urcuticum (-), Phricodoceras taylori (-), Prodactylioceras davoei (-), Coeloceras incertum (+), Phymatoceras rude (-), Phymatoceras tumefacta (-). Fig. 4-35 shows that Phricodoceras taylori becomes more compressed during ontogeny and the negative correlation between W and WWWH is evident by comparing Fig. 4.35 with Fig. 4-34. Fig. 4-36 shows that Aegoceras luridum becomes more depressed.  Morphological Variation and Covariation  1.2  •  <  •  93  •  1  • OR  •  i>  06 04 0?  n 6  8  10  12  14  D - Shell Diameter (cm)  Figure 4-35 Plot of ontogenetic change in whorl shape for Phricodoceras taylori  1.6 «>  1.4 >  1.2  ii  1 0.8 0.6 0.4 0.2 0 0.5  1.5  2  2.5  3  3.5  4.5  D - Shell Diameter (cm)  Figure 4-36 Plot of ontogenetic change in whorl shape for Aegoceras luridum  94  Morphological Variation and Covariation  4.4.4  Primary Rib Density (PRHW) It is found that primary rib density for virtually all species remains more or less  constant (61%) or increases (39%) during ontogey, none show significant decrease in primary rib density during ontogeny although the weakening of ornamentation is common. The top ten species that undergo significant significant ontogenetic change on primary rib density are: Amaltheus  conspectus,  algovianum, Harpoceras  Amaltheus  margaritatus,  Amaltheus  extremus,  chrysanthemum, Harpoceras falciferum,  Arieticeras  Protogrammoceras  praecurionii, Pseudolioceras lythense, Reynesoceras italicum, Schlotheimia angulata. Fig. 437 shows that the rib density of Amaltheus conspectus increases during ontogeny and Fig. 438 shows the rib density change for Arieticeras algovianum. 30 25  !L_  20 X  •  .  •  15  •  °10 5  0 J  |  I  0  2  4  Figure 4-37  |  I  6 8 D - Shell Diameter (cm)  |  |  10  12  14  Plot of ontogenetic change in PRHW for Amaltheus conspectus  Morphological Variation and Covariation  95  25  •  • 20  s  •  •  • II  16 •  X  •» • •  • •  • •  •  •  • •  •  °- 10  0  1  2  3  4  5  6  7  8  D - Shell Diameter (cm)  Figure 4-3 8 4.4.5  Plot of ontogenetic change in PRHW for Arieticeras algovianum  Superfamily The difference of parameter values on the largest and smallest specimens is used to  represent the degree of ontogenetic variation for each species with more than four specimens. Table 4-3 shows the average ontogenetic changes of species within superfamilies. the Psilocerataceae has the largest ontogenetic variation in U whereas the Eoderocerataceae shows greater ontogenetic variation in WWWH. Members of the Hildocerataceae are more likely to undergo ontogenetic change on W Table 4-3 Average ontogenetic changes of species within superfamilies Superfamily Psilocerataceae Eoderocerataceae Hildocerataceae  U 0.071 0.049 0.053  W 0.165 0.173 0.186  WWWH 0.128 0.205 0.135  Changes through Time  Chapter 5 5.1  96  Changes through Time  Introduction  Evolutionary change is not evenly distributed over time but is concentrated in episodes of evolutionary radiation as clearly indicated by the fossil record (Foote 1991). For ammonites the early Jurassic represents the most important episode because the ammonoid stem barely escaped extinction at the close of the Triassic (Donovan, Callomon and Howarth 1981). Yet, despite its significance, a limited number of approaches have been used to study this diversification, most notably the analysis of taxonomic data (Hallam 1987). The analysis of diversification by 'taxon counting' assumes either that morphologic diversity can be measured by taxonomic diversity or that the number of taxa reflects the number of objectively discernible morphotypes (Foote 1991). We know that taxonomic data and morphologic data do correlate, but taxonomic and morphologic approaches are not simply redundant (Foote 1991). If taxa are consistently defined, then taxonomic data can tell us about the number of biological units at a given time. But if we want to know the nature of these units, how they originate, how they evolve once established and how discrete they are from each other then morphological data are clearly necessary. "Since form represents the raw data of paleobiology, it is important to document significant events in the history of life from the standpoint of morphology" (Foote 1991). This study represents an attempt to analyze in detail the Lower Jurassic ammonite record, in terms of morphologic and taxonomic diversity and their relationship at 20 successive levels (zones) through an approximately 30-Ma interval (Harland et al. 1990).  97  Changes through Time Table 5-1 Series Middle Jurassic  Lower Jurassic zonal scheme for northwest Europe Age at base 179 Ma  Stage Aalenian  187 Ma  Toarcian  196 Ma  Pliensbachian  203 Ma  Sinemurian  208 Ma  Hettangian  Lower Jurassic  5.2  Zone Opalinum Levesquei Thouarsense Variabilis Bifrons Falciferum Tenuicostatum Spinatum Margaritatus Davoei Ibex Jamesoni Raricostatum Oxynotum Obtusum Turneri Semicostatum Bucklandi Angulata Liasicus Planorbis  Stratigraphic Division  The traditional stratigraphic division of the Lower Jurassic into 4 stages and 20 primary standard zones is adopted here with the age at the base of each stage taken from Harland et al. (1990)(Table5-l).  5.3  Choice of Characters  I have attempted to represent ammonite morphologic diversity in terms of basic shell geometry and ornamentation, which are the major describable morphological characters for species identification. Basic shell geometry includes parameters: W, U, WWWH; as well as  Changes through Time  98  venter for each species. Ornamentation includes PFORM (primary rib form), PRHW (primary rib density), FURC (a combination of pattern and position of rib furcation), and tuberculation (a combination of pattern and position of tubercles). All parameters are defined in Chapter 2. Aperture shape is not included in this study due to limited data available. This study is restricted to external morphology rather than internal characters, such as the septal suture. In strong contrast to earlier systems, the septal sutures of Jurassic ammonites are seldom useful for defining major groups and are hardly ever employed at lower levels of classification (Donovan, Callomon and Howarth 1981). The data used in this study comprise observations made on 6784 specimens, representing 15 families, 179 genera, and 1319 species. This comprises virtually complete coverage of the ammonite genera known to occur in the Lower Jurassic as catalogued by Donovan, Callomon and Howarth (1981).  5.4  Geometry through Time  It is tempting to search the biometrical data for evidence of correlation between geometry and stratigraphic time. W-U plots have been made for the four stages. A bimodal distribution characterizes the Hettangian (Fig. 5-1), with one peak corresponding to evolute and slowly expanding forms, and another peak corresponding to moderately involute forms. Sinemurian ammonites fully explored the region of the first peak (Fig. 5-2) but the W-U distribution for the Pliensbachian concentrates on the second more involute peak (Fig. 5-3), a trend that continues for the Toarcian (Fig. 5-4).  99  Changes through Time 1.20  1.40  1.59  1.79  1.99  2.77 2.97 3.16  3.36 3.56 3.75  3.95  1.20  1.40  1.59  1.79  1.99 2.18 2.38 2.58 2.77 2.97 3.16  3.36 3.56 3.75  3.95  Figure 5-1  2.18  2.38  2.58  w Density diagram for Hettangian ammonites (101 species)  1.20  1.40  1.59  1.79  1.99  2.18  2.38  2.58  2.77 2.97 3.16  3.36 3.56  1.20  1.40  1.59  1.79  1.99  2.18 2.38 2.58 2.77 2.97 3.16 3.36 3.56 3.75 3.95  W  Figure 5-2  Density diagram for Sinemurian ammonites (366 species)  3.75  3.95  Changes through Time  100  1993). I will use as a starting point the sum of the morphological range as a measure of morphological diversity. Figure 5-7A shows the morphological diversity for each of the 20 successive zones using the four basic characters of shell geometry. Each bar in the graph represents a zone and each shaded portion represents the morphological diversity for a character with all characters having the same weight. Figure 5-8A adds ornamentation to the four shell geometry characters. In Chapter 4, I demonstrated that covariation is widespread in ammonites and covariation will introduce a certain amount of redundancy into the measures of morphologic diversity, as is evident in Table 5-2. The shaded boxes in Table 5-2 indicate pairs of characters with correlation coefficients greater than 0.5. the most significant correlation occurs among the three parameters describing rib density, form and furcation (coefficient > 0.8) which are therefore combined (averaged) into one parameter (RIB) for this study. The covariations among W, U, and WWWH demonstrated by Eqs (1) and (2) in section 4.2 are also evident here. As can be expected, there is a significant correlation between ornamentation and whorl shape, and a correlation between rib furcation and tuberculation. To eliminate the redundancy caused by covariations, a multiple linear regression was performed for each parameter using the rest of the parameters. The ratio of residual to total variance which indicates the degree of independence of each parameter with respect to the rest (Table 5-3) can then be used as a weight in the summing up of the MRDI values for each zone as shown in Fig.5-7B, 5-8B. Table 5-2  MRDI correlation matrix (Shaded values have correlation coefficients > 0.5) W  U WWWH VENTER  w u  0^635982  1  WWWH  0 559241  0.6933  PRHW PFORM  FURC TUBERC  1 1  VENTER 0.066713 0.421967 0.252447  1  PRHW  0.096465 0.208958 0.565855 0.156352  1  PFORM  0.365184 0.326135 0.601697  FURC  0.203162 0.387015 0641858 0.257381 0.922446 0.842275  0.19651 0.841871  1 1  TUBERC 0.440936 0.366407 0.492782 0.119988 0.34703 0.521663 0.539111  1  Changes through Time 5.5  101  Taxonomic Diversity  Ammonites have served as classic examples of biostratigraphic index fossils. Their fossil record is exceedingly rich and their taxonomy is mature in the sense that it no longer shows an exponential increase in description of new taxa each year (rather, the reverse is happening) which makes them well suited for taxa counting (Ward 1983). The data sets become more comprehensive moving up the taxonomic and stratigraphic hierarchy as sampling failure becomes less likely. Even so, there is no reason to assume any non-random bias in sampling even down to the level of species and zones, so that the data can be confidently used to assess relative, if not absolute, changes in diversity and turnover through time. The method of taxonomic diversity analysis adopted here is similar to that presented for a number of invertebrate groups in the Lower Jurassic of northwest Europe by Hallam (1987). The diversity graphs are simple plots of numbers of taxa for each successive zone; the graphs of times of family first and last appearances are self explanatory. The major difference is my greatly expanded database which enables me to work at the species as well as the generic level. As illustrated in Fig. 5-5A, species diversity shows a slow increase from the oldest Planorbis Zone to the Bucklandi Zone, followed by a slight decline to the Turneri Zone, and rapid rise to a middle Pliensbachian maximum followed by a spectacular crash through the Tenuicostatum Zone to a Falciferum Zone minimum. Thereafter there is a further rise to the Bifrons Zone to match Sinemurian but not Pliensbachian levels followed by a decline to the Thouarsense Zone and a final rise to the Levesquei Zone. It is evident from Fig. 5-5B,C that diversity curves for genera and families closely resemble the one for species. The overall similarity among the three diversity curves suggests that they reflect a common underlying pattern which supports the general claim made by Bambach and Sepkoski (1992) that largescale spatial and temporal diversity patterns at the level of species, genus, and family are well correlated. It is interesting to note that diversity peaks first at the family level in the Ibex  Planorbis  Angulata  Semicostatum  Obtusum  Raricostatum  Ibex  Margaritatus  Tenuicostatum  Bifrons  Thouarsense  H  IT"  t±1  zf  1  I  1  n_  50  \ = ^—^-  '  |  zC  1  J  1  1 —  -  1  150  . 1  1  1  200  10  —i  1  20 Number of genera  JL.  ^T  1  30  ^  Number of families  1  10  1  5  ^  ^  Number of families making their first appearance  102  Figure 5-5 Lower Jurassic Ammonite Taxonomic Diversity Changes through Time  Number of species  100  1  " 1  i  Number of families making their last appearance  103  Changes through Time  A  Figure 5-6  B  C  Diversity of Lower Jurassic ammonite (A), bivalve (B), and  brachiopod (C) diversity. Number of genera for ammonites, number of species for the  rest (Hallam 1987).  Zone, followed by generic data one zone later, and finally species which implies significant delay in radiation for lower levels of ammonite taxa. The observed genus diversity change pattern is in general agreement with the one shown for ammonite genera (Fig. 5-6A) by Hallam (1987) where there is a more or less steady rise in diversity from a very low level in the early Hettangian through to the Pliensbachian followed by a marked decline into the early Toarcian after which it tends once more to increase. The major difference between the two is that ammonite genera reach their highest diversity level in the Pliensbachian instead of the middle Toarcian in my data set. My ammonite species diversity peak coincides with Hallam's bivalve and brachiopod diversity peaks of the late Pliensbachian (Fig. 5-6B, C). Fig. 5-5 D, E shows the Oxynotum Zone has the highest family origination rate and one of the lowest species diversity. The late Sinemurian and early Pliensbachian also have high family origination rates and relatively low species diversities; species reach their highest diversity  Changes through Time  104  level in the late Pliensbachian which happens to have the highest family extinction rate and an almost zero origination rate. Raup and Sepkoski (1986) identified the Pliensbachian as a time of mass extinction at the family level that was part of a 26 Ma periodic series. The average ammonite family extinction rate for the Upper Pliensbachian is 50% which is significantly higher than 7% — the average for the rest of Lower Jurassic zones (Fig. 5-5). The claim of periodic extinction has provoked speculation about an ultimate cause, such as sea level changes (Hallam 1987), climatic shifts, volcanic eruptions (Officer et al. 1987) or extraterrestrial events (Raup 1986). A central issue has been how rapidly the extinction occurred. It is evident from Fig. 5-5C, E that the Pliensbachian extinction event was gradual for ammonites at the family level, it started at Davoei Zone with a family extinction rate of 22% and followed by high extinction rate of 50% in the Margaritatus Zone and the Spinatum Zone.  5.6 5.6.1  Morphological Diversity  Morphological Range Diversity Index (MRDI) The variance seems to be a good choice to represent morphological diversity but  unfortunately, most paleobiological data sets include both quantitative and qualitative data and there is no meaningful distance measurement between nominal data, such as the pattern of ribs. As a result, the range of forms is generally accepted as a measure of morphological diversity. For qualitative data, the MRDI is the percentage of occupied character states. For quantitative data, MRDI is the difference between the maximum and minimum of the morphologic characters with normalization so that the MRDI value always falls between 0 and 1. Van Vale (1974) discusses the multivariate generalization of the univariate range, suggesting two measures: the sum of the univariate range of morphological variables and the product of univariate ranges. The latter represents the volume of morphospace occupied, but this quantity vanishes or nearly vanishes if any of the ranges is zero or nearly zero (Foote 1993). I will use as a starting point the sum of the morphological range as a measure of  Changes through Time  105  morphological diversity. Figure 5-7A shows the morphological diversity for each of the 20 successive zones using the four basic characters of shell geometry. Each bar in the graph represents a zone and each shaded portion represents the morphological diversity for a character with all characters having the same weight. Figure 5-8A adds ornamentation to the four shell geometry characters. In Chapter 4,1 demonstrated that covariation is widespread in ammonites and covariation will introduce a certain amount of redundancy into the measures of morphologic diversity, as is evident in Table 5-2. The shaded boxes in Table 5-2 indicate pairs of characters with correlation coefficients greater than 0.5. the most significant correlation occurs among the three parameters describing rib density, form and furcation (coefficient > 0.8) which are therefore combined (averaged) into one parameter (RIB) for this study. The covariations among W, U, and WWWH demonstrated by Eqs (1) and (2) in section 4.2 are also evident here. As can be expected, there is a significant correlation between ornamentation and whorl shape, and a correlation between rib furcation and tuberculation. To eliminate the redundancy caused by covariations, a multiple linear regression was performed for each parameter using the rest of the parameters. The ratio of residual to total variance which indicates the degree of independence of each parameter with respect to the rest (Table 5-3) can then be used as a weight in the summing up of the MRDI values for each zone as shown in Fig.5-7B, 5-8B. Table 5-2  MRDI correlation matrix (Shaded values have correlation coefficients > 0.5) WWW  w u  0.63598  WWWH  VENTE  PRH  0.55924  0.693  VENTER 0.06671  0.42196  0.25244  PRHW  0.09646  0.20895  0.56585  0.15635  PFORM  0.36518  0.32613  0.60169  0.1965  0 84187  FURC  0.20316  0.38701  0.64185  0.25738  $92244  TUBERC 0.44093  0.36640  0.49278  0.11998  0.3470  PFOR  FUR  0.84227 0 52166 0.53911  TUBER  SI  9  o a  1  2  2.5  All characters with equal weight  1.5  3  The weight for each character is based on its degree independence (Table 5-3)  106  Figure 5-7 The Accumulation of Morphological Range Diversity Index for Basic Shell Geometry  0.5  pianorb  Mgulata  tm  ta  5  0  0  em  S  Obtusum  ex  Ib  s  garitatu  um  TenUI0stat  BfrorS  n  Ihouarse  jgUrC  0  2  4 0 ia ra° With eqUa’  1  5  o.5  1  1.5  2 nitS degree 0t I depefld gable 5-3) The weight for each charactet is based 0 e  0  B  107  f orphob 5-8 The Accumulation 0 0I’ gaUge DiVersitY Index for All ?aramets  1  A  SW  WWM  0 V entet  •Ri1  108  Changes through Time Table 5-3  Measure of independence--residuals from multiple linear regression  Sum of Squares  W  U  WWW  VENTER  RIB  TUBERC  Total  0.320  0.189  0.731  0.121  0.512  0.341  Residual  0.197  0.050  0.278  0.231  0.174  0.124  Ratio %  38.10  20.92  27.55  65.62  25.36  26.66  The diversity of basic shell geometry (Fig. 5-7B) shows a rapid rise to an early Sinemurian maximum through morphological radiation, followed by a pronounced fall in the middle Sinemurian. Thereafter morphological diversity remains high and is stable apart from two modest troughs, one in the Falciferum Zone (which, incidentally, correlates with the early Toarcian anoxic event in northwest Europe) and another in the Thouarsense Zone. Fig. 5-8B shows a similar general pattern except that the Pliensbachian and Toarcian ammonites have significantly higher ornamentation diversities than those of the Hettangian and Sinemurian. 5.6.2  Shannon Diversity Index (SDI) The measure of information proposed by Shannon (1948) is the bit. Thus, if we have a  device such as a switch, which has two stable positions, on or off, then it can store 1 bit of information 2 1og  =  1.0 bit  There is a close relationship between information and uncertainty, so the more uncertain an answer is, then the more information is passed when the answer is given. If there are number of alternatives, then the amount of information is maximized when each is equally likely to occur. If we consider a system with N alternatives, and the probabilities of each alternative is given by Pi’ P2’  P3’  P  then the information H is given by og 2 l H=-Zp 1 p  i1,2  ,n  Changes through Time  109  H is the entropy of the system. If we consider the case of two alternatives, each being equally likely, then Pl=P2  = 0 5  -  H = -0.5 log20.5 - 0.5 log20.5 = 1.0 if/?, = 1 mdp2 = 0 (or vice versa), then H=0. Thus H is maximized when/?/ = p2 = ••• = pn and H is equal to log2 n, the ratio -Lpt\og2Pi I log 2 n  i = 1,2, .... ,n  is known as the relative entropy (RE) (Shannon 1948), and can be used as an alternative to the morphological diversity range index. RE describes not only the range of the morph space occupied, but also the evenness of the occupation. For qualitative morphological characters (VENTER, FURC, TUBERC) the Shannon diversity index (SDI) is defined as SDi = -z/;iog„y; i = i,2,....,n n — number of the states for the character fj — frequency of the state i For quantitative morphological characters (W, U, WWWH, DMAX), there are no natural division of states, therefore each character is divided into n evenly spaced intervals. If n is equal to one, the whole character range is considered as one state and the SDI is equal to zero. As n increases, the SDI gradually rises to approach the true diversity of the character. Experiment shows that the SDI starts to stabilize when n is bigger than one fifth of the sample size if the sample size is not too small (>40), and this value is subjectively adopted here. This is not critical since the current study is not meant to estimate the absolute morphological diversity of ammonite species that occurs in each zone, but to assess the relative changes.  The change in diversity shown in Figs. 5-9 and 5-10 is in general  agreement with the pattern observed in Figs. 5-7 and 5-8. There is a rapid rise to an early Sinemurian maximum through morphological radiation, followed by a pronounced fall in the middle Sinemurian with diversity remaining relatively high and stable thereafter. This temporal pattern is also reflected in Fig. 5-11 where the first ammonite superfamily in the Early Jurassic — the Psiloceratacea.  o SI  1  2  2.5  All characters with equal weight  1.5  3  3.5  0.2  0.4  0.6  0.8  110  1  1.2  1.4 The weight for each character is based on its degree of independence (Table 5-4)  0  Figure 5-9 The Accumulation of Morphological Shannon Diversity Index for Basic Shell Geometry  0.5  • Venter • WWWH IU IW  2 All characters with equal weight  3  4  0.5  1  111  1.5  2  The weight for each character is based on its degree of independence (Table 4-6)  0  Figure 5-10 The Accumulation of Morphological Shannon Diversity Index for AH Characters  1  IW  • U  OWWWH  D Venter  •Rib  ITuberc  i \  1  ,  \  \  /  3  \  /  \  All characters with equal weight  2  •  4  ^  J! 5  0.5  \  \  /  1  112  ^  •  /  ^ ^ 5 =^  /  B  1.5  2  The weight for each character is based on its degree of independence (Table 4-6)  0  \ \  i^i^l^i^H  Figure 5-11 The Accumulation of Morphological Shannon Diversity Index by Superfamily  0  Psilocerataceae 1  ^5—  Eoderocerataceae 1  ^  Hildocerataceae 1  A  •w  •U  DWWWH  D Venter  BRib  •Tuberc  113  Changes through Time Table 5-4  Residuals from multiple linear regressions of SDI  Sum of Squares  W  U  WWW  VENTER  RIB  TUBERC  Total  0.108  0.093  0.309  0.397  0.056  0.346  Residual  0.029  0.051  0.131  0.286  0.014  0.137  Ratio %  21.16  35.41  29.77  41.87  20  28.36  shows the greatest morphological diversity, followed by the morphologically more restricted Eoderocerataceae, and a diversity rebound with the Hildocerataceae.  5.7  Discrepancies between Morphological and Taxonomic Diversity  It is evident by comparing Fig. 5-5 with Figs. 5-8 and 5-10 that initial morphological diversification in Lower Jurassic ammonites far exceeded the proliferation of lower-level taxa. Such a pattern suggests that morphological transitions were larger earlier in this clade's history, a point that is relevant to the ecological and evolutionary mechanisms of diversification (Stanley 1979; Foote 1992, 1993). A similar pattern has been discussed for echinoderms (Foote 1992; Sprinkle 1980), and stenolaemate bryozoans (Anstey and Pachut 1992). The most striking fact emerging from the comparison is that the morphological diversity of the Bucklandi Zone with 46 species is higher than that of the Margaritatus Zone with 177 species which demonstrates morphological diversity need not increase as taxonomic diversity increases. Such morphological stagnation indicates taxonomic diversification that is highly constrained morphologically (Foote 1993). Two patterns are seen during the decline of taxonomic diversity: (1) from the Spinatum Zone through the Tenuicostatum Zone to the Falciferum Zone, the number of species drops to 49 from a high level of 161, whereas the morphological diversity remains relatively stable suggesting that the extinct species are randomly distributed with respect to morphology; (2) from the Bucklandi Zone through the Semicostatum Zone to the Turneri Zone, morphological diversity decreases along with  Changes through Time  114  taxonomic diversity which may imply selective extinction in certain regions of the morphospace, but could also be due to the very low level of species diversity in the Turneri Zone.  5.8  Other interesting observations  Table 5-5 shows that all families that radiate into numerous species (>13) in the first zone of their occurrence have durations of less than 4 zones, which may imply that evolution rates associated with these families are high. In other words, rapid origination is associated with short duration, although the time resolution of my data does not warrant a firm conclusion. Fig. 5-12 shows the average shell diameter changes for Lower Jurassic ammonite superfamilies through 20 successive zones. The basic calculation unit is species and the maximum shell diameter achieved for the species is used to compute the average for the superfamily. The rationale for using maximum instead of average shell diameter for species is to eliminate juvenile and immature forms from the calculation whenever possible. The average maximum diameter curves for the three superfamilies are more or less parallel. Most noticeably, the diameter curves show a synchronized drop from the Obtusum Zone to the Oxynotum Zone, followed by a parallel rise in the Raricostatum Zone. Furthermore, the mean maximum diameters for all three superfamilies decrease from the Jamesoni Zone to the Ibex Zone. It is possible that the observed parallelism among the average diameters for the three superfamilies is a coincidence which may disappear at the family level. However, Fig. 5-13 presents a similar pattern with the diameter curves showing a pronounced trough in the Oxynotum Zone, and six out of eight families showing a significant decrease in shell diameter in the Ibex Zone. Interestingly, these two zones show high family origination rates, relatively low species diversity (Fig. 5-5A, D) and are times of regression (Hallam 1988). This may imply r selection whereby times of regression cause a deterioration of the environment, increasing the stress on organisms and promoting the origination of high-level  Changes through Time  115  taxa which radiate at lower taxonomic levels during sea level rise. "The new taxa evolving at times of low sea-level stand are often smaller than their ancestors, and increase in size phyletically during the subsequent, environmentally less stressful times of high sea-level stand" (Hallam 1987). Another possible explanation for the observed correlation is that it is an artifact of preservation bias but my data do not contain information on facies and so cannot address this problem.  116  Zone\Family Psi Sch Oxy Cym Ech Ari Ama Coe Dae Eod Lip Phr Pol Hil Phy Levesquei 40 13 Thouarsense 23 5 Variabilis 10 14 33 Bifrons 38 43 7 Falcifer 12 37 Tenuicostatum 30 72 Spinatum 5 114 19 23 /h 1 Margaritatus 12 2 2 2 6 126 Davoei 2 41 7 10 15 8 29 3 6 Ibex 1 1 7 7 74 2 33 7 9 Jamesoni 12 18 12 1 17 53 Raricostatum 2 11 38 4 16 3 Oxynotum 4 11 14 2 1 5 Obtusum 1 2 18 5 Turneri 4 1 17 Semicostatum 2 1 28 Bucklandi 1 7 11 27 Angulata 14 8 8 Liasicus 12 12 5 Planorbis 30  Table 5-5 Number of species in each zone for Lower Jurassic ammonite families  > <  a u  0>  I  s  10  12  14  yT  —  !  1  m  3  1 1 i ! t 1 ! 1 1 1 1 1 1  I  1  1 i 1 1  r  r  t/3  I  1 1 i l i 1 1 1 11 1 1 1  1  |  1 i 1 1-  t?  1 1 i l i 1 1 1 \ 1 1 1 1  1  |  1 i 1 1  i  '  i ' i i ' 1  X \  1  O  X  c  Io  T / \ 1/ \ i / Xi W t 1 1 | 1 1 1 1  X  /  /  X ' / /  • Psilocerataceae  O  3  s  1 1 i 1 i I 1 1 | 1 1 1 1  '  '\ 1  1  B  1 i I I 1 1 1 1 1 1 1 1  '  i \ ' \ i \ i \ ' \ 1 \ '  T i ' i i ' 1  c o  \  '  '  I  I X. 1 x . 1 ^^"^ WT I 1 1 1 -|1 1 1 1  \  Zone  i \ 1 i I I 1 1 1 1 ! 1 1 i  '  '  *\ ' \ i\ i \ ' \ ' 1 - \ — -t-  ^  r  i  i ' i i ' 1  j  i  - Hildocerataceae  I  1  1  1  '  ' i '  i  i ' i i '  ^00- M ^-**^'^ 1 i _J^*-^*W i 1 1 1 1 1 1 1 I  1  ^ X T \L mr I 1 1 1 1 1 1 1  '  'S  \  ^  Q  \  '  ' i '  i  i ' i i '  g  r  o  i B i 1 I I 1 1 -1 1 1 1 1  M \  M  ' i X ' \ ^  • Eoderocerataceae  ^ r W^ /i /^ /T^v / /l >v / / ' >^  i  V X ' / / ' • X t / / i "\ \ ' / / ' r - X — V — i - -j ~j—i  i ^s"^« i i -.*^'^v s St i ^j*000^ 'X^s. i B^ i \ x ^ i ' \ A 1 1 \ 1\ ' \ ' \  T  / / / 1— /  1  I  i 1 1 1 1 1 1 1 1  i  B  1 /  ' / '  ' i '  i  i ' i i '  i  1  "3  o  1 i 1 i I 1 1 1 1 1 1 1  ' i ' 1  i ' i i ' • / T V  i  117  Figure 5-12 Average Shell Diameter Change for Lower Jurassic Ammonite Superfamihes  3  3  1 1 i i i I 1 1 1 1 1 1 1  1  1 1 i l i 1 1 1 | 1 1 1 1  |  l/ ^i W 1  |  1 i jto - ^ ^  i /1 i / i i t i i / i i / i 1 / 1 ' /  i i i i i 1 '  i  i  i  1  s  c o  1 i 1 i I 1 1 -t 1 1 1 1  '  +  1 W i '  i ' i i '  T  y  /  >  1  1  1 i 1 i I 1 1 -1 1 1 1 1  ^  1 i '  73 Xl C3  t  l  i  r  i  1  O  1 3  e  i 1 I 1 1 1 1 i 1  1 i  '  1 i '  i i _M l ^0*-***>\. J^"^ i  I  i i '  l  r  i  l  X.  l I 1 I 1 1 1 1 1  > u  tZ)  a-  3  1  '  1 l 1 i  '  ^^ W '  i ' i i I  i  Average Diameter (cm)  N o CD  An Aid to Identification  Chapter 6 6.1  119  An Aid to Identification  Introduction  Identifying ammonite species requires the recognition of associations of ammonite shell morphologies which can be demonstrated to maintain their superpositional relationships throughout their entire geographic distribution. Each species shows variation within the population and also during ontogeny, variation which must be determined before a species can be identified with confidence. Traditionally intraspecific variation is determined by examining the illustrations and descriptions of the specimens of the taxon under consideration which means scouring a voluminous literature that is in many different languages and often reaches back well into the last century (Smith 1986). In order to effectively utilize the literature, the attributes of a large number of specimens have to be memorized and evaluated in an objective manner. Direct comparison of two specimens is relatively easy but the problem increases rapidly as more specimens are involved. To a large extent the image database Ammon can overcome these problems. The basic idea is that given information supplied by the user, a search of Ammon is made and closely matching species are displayed on the screen for visual comparison with the specimen in question. If the candidate list is large, both the rough stratigraphic range and geographic locality of the specimen can be used to narrow the search. Searches can also be restricted to a certain diameter range to circumvent the problem of ontogenetic variation.  SDeci Sub ist  Main List  Brightness:  Goto Specimen  Previous Pacie  Some Utility:  Combination  Reference =>  Moroholociv =>  Stratiaraohv =:  Taxonomv =>  Retrieve by:  amnion Image Database  Figure 6-1  The start-up screen of the database Amnion  1. Taxonomy: Family, Genus, and Species. 2. Stratigraphy: Stage and Standard Zone. 3. Geography: Geographic Area and Country. 4. Morphology: Volution. Expansion Rate, Whorl Shape. Ribs, Tubercles. 5. Reference: in which the figure of the specimen appears. You can also retrieve by combining the above criteria.  You can retrieve Jurassic ammonites by:  WELCOME TO JURASSIC AMMONITE IMAGE DATABASE  Display Image Window  121  An Aid to Identification 6.2  User Interface  Ammon has an easy to use, menu-driven user interface which is written in Sunview and the embedded SQL query language of Oracle RDBMS. Fig. 6-1 shows the start-up screen which consists of three windows: the upper-right window displays a welcome message and explains what user can do with the system, the lower-right is a graphics window showing the lateral and frontal views of a Lower Jurassic ammonite specimen and the left window hosts available command buttons, menu-buttons  and  sliders. Users can retrieve Jurassic (mainly Lower  Arietitidae Ecfiioceratldae Oxynoticeratidae  t  Cymbitidae  Jurassic) ammonites by Taxonomy, Stratigraphy,  Eoderoceratldae  Geography, Morphology, Reference or various  C  Combinations:  ^Mffif hitidae Llparoceratidae  1. Taxonomy  f  i  Amaltheidae  When the Taxonomy is pressed with the right mouse button in the left window, a pull-right menu appears which shows the available ammonoid families in the database (Fig. 6-2). If, for example, the  user  selects  the  ammonite  family  Dactylioceratidae by highlighting it and releasing the mouse button, all specimens of the family in the  Phymatoceratldae  < \ Collina  Graphoceratidae Sonninlldae  f j Dactytoceras r Nodlcoeloceras  Cardioceratidae  i  Erycitidae  f  family menu has a pull-right menu such that if the  Kosmoceratidae Otoltidae  t  Sphaeroceratidae  r  Stephanoceratidae  t  genus list for the family would appear (Fig. 6-2).  Re  ynesoceras  • Zygodactylies  Reineckelidae l  Phylloceratidae r  Lytoceratidae •  Suppose that  Prodactyiioceras  Perisphinctidae Discophyllitidae  user pulls right from the item Dactylioceratidae, a  Porpoceras Preperonoceras  Oppeliidae  database will be retrieved. Each item itself in the  Peronoceras  —  —  M  Dactylioceras is selected, then the Figure 6-2 Family Menu (Left) Genus submenu of Dactylioceratidae screen shown in  Amnion Image Database  Figure 6-3  The retrieval results of Dactylioceras  Display Image Window  An Aid to Identification  123  Fig. 6-3 would be the query result. The top-right  ESI : E  window records the query text and gives the number  ; Bajocian : Aalenian  r r-  Toarcian  r  Pliensbachian  r  Sinemunan  r  of images retrieved and the number remained to display. Images are displayed in order of size for efficient utilization of the screen space and the user  H6ttangian  ESI NKJ  Spinatum r- N< Davoef  can go to next screen of images by pressing the Next  Ibex  Page with the left mouse button and back to previous  Jamesoni  screen by pressing the Previous Page button. A user Figure 6-4 interested in a specific specimen can click on the  Stage Menu (Left)  Zone Submenu of Pliensbachian  image with the left mouse button which will display all information related to the specimen in the middle-  Cn yn?ry  I , Country I  right text window (Fig. 6-3). A user interested in the species to which the specimen belongs and wants to  3ritain  nada  examine the intraspecific variation can mark the  tile  specimen with the middle mouse button and click on  lina Ecuador  the Speci Sublist (Fig. 6-3). The user can return to  linCS::;: Jermany  the genus level by clicking on the Main List button.  jreece  Exercises such as this enable the user to get familiar  «|ngary Ireland  with a particular taxonomic group very quickly. 2. Stratigraphy  Japan Madagascar  The Stratigraphy button has a two-level  rfexico  menu. The top level is the stage menu (Fig. 6-4)  3  which lists the four Lower Jurassic stages and two of  ortugal  lussia  mSaudi Arabia  the Middle Jurassic stages. Each stage has a pull-  Switzerland Jriited States  right menu which shows the zones (northwest Europe scheme) in the stage. The user can scan the Figure 6-5  Country Menu  An Aid to Identification  124  falcoid falcate biconcave projected  Figure 6-6  Morphology Menu (Left), Rib Submenu  (Middle) and Rib Form Sub-submenu (Right) database by zone and get some idea of how ammonite morphology changes through time. 3. Geography The user can explore morphological and temporal changes of ammonite taxa in different parts of the world by using Geography as query criterion, he or she can retrieve ammonites by geographic region or country (Fig. 6-5). There are five geographic regions: Northwest Europe, Western Tethyan, Western Pacific, North America and South America each of which has thousands of specimens in the database and could easily overwhelm the user. Geographic regions are most commonly used with other criteria to narrow a search. 4. Morphology Morphology is one of the two foundations for fossil identification. The user can also search the database using morphological characters such as the degree of involution, shell expansion rate, rib form & furcation pattern, tubercle pattern, whorl shape and ventral geometry (Fig. 6-6). If the images displayed in the graphics window are fuzzy or do not have  An Aid to Identification  Reference  125  § 9 Reference • : • • • • :  ArkeilEtc 1957 Atlas Ed. ByRepin 1968  .  •  :••  • • : •  Hi ••.  •  : • . • : • : • : • : • : • : • : • : • : • • • • • • .  • • • • : • • : • • : • . • •  .  .  Arthur 1985 8iascoT978  Crickmay  \ Dagis  Dean, Donovan, Howarth 1961  ; Erben1956  Freboid  .  Freboid and Mountjoy etc 1967  Gabb1869  iGabilly 1976  Geczy 1976  | Geyer  lillex  I Hall 1987  Hall and Westerman 1980  j Half and Howarth 1983  Hlllebrandt  ! Hirano  imlay 1968  Imlay 1981  Jakobs1992  i Kalacheva 1980  Mclearn 1932  I Meister 1986  dferien 1985  I Palfy 1991  Poulton ;  | Poulton And TipperT991  Quinzio Sinn 1987  I Repin 1974  Schlatter 1991  | Schiegelmilch 1976  Smith 1976 ••  i Smith 1981  Smith and Tipper  ! Stankevich1964  Taylor 1988  ! Thomson And Smith 1992  Tilmann 1917  j Tipper and Smith etc 1991  Wang and Smith 1986  j White 1889  Whiteaves 1884  : Wiedenmayer 1977  Wiedenmayer 1980  : Others  Figure 6-7  Reference Menu  the right brightness, the user can adjust them using the Brightness and Contrast sliders in the command window. 5. Reference A user interested in a specific person's work can query the database by Reference (Fig. 6-7) which has a two-column author menu with authors arranged in alphabetic order and the list will grow as new references are added to Ammon. 6. Combination  An Aid to Identification  126  The Taxonomy, Stratigraphy, Geography, Morphology and Reference menu system offers the user easy access to the database but at the same time reduces flexibility because the user can only search the database in one area of inquiring at a time and the file that lists all menu items needs to be updated whenever new character states are added. For any serious application, a combination of the above search criteria is needed as provided by the Combination button in the command window (Fig. 6-3). Suppose that the illustrations in the start-up screen are of interest and the user wants to know the species name and the locality where the specimen was collected. The user composes a query using the morphological features available from the image: a carinate venter, 13 ribs per half whorl at a shell diameter of 12 cm, the average trend of ribs is gently rursiradiate, no tubercles. Taking into account measurement error, the query is typed into the search field in the top-right text window as : venter=carinate and prhw>10 and prhw<16 and d>10 and d<14 and ptrend=grursiradiate and tuberc=no  and the Combination button pressed to search the database. The response to the query (Fig. 6-8) shows the specimen that appears in the start-up screen, click on it with the left mouse button, all information related to this specimen is displayed in the middle-right window: the specimen is named as Agassiceras scipionianum and was collected from southwest Germany. With the Save Image As button and the File: name field, the user can save the whole or any part of the graphics window (using mouse button to mark the region of interest) as a file for later reference or print out. The textual information displayed in the middle-right window can be saved as an ASCII file using the pull-right menu of the window, so that the information is available to other applications.  Figure 6-8  Amrnon Image Database  The retrieval of the specimen in the start-up screen  Display Image Window  An Aid to Identification 6.3  128  Examples  It would be interesting to see what kind of role that Ammon can play and how effective it can be in dealing with the problem of fossil identification. A colleague of mine, Genga Nadaraju of the UBC Paleontology Lab has just finished her Master's thesis entitled "Triassic-Jurassic biochronology of the eastern Iskut River map area, northwestern British Columbia" but the illustrations and taxonomic descriptions of her ammonite collections have not yet been entered into Ammon. Most of the ammonite specimens from Nadaraju's collection are poorly preserved and fragmentary thereby providing a challeging test of the system. 1. Example 1 - Fig. 6-9 (Nadaraju 1993, Plate V, Fig. 1 ) Measurements (From Nadaraju 1993, p.98): SPECIMEN  D(cm)  UD (cm)  U  PRHW  C-201415a  «8.53  5.00  0.58  33  Description:  Evolute form with a  wide umbilicus. Flanks slightly convex and ornamentation  consisting  of  numerous  simple ribs that trend prorsiradiately on the outer part of the flanks. A query measurements  based  and  on  the  description  above can  be  composed: U>0.55 and UO.62 and UD>4 and PRHW>25 and PRHW<40 and PTREND like  prorsiradiate  and  FURC=no  and  TUBERC^no. Each character in the query is Figure 6-9 Plate V, Fig. 1 of Nadaraju 1993 given a range centering around the  Geoqraphv =>  [EMREiETEi.  Retrieve by:  Amnion Image Database Display Image Window  Figure 6-10  Query results of Example 1  ie.  25 and prhui<40 and ud>4 and ptrend l i k e  D: 13.59 LIB: 7.7b LI: 0.58 EXP: 1.58 WH: 3.1 shallow. VENTER:carinate-sulcate. PTP.END:prors1rai IBWIDTH: 0.10 EXPO: 1.71 VOLUTIOND: 0.13  H1.55 and iKO'.Bl  H ^o  130  An Aid to Identification  measured value as well as taking into account the measurement errors and intraspecific variations. For example, "PTREND like prorsiradiate" would include specimens with either prorsiradiate ribs or gently prorsiradiate ribs. As result of the query, 5 specimens are retrieved from the database. Fig. 6-10 shows the first two specimens and by clicking on the left specimen with the left mouse button, all textual information related to it appears in the middle-right window: a Paracaloceras multicostatum from Upper Hettangian and Lower Sinemurian. Paracaloceras cf multicostatum was the identification made by Nadaraju (1993). The other four candidates are : harbledownense, Echioceras  Paltechioceras yakounense,  aklavikense, Leptechioceras  Paltechioceras  alvarezi, all from  Upper  Sinemurian If it is known that the specimen is from Hettangian or Lower Sinemurian, then Paracaloceras multicostatum offers the best candidate. Example 2 - Fig. 6-11 (Nadaraju 1993, Plate VI, Fig. 1 ) Measurements SPECIMEN  D(cm)  U  W  PRHW  C-201631b  «14  0.73  1.46  «36  Description: Evolute, ellipsoidal shell with many whorls. Ornamentation consists of simple ribs that are dense. No keel observed due to the state of preservation. A query based on the above measurements and description can be composed: U>0.67 and W<1.5 and PRHW>30 and D>12 and FUROno which leads to retrieval of four specimens from the database and the first one of which (Fig. 6-12) is Alsatites cf. proaries, the identification made by Nadaraju (1993). The other candidates are : Alsatites liasicus from the Middle Hettangian and Coroniceras longidomus from the Lower Sinemurian.  An Aid to Identification  &£TO''  t§6 r-tb  %  MI* ^ 7 * . ~v  ft.-  rt*  **i^Ji^s  Figure 6-11  Plate VI, Fig. 1 of Nadaraju 1993  131  Amman Image Database  Figure 6-12  Display Image Window  Query results of Example 2  An Aid to Identification  133  Example 3 - Fig. 6-13 (Nadaraju 1993, Plate VIII, Fig. 1 ) Measurements SPECIMEN  D(cm)  U  WWWH  PRHW  C-201453  «4.2  0.42  1.00  13  Description: Midvolute form with an elliptical whorl section reaching its greatest width near the middle of the flank. Each whorl embraces nearly half of the preceding one. Rounded, plain venter. Ornamentation consists of straight ribs that arise at the umbilical shoulder becoming progressively sharper and thicker to mid-flank and then fading at the ventro-lateral shoulder. A query can be formulated as: U>0.37 and U<0.47 and WWWH>0.85 and WWWH<1.2 and PRHW>10 and PRHW<16 and D>3 and D<6 and VENTER=plain and TUBERC=no Fig. 6-14 shows the query result. Most of the specimens have ribs that cross the venter which does not fit the above description. The only two species that have unornamented venters are Badoiaia canadensis and Franziceras coronoides. The former has ribs that gradually fade whereas the latter has ribs that terminate suddenly at the ventro-lateral shoulder. Fig. 6-13 is probably a Badoiaia canadensis, the identification made by Nadaraju (1993). Rib strength change across flank can be perceived easily by the human eye but it is difficult to describe in rigid morphological terms that can be used in a computerized database. In order to maximize the benefit and minimize the potential for errorious conclusions, it is clear that human and computer interaction is the best approach to identification.  Fig. 6-13 Plate VIII, Fig. 1 of Nadaraju 1993  Retrieve by:  Ammori Image Database 0  and D<6 and VENTER=plain and TUB!  Query results of Example 3  •lumber of Imaqes Remained to D i e p l a v :  Figure 6-14  Display Image window  An Aid to Identification  135  In summary, Amnion can be very useful in assisting identification of Lower Jurassic ammonites. Instead of memorizing thousands of species, the user need only to know a dozen morphological descriptors and a few database operators such as AND, OR, NOT, LIKE, IN. A new user of Ammon may need to measure a few quantitative morphological parameters but after some practices the user should be able to build up a sense of relationship between quantitative and qualitative parameters. At this point identification becomes fun. A computerized ammonite image database cannot replace the human expert but does alleviate the burden of memorizing many species and associated data allowing the user to focus on more important questions The following figures show the variations of basic shell geometry for Lower Jurassic ammonite genera which aims to define these genera more objectively; similar plots for species are not made due to space limitations.  136 Figure 6-15 Shaded boxs show the range of expansion rate for each genus, the figures in the bracket show number of specimens in each genus  Coeloceras(87) Catacoeloceras(11) Canavaria(46)_ Caloceras(11) Brodieia(4) Brasilia(2) Bifericeras(21)  I  Aveyroniceras(44) Asteroceras(41) Arnioceras(154) Arieticeras(144) Apoderoceras(13) Androgynoceras(71) Amaltheus(264) Alsatites(14) Aegoceras(49) Acanthopleuroceras(79)  137 Figure 6-16 Shaded boxes show the range of expansion rate for each genus, the figures in the bracket show number of specimens in each genus  Gagaticeras(8) Frechiella(6) Fontanelliceras(22) Fanninoceras(98) Eudmetoceras(21 EsericerasO) Erycites(2) Epideroceras(16) Eoderoceras(15) Eleganticeras(36) Dumortieria(51) Discamphiceras(18) Dayicerasd 1) Dactylioceras(200) Cyclicocerasd  Costileiocerasd) Collina(20)  W  138 Figure 6-17 Shaded boxes show the range of expansion rate for each genus, the figures in the bracket show number of specimens in each genus  Oregonites(IO) Nodicoelocerasd6) Nejdiad) Miltoceras(4) Metarniocerasd) Mercaticeras(5) Liparoceras(50) Leukadiella(14)  o  Leptaleoceras(98) Laqueoceras(5) Hyperliocerasd) Hudlestonia(6) HildaitoidesO) Haugia(55) Haplopleurocerasd) Graphoceras(2) Gleviceras(48)  139 Figure 6-18 Shaded boxes show the range of expansion rate for each genus, the figures in the bracket show number of specimens in each genus  Pseudasterocerasd) Protogrammoceras(256) Promicroceras(6) Praesphaerocerasd) Pompeckiocerasd) Polymorphites(37) Podagrosiceras(5)  I  Pleuroceras(47) Planammatoceras(21) Phymatoceras(98) Phlyseogrammocerasd 8) Peripleuroceras(3) Paroniceras(7) Parapsilocerasd) Paradiscamphiceras(2) Paltechioceras(120) Oxynoticeras(38)  140  Figure 6-19 Shaded boxes show the range of expansion rate for each genus, the figures in the bracket show number of specimens in each genus  Yakounia(20) Waehneroceras(45) Uptonia(48) Transipsiloceras(l) Tmaegophiocerasd) Tiltoniceras(41) Taffertiad) CO  Sulciferites(48) Sphenarpitesd) Slatteritesd) Saxoceras(6) Reynesoceras(53) Renzicerasd) Puchenquia(21) Psiloceras(92) Pseudoskirroceras(6) Pseudolioceras(206)  141  Figure 6-20 Shaded boxes show the range of whorl overlap (U) for each genus, the figures in the bracket show number of specimens in each genus  Coeloceras(87)  =ZT  Catacoelocerasd 1) Canavaria(46)  ^  •U  Calocerasd 1)  ¥  Brodieia(4)  E£  Brasilia(2)  ^  ?  5L  Bifericeras(21) 00  I  2.  Aveyroniceras(44)  —*-—•—•—*—uy /•  5  ~^  Asteroceras(41) Arnioceras(154) Arieticeras(144) Apoderoceras(13)  3>  S"  5  Androgynoceras(711 Amaltheus(264)  _-  Alsatites(14)~ ^  Aegoceras(49)  E  Acanthopleuroceras(79)  0.1  0.2  0.3  2  ~  X  0.4  U  0.5  0.6  0.7  0.8  142  Figure 6-21 Shaded boxes show the range of whorl overlap (U) for each genus, the figures in the bracket show number of specimens in each genus  Gagaticeras(8) Frechiella(6) Fontanelliceras(22) Fanninoceras(98) Eudmetoceras(21) EsericerasO) Erycites(2) 05  1  Epideroceras(16) Eoderoceras(15) Eleganticeras(36) Dumortieria(51) Discamphiceras118) Dayicerasd 1) Dactylioceras(200) Cyclicocerasd) Costileiocerasd) Collina(20)  143  Figure 6-22 Shaded boxes show the range of whorl overlap (U) for each genus, the figures in the bracket show number of specimens in each genus  Oregonites(IO) Nodicoeloceras(16) Nejdiad) Miltoceras(4) Metarniocerasd Mercaticeras(5) Liparoceras(50) Leukadiella(14)  O  Leptaleoceras(98) Laqueoceras(5) Hyperliocerasd Hudlestonia(6) HildaitoidesO) Haugia(55) Haplopleurocerasd Graphoceras(2) Gleviceras(48) 0.8  144  Figure 6-23 Shaded boxes show the range of whorl overlap (U) for each genus, the figures in the bracket show number of specimens in each genus  Pseudasterocerasl 1) Protogrammoceras(256) Promicroceras(6) Praesphaeroceras( 1 Pompeckiocerasd) Polymorphites(37) Podagrosiceras(5)  I  Pleuroceras(47) Planammatoceras(21 Phymatoceras(98) Phlyseogrammocerasd 8) Peripleuroceras(3) Paroniceras(7) Parapsilocerasd) Paradiscamphiceras(2) Paltechiocerasd 20) Oxynoticeras(38) 0.8  145  Figure 6-24 Shaded boxes show the range of whorl overlap (U) for each genus, thefiguresin the bracket show number of specimens in each genus  Yakounia(20) Waehneroceras(45) Uptonia(48) Transipsiloceras(1 Tmaegophioceras( 1 Tiltoniceras(41 Taffertiad) 05  I  Sulciferites(48) Sphenarpitesd Slatteritesd) Saxoceras(6) Reynesoceras(53) Renzicerasd Puchenquia(21 Psiloceras(92) Pseudoskirroceras(6) Pseudolioceras(206) 0.8  146  Figure 6-25 Shaded boxes show the range of WWWH for each genus, the figures in the bracket show number of specimens in each genus  -0  Coeloceras(87)  c  r  Catacoelocerasd 1)  XT  Canavaria(46) Calocerasd 1) Brodieia(4) Brasilia(2)  0 Bifericeras(21)  1 o  fi  0  Aveyroniceras(44) Asteroceras(41) Arnioceras(154) Arieticeras(144)  /  l>  Apoderoceras(13) Androgynoceras(71) Amaltheus(264) Alsatites(14) A Q  Aegoceras(49) Acanthopleuroceras(79)  f 0.5  1.5 WWWH  f 2.5  r  147 Figure 6-26 Shaded boxes show the range of WWWH for each genus, the figures in the bracket show number of specimens in each genus  Fuciniceras(161 FranzicerasO) Fieldingiceras(3) Exomilocerasd Eudmetoceras(21) EsericerasO) Erycites(2) Epideroceras(16)  a O  Eoderoceras(15) Eleganticeras(36) Dumortieria(51 Discamphicerasd 8) Dayicerasd 1 Dactylioceras(200) Cyclicocerasd Costileiocerasd Collina(20)  148 Figure 6-27 Shaded boxes show the range of WWWH for each genus, the figures in the bracket show number of specimens in each genus  Onychocerasd) Neolioceratoides( 19) Mullerites(2) Microderocerasd 6) Metaderoceras(83) Ludwigia(14) Lioceratoides(34) Leptechioceras(29)  6  Leioceras(29) Kammerkarocerasd) Hyperderocerasd 6) Hildoceras(55) Hildaites(51) Harpoceras(165) Hammatoceras(28) Grammoceras(47) Gemmellarocerasd 2)  149  Figure 6-28 Shaded boxes show the range of WWWH for each genus, the figures in the bracket show number of specimens in each genus  Pseudaetomoceras(1) Protechioceras( 1) Prodactylioceras(37) Praesphaeroceras(1) Pompeckioceras(1) Polymorphites(37) Podagrosiceras(5) Pleuroceras(47) Planammatoceras(21) Phymatoceras(98) Phlyseogrammoceras(1 8) Peripleuroceras(3) Paroniceras(7) Parahildaites(3) Paracymbites(1) Palaeoechioceras(3) Ovaticeras(8) 0  0.5  1  1.5  WWWII  2  2.5  3  150  Figure 6-29 Shaded boxes show the range of WWWH for each genus, the figures in the bracket show number of specimens in each genus  Yakounia(20) Waehneroceras(45)  -  :  -  I  -  Uptonia(48) Transipsiloceras(1) Tmaegophioceras(1 ) Tiltoniceras(41 )  -  -  IJ  -  -  I,  -  I  Taffertia(1)  L)  -  V Sulciferites(48)  I  I  IJ  -  Sphaerocoeloceras(6)  -  Schlotheimia(40)  I____  Reynesocoeloceras(21) -  Reynesella(1) Radstockiceras(34) Psilophyllites(7)  -  -  III  Pseudotropites(1) Pseudomercaticeras(5) Pseudogrammoceras(72)  E_c 0  I  I  I  0.5  1  1.5  WWWH  2  I  I  2.5  3  Summary and Conclusions  Chapter 7  151  Summary and Conclusions  This thesis presents the first computerized image database for ammonites which allows automated measurement of morphological parameters from images. The database Ammon contains 7790 specimens representing 15 Lower Jurassic arnmonite families, 179 genera and 1319 species. Each specimen has 102 descriptors covering taxonomy, quantitative morphology, qualitative morphology, stratigraphy, locality and general comments. Computer image analytical teclmiques are used to derive morphological parameters from images in the database and a graphics interface is implemented to give the user easy access. Elliptical Fourier representation is used to quantify whorl shape for the first time which allows the construction of intermediate whorl shapes and the theoretical extension of morphologic trends beyond the forms available. Fourier representation of whorl shape enables a more objective documentation and comparison of whorl shape variations within and among taxa. The species density diagrams for Lower Jurassic ammonites are plotted with respect to basic shell geometry.  The distributions are strikingly similar to those for Mesozoic  ammonoids in general, being largely concentrated on low W and high U regions and suggesting the same geometrical restraints. The data show strong correlations among basic geometric parameters (W, U, WWWH) which may be related to restrictions imposed by the shape and relative size of the whorl. This has been approached mathematically. Preliminary study of morphological and stratigraphical data from Ammon suggests a possible correlation between basic shell geometry, morphological variability and taxa duration. Low within-population morphological variabilities and short durations are associated with taxa that inhabit the most densely populated region of low W and high U.  Summary and Conclusions  152  Away from this peak in faster expanding regions, there is a steady increase in both morphological variability and taxa longevity implying a decrease in selective pressure. The inter-relationships of shell expansion rate, degree of involution, whorl shape, ribs, tubercles and venter have been studied using the Amnion database. A few covariations have been observed and documented quantitatively. The major covariation patterns are: (a) Faster expanding shells tend to be more involute, involute shells are more compressed than evolute shells, and compressed shells have finer ribs, (b) The frequency of shells with tubercles increases if ribs furcate, (c) Tubercles of compressed shells tend to be on the lower flank whereas tubercles of depressed shells tend to be on the upper flank, (d) Shells with sinuous ribs are more involute and more compressed than shells with straight ribs, (e) There is a positive correlation between tuberculation and rib strength, (f) The frequency of shells with a keels increases in shells that are compressed, or have a small fineness ratio. Some interpretations and speculations for these covariations are given. The taxonomic diversity of Lower Jurassic ammonites peaks first at the family level in the Ibex Zone, followed by generic data one zone later, and finally species in the Margaritatus Zone implying a delay in radiation for lower levels of ammonite taxa. The late Sinemurian and early Pliensbachian have high family origination rates and relatively low species diversities; species reach their highest diversity level in the late Pliensbachian, which also has the highest family extinction rate and an almost zero origination rate. The data support the claim (Raup and Sepkoski 1986) that the Pliensbachian is a time of mass extinction. Furthermore, the data indicate that the extinction event happened in the Late Pliensbachian and was gradual for ammonites at the family level. Two morphological diversity indexes are used to study changes through time. The range index describes the range of the morphospace occupied. The Shannon Index measures both the range and the evenness of the occupation. Both indexes indicate a similar pattern.  Summary and Conclusions  153  There is a rapid rise to an early Sinemurian maximum through morphological radiation especially in terms of the basic shell geometry, followed by a pronounced fall in the middle of Sinemurian with diversity remaining relatively high and stable thereafter. The data also show that Pliensbachian and Toarcian ammonites have significantly higher ornamentation diversities than earlier forms in the Hettangian and Sinemurian. It is evident by comparing taxonomic and morphological diversity changes through time that initial morphological diversification in Lower Jurassic ammonites far exceeded the proliferation of lower-level taxa. The most striking fact emerging from the comparison is that the morphological diversity of the Bucklandi Zone with 46 species is higher than that of the Margaritatus Zone with 177 species. It demonstrates that morphological diversity need not increase as taxonomic diversity increases. "Such morphological stagnation indicates taxonomic diversification that is highly constrained morphologically" (Foote 1993). There are two interesting observations although the resolution and type of my data does not warrant firm conclusions: (1) All Lower Jurassic ammonite families that radiate into numerous species in the first zone of their occurrence have durations of less than 4 zones; in other words, rapid origination is associated with short duration. (2) The mean maximum shell diameters of species within families and superfamilies show synchronized drops in the Oxynotum Zone and Ibex Zone. Interestingly, these two zones show high family origination rates and relatively low species diversities. Finally a few specimens collected from the Iskut River map area are used to test Amnion as a tool for identification; the results are encouraging.  References  154  References Ackerly, S. C. 1989. Kinematics of accretionary shell growth with examples from brachipods and molluscs. Paleobiology 15 : 147-164. Anstey, R. L. and Delmet, D. A. 1973. Fourier analysis of zooecial shapes in fossil tubular bryozoans. Geological Society of America Bulletin 84: 1753-1764. Arkell, W. J., Kummel, B. and Wright, C. W. 1957. Mesozoic ammonoidea. in The Treatise on Invertebrate Paleontology (Moore, R. C , ed.), University of Kansas Press. Arnold, A. J. and Fristrup, K. 1982. The theory of evolution by natural selection: a hierarchical expansion. Paleobiology 8(2): 113-129. Anonymous 1990a. Introduction to SQL by Oracle Corporation. — 1990b. SQL*Loader User's Guide (Version 1.0) by Oracle Corporation. — 1990c. SQL Language Reference Manual (Version 6.0) by Oracle Corporation. Arthur, A.J. 1985. Biostratigraphy of the Lower to Middle Jurassic sediments, Ashcroft area, south central British Columbia. B.Sc. thesis, University of British Columbia. — 1987. Mesozoic stratigraphy and paleontology of the west side of Harrison Lake, southwestern British Columbia. M.Sc. thesis, University of British Columbia. Arthur, A., Smith, P. L., Monger, J. W. and Tipper, H. W. 1992: Mesozoic stratigraphy and Jurassic paleontology west of Harrison Lake, southwestern British Columbia. Geological Survey of Canada Bulletin 441. Batt, R. J. 1989. Ammonite shell morphotype distributions in the Western Interior Greenhorn Sea and some paleoecological implications. Palaios 4: 32-42. Bayer, U. 1985. Pattern recognition problems in geology and paleontology. Berlin: SpringerVerlag. Bayer, U. and McGhee, G. R. 1984. Iterative evolution of Middle Jurassic ammonite faunas. Lethaia, 17: 1-15. — 1985. Evolution in marginal epicontinental basins: the role of phylogenetic and ecological factors, in Sedimentary and Evolutionary Cycles (Bayer, U. and Seilacher, A., eds.) p. 164-215, Springer-Verlag, Berlin.  References  155  Beerbower, J. Jordan, D. 1969. Application of information theory to paleontologic problems: taxonomic diversity. Journal of Paleontology, 43(5): 1184-1198. Billings, E. 1873. On the Mesozoic Fossils from British Columbia collected by Mr. James Richardson in 1872. Geological Survey of Canada, Report of Progress, 1872-1873, p. 71-75. Blasco, G., Levy, R. and Nullo, F. 1978. Los amonites de la formacion Osta Arena (Liasico) y su posicion estratigrafica-Pampa de Agnia-(Provincia del Chubut): VII Congreso Geologico Argentino, Neuquen, Actas, 2: 407-429. Benson, R. H., Chapman, R. E. and Siegel, A. F. 1982. On the measurement of morphology and its change. Paleobiology 8: 328-339. Bisby, F. A. 1983. Information services in taxonomy. In Allkin, R. and Bisby, F. A. eds. Databases in Systematics. Canfield, D. J. and Anstey, R. L. 1981. Harmonic analysis of Cephalopod suture patterns. Mathematical Geology 13: 23-35. Canny, J. 1986. A computaional approach to edge detection. IEEE Trans, on pattern analysis and machine intelligence 8: 679-697. Chamberlain, J. A. 1976. Flow patterns and drag coefficients of cephalopod shells. Paleontology 19(3): 539-563. — 1981. Hydromechanical design of fossil cephalopods In: House, M. R. and Senior, J. R. eds. The Ammonoidea. Systematics Association Special Volume 18: 289-336. Checa, A. 1987. Morphogenesis in ammonites - differences linked to growth pattern. Lethaia 20: 141-148. Checa, A. and Westermann, G. E. G. 1989. Segmental growth in planulate ammonites: inferences on coastal function. Lethaia 22: 95-100. Christopher, R. A. and Waters, J. A. 1974. Fourier series as a quantitative descriptor of miospore shape. Journal of Paleontology 48: 697-709. Clark, M. W. 1981. Quantitative shape analysis: a review. Mathematical Geology 13: 303-320. Cleynenbreugel, V. et al 1988. Knowledge-based road network extraction on SPOT satellite images. 4th International Conference on Pattern Recognition.  References  156  Conrad, M. A. and Beightol, D. S. 1988. Expert systems identify fossils and manage large paleontological databases. Geobyte, No. 2 : 42-46. Crickmay, C.H. 1925: A note on two of Hyatt's Liassic ammonites. Proceedings of the California Academy of Sciences, fourth series, 14: 77-81. — 1928: The stratigraphy of Parson Bay, British Columbia. University of California Publications, Bulletin of the Department of Geological Sciences , 18: 51-70. — 1932 : A new Jurassic ammonite from the Coast Ranges of California. American Midland Naturalist, 13:1-7, pi. 1-2. — 1932-1933: Some of Alpheus Hyatt's unfigured types from the Jurassic of California. United States Geological Survey, Professional Paper 175-B: 51-64, pi. 14-18. — 1933: Mount Jura investigation. Bulletin of the Geological Society of America, 44: 895-926, pi. 23-34. Dagis, A.A. 1968. Toarcian Ammonites (Dactylioceratidae) from northern Siberia. U.S.S.R. Academy of Sciences, Siberian Branch, Transactions of the Institute of Geology and Geophysics, no. 40, 108 p., 12 pi. — 1971. On the Toarcian-Pliensbachian boundary and zonation of the Lower Toarcian sediments in the northeastern U.S.S.R.. Geologiya i Geofizika, no. 5 (136), p. 128-132. ~ 1974. Toarcian ammonites (Hildoceratidae) from northern Siberia. U.S.S.R. Academy of Sciences, Siberian Branch, Transactions of the Institute of Geology and Geophysics, no. 99, 188 p., 19 pi. — 1976. Late Pliensbachian ammonites (Amaltheidae) of the North Siberia: Publishing House, Nauka, Siberian Branch, Novosibirsk, 79 p., 17 pi. (in Russian). Davis, J. C. 1986. Statistics and data analysis in geology. New York: Wiley. Dawson, G.M. 1880. Queen Charlotte Islands. Geological Survey of Canada, Report of Progress, 1878-1879. Dean, W.T., Donovan, D.T. and Howarth, M.K. 1961. The liassic Ammonite zones and subzones of North-West european province. Bulletin of the British Museum (Natural History), 4(10), p. 437-505, pi. 63-74. Doguzhaeva, L. 1982. Rhythms of ammonoid shell secretion. Lethaia 15: 385-394.  References  157  Dommergues, J. L. 1988. Can ribs and septa provide an alternative standard for age in ammonite ontogenetic studies ? Lethaia 21: 243-256. Donovan, D.T. 1964. Cephalopod phylogeny and classification. Biology Review 39: 259-287 — 1985. Ammonite shell form and transgression in the British Lower Jurassic in Sedimentary and Evolutionary Cycles (Bayer, U. and Seilacher, A., eds.) p. 48-57, Springer-Verlag. Berlin. Donovan, D.T., Callomon, J.H. and Howarth, M.K. 1981. Classification of the Jurassic Ammonitina. in The Ammonoidea, (House, M.R. and Senior, J.R., eds.), Systematics Association, Special Publication 18, Academic Press, p. 101-155. Ehrlich, R. 1983. Comments on the validity of Fourier descriptors in systematics: a reply to Bookstein. Systematic Zoology 32 : 202-206. Erben, H.K. 1956: El Jurasico inferior de Mexico y sus amonitas. XX Congreso Geologico Internacional, 393 p. Foote, M. 1989. Perimeter-based Fourier analysis: a new morphometric method applied to the trilobite cranidium. Journal of Paleontology 63(6): 880-885. — 1991. Morphologic patterns of diversification: examples from trilobites. Paleontology 34(2): 461-485. — 1992. Rarefaction analysis of morphological and taxonomic diversity. Paleobiology 18(1): 1-16. — 1993. Discordance and concordance between morphological and taxonomic diversity. Paleobiology 19(2): 185-204. Frebold, H. 1951: Lowermost Jurassic Fauna in Whitesail Lake map-area, British Columbia, in Contributions to the Palaeontology and Stratigraphy of the Jurassic System in Canada, Geological Survey of Canada Bulletin 18: 18-21, 1 pi. — 1957: The Jurassic Fernie Group in the Canadian Rocky Mountains and Foothills. Geological Survey of Canada Memoir 287:1-197,44 pi. — 1958. Stratigraphy and correlation of the Jurassic in the Canadian Rocky Mountains and Alberta Foothills, in Jurassic and Carboniferous of Western Canada, American Association of Petroleum Geologists. ~ 1959: Marine Jurassic rocks in Nelson and Salmo areas southern British Columbia. Geological Survey of Canada, Bulletin 49: 31 p., 5 pi.  References  158  — 1960. The Jurassic faunas of the Canadian Arctic (Lowermost Jurassic and lowermost Middle Jurassic ammonites). Geological Survey of Canada, Bulletin 59: 1-33, pi. 1-15. — 1964a: Lower Jurassic and Bajocian ammonoid faunas of northwestern British Columbia and southern Yukon. Geological Survey of Canada Bulletin 116: 31 p. 8 pi. ~ 1964b: Illustrations of Canadian fossils Jurassic of Western and Arctic Canada. Geological Survey of Canada, Paper 63-4: 1-107, pi. 1-51. — 1966: Upper Pliensbachian beds in the Fernie Group of Alberta. Geological Survey of Canada, Paper 66-27: 1-7, 1 pi. — 1967a: Hettangian ammonite faunas of the Taseko lakes area British Columbia. Geological Survey of Canada, Bulletin 158: 1-35, pi. 1-9. — 1967b: Position of the Lower Jurassic genus Fanninoceras McLearn and the age of the Maude Formation on Queen Charlotte Islands. Canadian Journal of Earth Sciences, 4: 1145-1149. — 1970: Pliensbachian ammonoids from British Columbia and Southern Yukon. Canadian Journal of Earth Sciences, 7: 435-452, pi. 1-4. — 1975. The Jurassic faunas of the Canadian Arctic (lower Jurassic ammonites, biostratigraphy and correlation) Geological Survey of Canada, Bulletin 243, 24 pps., 5 pi. — 1976: The Toarcian and Lower Middle Bajocian beds and ammonites in the Fernie Group of southeastern British Columbia and parts of Alberta. Geological Survey of Canada Paper 75-39 : 20 p., 9 pi. Frebold, H. Mountjoy, E.W. and Tempelman-Kluit, D. 1967. New occurrences of Jurassic rocks and fossils in central and northern Yukon. Geological Survey of Canada, Paper 67-12 Frebold, H. and Tipper, H.W. 1969. Lower Jurassic rocks and fauna near Ashcroft, British Columbia and their relation to some granitic plutons (92-1). Geological Survey of Canada, Paper 69-23: 20 p., 1 pi. Frebold, H. and Tipper, H.W. 1970. Status of the Jurassic in the Canadian Cordillera of British Columbia, Alberta and Southern Yukon. Canadian Journal of Earth Sciences, 7(1): 1-21. Frebold, H., Tipper, H.W. and Coates, J.A. 1969. Toarcian and Bajocian rocks and guide ammonites from Southwestern British Columbia. Geological Survey of Canada,  References  159  Paper 67-10: 55 p., 6 pi. Gabb, W.M. 1869. Descriptions of some secondary fossils from the Pacific Coast States. American Journal of Conchology, 5: 5-18, pi. 3 . Gabilly, J. 1975. Evolution et systeque des Phymatoceratinae et des Grammoceratinae (Hildocerataceae Ammonitina) de la region de Thouars, stratotype du Toarcien. Memoires de la Societe Geologique de France, no. 124, Nouvelle Serie, tome LIV, p. 1-196, pi. I-XXXVI. — 1976. Le Toarcien a Thouars et dans le centre-ouest de la France - biostratigraphie evolution de la faune (Harpoceratinae, Hildoceratinae). Les Stratotypes Francais, Publications du Comite Francais de Stratigraphie, 3: 1-217, pi. 1-29. Geczy, B. 1976. Les ammonitines du Carixien de la Montagne du Bakony. Akademiai Kiado, Budapest. 223 p. Geyer, O. F. 1974. Der Unterjura (Santiago-Formation) von Ekuador. Neues Jahrbuch fur Geologie und Palaontologie, Monatshefte, 9: 525-541. Geyer, O. F. 1979. Ammoniten aus dem tiefen Unterjura von Nord-Peru. Palaontologische Zeitschrift, 53: 198-213. Gould, S. J. 1991. The disparity of the Burgess Shale arthropod fauna and the limits of cladistic analysis: why we must strive to quantify morphospace. Paleobiology 17(4): 411-423. Gregory, S. 1963. Statistical methods and the geographer. Longmans, Green and Co. Ltd. Guex, J. 1980. Remarques preliminaires sur la distribution stratigraphique des ammonites hettangiennes du New York Canyon (Gabbs Valley Range, Nevada). Bulletin de Geologie Lausanne, 250: 127-140. — 1981. Quelques cas de dimorphisme chez les ammonoides du Lias inferieur. Bulletin Soc. Vaud. Sc. Nat., 75:239-248. ~ 1989. Note sur le genre Franziceras Buckman (Ammonoidea, Cephalopoda). Bulletin de Geologie Lausanne, 305:347-354. Hall, R.L. 1987. New Lower Jurassic ammonite fauna from the Fernie Formation, southern Canadian Rocky Mountains. Canadian Journal of Earth Science, 24: 1688-1704, 5 pi. Hall, R.L. and Howarth, M.K. 1983. Protogrammoceras paltum (Buckman), a late Pliensbachian (Jurassic) ammonite from Axel Heiberg Island, Canadian Arctic Archipelago. Canadian Journal of Earth Sciences, 20: 1470-1475.  References  160  Hall, R.L. and Westermann, G.E.G. 1980. Lower Bajocian (Jurassic) cephalopoda faunas from Western Canada and proposed assemblage zones for the Lower Bajocian of North America. Palaeontographica Americana, v. 9(52): 1-93, pi. 1-15. Hallam, A. 1985. Jurassic moUuscan migration and evolution in relation to sea level changes. in Sedimentary and Evolutionary Cycles (Bayer, U. and Seilacher, A., eds.) p. 4-5, Springer-Verlag, Berlin. — 1986. The Pliensbachian and Tithonian extinction events. Nature 319: 765-767. — 1987. Radiations and extinctions in relation to environmental change in the marine Lower Jurassic of northwest Europe. Paleobiology 13(2): 152-168. Harland, W.B., Armstrong, R.L., Cox, A.V., Craig, L.E., Smith, A.G. and Smith, D.G. 1989. A geologic time scale, 1989. Cambridge University Press. HiUebrandt, A. von. 1973a. Neue Ergebnisse tiber den Jura in Chile und Argentinien. Munstersche Forschungen zur Geologie und Palaontologie, Heft 31/32: 167-199, pi. 1. — 1973b. Die Ammoniten-Gattungen Bouleiceras und Frechiella im Jura von Chile und Argentinien. Eclogae geologicae Helvetiae, 66/2: 351-363, pi. I-III. — 1982. Faunas de amonites del Liasico inferior y medio (Hertangiano hasta Pliensbachiano) de America del sur (Excluyendo Argentina). Cuncas sedimentarias del Jurasico y Cretacico de America del sur, 2: 499-538, pi. I-X. ~ 1987. Liassic ammonite zones of South America and correlations with other provinces with descriptions of new genera and species of ammonites. Biostratigrafia de los sistemas regionales del Jurasico y Cretacico en America del Sur, Tomo I: Jurasico anterior a los movimentos malmicos, 1: 111-157, 14 pi. HiUebrandt, A. von and Schmidt-Effing, R. 1981. Ammoniten aus dem Toarcium (Jura) von Chile (Sudamerika) - Die Arten der Gattungen Dactylioceras, Nodicoeloceras, Peronoceras und Collina. Zitteliana, Abhandlungen der Bayerischen Staatssammlung fur Palaontologie und historische Geologie, 6, 74 p., 8 pi. Hirano, H. 1971a. Biostratigraphic study of the Jurassic Toyora Group, Part I. Memoirs from the Faculty of Science, Kyushu University, Series D, Geology, 21(1): 93-128, pi. 14-20. ~ 1971b. Biostratigraphic Study of the Jurassic Toyora Group, Part II. Transactions and Proceedings of the Palaeontological Society of Japan, N.S., no. 89, p. 1-14, pi. 1-4.  References  161  - 1971c. Biostratigraphic Study of the Jurassic Toyora Group, Part III. Transactions and Proceedings of the Palaeontological Society of Japan, N.S., no. 90, p. 45-71, pi. 9-10. Hohenegger, J. and Tatzxeiter, F. 1992. Morphometric methods in determination of ammonite species, exemplified through Balatonites shells (Middle Triassic). Journal of Paleontology 66(5): 801-816. Horn, B. K. P. 1986. Robert Vision. The MIT Press. Howarth, M.K. 1992. The ammonite family Hildoceratidae in the Lower Jurassic of Britain. Monograph of the Palaeontographical Society, part 1, 1-106, pi. 1-16. Huber, B. T. 1990. Digital-image processing will replace most hard-copy photography in palynology. Geotimes 35(2): 43-44. Illert, C. and Pickover, C. A. 1992. Generating irregularly oscillating fossil seashells. IEEE Computer Graphics and Applications. No. 5: 18-22. Imlay, R.W. 1968. Lower Jurassic (Pliensbachian and Toarcian) Ammonities from Eastern Oregon and California. United States Geological Survey, Professional Paper 593-C: 51. 9 pi. Imlay, R.W. 1981. Early Jurassic Ammonites from Alaska. United States Geological Survey, Professional Paper 1148: 49 p., 12 pi. Jakobs, G. 1992. Toarcian (Lower Jurassic) ammonite biostratigraphy and ammonite fauna of North America. Unpublished Ph.D. thesis, University of British Columbia, 682 p. Jones, D.L. and Moore, J.G. 1973. Lower Jurassic ammonite from the South-Central Sierra Nevada, California. Journal of Research, U.S.Geological Survey, 1: 453-458. Kaesler, R. L. and Waters, J. A. 1972. Fourier analysis of the ostracode margin : Geological Society of America Bulletin 83: 1169-1178. Kauffman, E. G. 1977. Evolutionary rates and biostratigraphy. In Kauffman, E. G. and Hazel, J. E. (eds.) Concepts and Methods of Biostratigraphy: 109-141. Kennedy, W. J. and Cobban, W. A. 1976. Aspects of ammonite biology, biogeography and biostratigraphy. Special Papers in Palaeontology, Palaeontological Association, London, 17:1-94. Klapper, G. and Foster, C. T. J. 1993. Shape analysis of Frasnian species of the Late Devonian conodont genus Palmatolepis. Journal of Paleontology 1993, supplement to No. 4.  References  162  Koch, G. S. J. and Link, R. F. 1971. Statistical analysis of geological data. New York : Wiley. Krumbein, W. C. and Graybill, F. A. 1965. Introduction to statistical models in geology. New York: McGraw-Hill. Kuhl, F. P. and Giardina, C. R. 1982. Elliptic Fourier features of a closed contour. Computer Graphics and Image Processing 18: 236-258. Kullmann, J., Korn, D., Kullmann, P. S. and Petersen, M. S. 1991. The status of GONIAT, a data-base for Paleozoic ammonoids. First Canadian Paleontology Conference, Vancouver, p. 48. Landman, N. H. 1989. Iterative progenesis in Upper Cretaceous ammonites. Paleobiology 15(2): 95-117. Landman, N. H., Rye, D. M. and Shelton, K. L. 1983. Early ontogeny of Eutrephoceras compared to Recent Nautilus and Mesozoic ammonites: evidence from shell morphology and light stable isotopes. Paleobiology 9(3): 269-279. Lehmann, U. 1981. The ammonites — their life and their world. Cambridge University Press. Liang, B. 1988. A knowledge-based system for analysing sedimentary environment. Geological Science and Technology Information 7: 125-130. — 1988. Artificial intelligence and its application to the Guizhou Coal Basin, China. Earth Science 9(3): 350-355. ~ 1990. An object-oriented pattern recognition algorithm. In Zhao, P. D. (ed.): Statistical analysis in mineral exploration, p. 120-123. — 1990. Expert system and its application in sedimentary environment analysis. In Zhao, P. D. (ed.): Statistical analysis in mineral exploration, p. 65-73. Liang, B. and Smith, P. L. 1991. Measurements from ammonoid images using a computer. First Canadian Paleontology Conference, Vancouver, p. 50. — 1992. A Lower Jurassic ammonite image database: applications and implications. Second Canadian Paleontology Conference, Ottawa, p. 16-17. Lohmann, G. P. 1983. Eigenshape analysis of micro fossils : a general morphometric procedure for describing changes in shape. Mathematical Geology 15: 659-672.  References  163  Lupher, R.L. 1941. Jurassic Stratigraphy in Central Oregon. Bulletin of the Geological Society of America, 52: 219-270,4 pi., 3 fig. MacKenzie, J.D. 1916. Geology of Graham Island, British Columbia. Geological Survey of Canada, Memoir 88. Marr, D. 1982. Vision. San Francisco: Freeman. Meister, C. 1986. Les ammonites du Carixien des Causses, France. — Mem. Suis. Paleont, 109, 209 p. ~ 1989. Les ammonites du Domerien des Causses, France. — Analyses paleontologiques et stratigraphiques. - Cahiers Pal. (CNRS edit), 98 p., Paris 1989 McLearn, F.H. 1930. Notes on some Canadian Mesozoic faunas. Transactions of the Royal Society of Canada, series 3, 24:1-7, 2pl. - 1932. Contributions to the stratigraphy and paleontology of Skidegate Inlet, Queen Charlotte Islands, British Columbia. Transactions of the Royal Society of Canada, series 3,26:51-80, 10 pi. Mutvei, H. and Reyment, R. A. 1973. Buoyancy control and siphuncle function in ammonoids. Palaeontology 16(3): 623-636. O'Brien, J. A. 1987. Jurassic biostratigraphy and evolution of the Methow Trough, southwestern British Columbia. B.Sc. thesis, University of British Columbia. Okamoto, T. 1988. Analysis of heteromorph ammonoids by differential geometry. Palaeontology 31: 35-52. Palfy, J. 1991. Uppermost Hettangian to lowermost Pliensbachian (Lower Jurassic) biostratigraphy and ammonoid fauna of the Queen Charlotte Islands, British Columbia.Unpublished M.Sc. thesis, University of British Columbia, Vancouver . Poulton, T.P. 1991. Hettangian through Aalenian (Jurassic) guide fossils and biostratigraphy, northern Yukon and adjacent Northwest Territories. Geological Survey of Canada, Bulletin 410, 95 p., 18 pi. Poulton, T.P. and Tipper, H.W. 1991. Aalenian ammonites and strata of western Canada. Geological Survey of Canada, Bulletin 411, 71 p., 7 pi. Price, D. 1984. Computer-based storage and retrieval of paleontological data at the Sedgwick Museum, Cambridge, England. Paleontology 27: 393-406.  References  164  Quinzio Sinn, L. A. 1987. Stratigraphische Untersuchungen im Unterjura des Sudteils der Provinz Antofagasta in Nord-Chile. Berliner geowissenschaftliche Abhandlungen, Reihe A, 87,105 p. Raup, D. M. 1966. Geometric analysis of shell coiling: general problems. Journal of Paleontology 40(5): 1178-1190. — 1967. Geometric analysis of shell coiling: coiling in Ammonoids. Journal of Paleontology 41(1): 43-65. Raup, D. M. and Crick, R. E. 1981. Evolution of single characters in the Jurassic ammonite Kosmoceras. Paleobiology 7(2): 200-215. — 1982. Kosmoceras: evolutionary jumps and sedimentary breaks. Paleobiology 8(2): 90-100. Raup, D. M. and Sepkoski, J. J. 1986. Periodic extinction of families and genera. Science 231: 833-836. Repin, Y.S. 1968. A new ammonoid genus from the Toarcian of the north-eastern U.S.S.R.. Palaeontological Journal, 3: 139-142. -- 1974. Biostratigraphy of the boreal Mesozoic, U.S.S.R. Academy of Sciences, Siberian Branch, 136:51-66,165-174. Rich, D. 1989. Image storage has geologic applications. Geotimes 34(9): 10-11. Riedel, W. R. and Tway, L. E. 1990. Artificial intelligence applications in paleontology and stratigraphy. In: Agterberg, F. P. and Bonham-Carter, G. F. [ed.]: Statistical applications in the earth sciences. Geological Survey of Canada, Paper 89-9: 383-388. Rock, N. M. S. 1988. Numerical geology : a source guide, glossary, and selective bibliography to geological uses of computers and statistics. Berlin; New York : SpringerVerlag. Rogers, M. J., Donovan, D. T. and Rogers, M. H. 1990. A deductive enquiry system for a palaeotological database of museum material. Palaeontology 33(3): 613-622. Sanborn, A.F. 1960. Geology and paleontology of the southwest quarter of the Big Bend quadrangle. California Division of Mines, Special Report 63: 3-26. Saunders, W. B. 1983. Natural rates of growth and longevity of Nautilus belauensis. Paleobiology 9(3): 280-288.  References  165  Saunders, W. B. and Shapiro, E. A. 1986. Calculation and simulation of ammonoid hydrostatics. Paleobiology 12(1): 64-79. Saunders, W. B. and Swan, A. R. H. 1984. Morphology and morphologic diversity of midCarboniferous (Namurian) ammonoids in time and space. Paleobiology 10(2): 195-228. Savazzi, E. 1990. Theoretical morphology of shells aided by microcomputers. In: Hanley, J. T., Merriam, D. F. eds. Microcomputer applications in geology II: 229-240. Schlegelmilch, R.S. 1976. Die Ammoniten des siiddeutschen Lias. Gustav, Fischer, Verlag, Stuttgart, 212 p., 48 pi. Schlatter, R. 1991. Biostratigraphie und Ammonitenfauna des Ober-Lotharingium und UnterPliensbachium im Klettgau (Kanton Schaffhausen, Schweiz) und angrenzender Gebiete, Schweizerische Palaontologische Abhandlungen, 113, 133 p., 21 pi. Sepkoski, J. J. 1993. Ten years in the library: new data confirm paleontological patterns. Paleobiology 19(1): 43-51. Sey, I.I. and Kalacheva, E.D. 1980. Biostratigraphy of the Lower and Middle Jurassic deposits of the Far East. Ministry of Geology, U.S.S.R., Geological Institute, Nedra, 187 p., 34 pi (in Russian). Smith, P.L. 1976. Biostratigraphy of the Snowshoe Formation (Jurassic) in the Izee area Grant County, Oregon. M.Sc. thesis, Portland State University, 213 p., 7 pi. ~ 1980. Biostratigraphy and ammonoid fauna of the Lower Jurassic (Sinemurian, Pliensbachian and lowest Toarcian) of eastern Oregon and western Nevada. Ph.D. hesis, McMaster University. - 1983: The Pliensbachian ammonite Dayiceras dayiceroides and Early Jurassic paleogeography. Canadian Journal of Earth Sciences 20: 86-91. ~ 1986. The implications of data base management systems to paleontology: a discussion of Jurassic ammonoid data. Journal of Paleontology, 60: 327-340. Smith, P.L., Thomson, R.C. and Tipper, H.W. 1984. Lower and Middle Jurassic sediments and volcanics of the Spatsizi map area, British Columbia, in Current Research, Part A, Geological Survey of Canada, Paper 84-1 A: 117-120. Smith, P.L. and Tipper H.W. 1986. Plate tectonics and paleobiogeography: Early Jurassic (Pliensbachian) endemism and diversity. Palaios 1: 399-412.  References  166  Smith, P.L. and H.W. Tipper 1988. Biochronology, stratigraphy and tectonic setting of the Pliensbachian of Canada and the United States. Second International Symposium on Jurassic Stratigraphy, Lisbon, 1:119-138. Smith, P.L., Tipper, H.W. Taylor, D.G. and Guex, J. 1988. An ammonite zonation for the Lower Jurassic of Canada and the United States: the Pliensbachian. Canadian Journal of Earth Sciences, 25:1503-1523. Smith, P.L. and Westermann, G.E.G. 1990. Paleobiogeography of the Ancient Pacific. Science, 249, p. 680. Spicer, R. A. Computerized palaeobotanical data bases: the way forward? In: Spicer, R. A. and Thomas, B. A. eds. Systematics and Taxonomic Approaches in Paleobotany. Stankevich, E.S. 1964, Ammonites in the Jurassic sandy-clay deposits of the northwestern Caucasus: Moskow-Leningrad, Nauka, 99 p. (in Russian). Stanley, G.D. Jr. and Yancey, T.E. 1990. Paleobiogeography of the Ancient Pacific. Science, 249, p. 680-681. Stanley, G.D. Jr. and Yang, X. N. 1987. Approximate evolutionary stasis for bivalve morphology over millions of years: a multivariate, multilineage study. Paleobiology 13(2): 113-139. Stansfield, S. A. 1986. ANGY: a rule-based expert system for automatic segmentation of coronary vessels from digital subtracted angiograms. IEEE Trans. Pattern Anal. Machine Intell. 8: 188-199. Sutherland Brown, A. 1968. Geology of the Queen Charlotte Islands, British Columbia. British Columbia Department of Mines and Petroleum Resources, Bulletin 54. Swan, A. R. H. and Saunders, W. B. 1987. Function and shape in late Paleozoic (midCarboniferous) ammonoids. Paleobiology 13(3): 297-311. Taylor, D.G. 1988a. Paradiscamphiceras, a new Lower Liassic ammonite genus. Bull. Soc. vaud. Sc.nat. 79:117-122. — 1988b. Middle Jurassic (late Aalenian and early Bajocian) ammonite biochronology of the Snowshoe Formation, Oregon. Oregon Geology 50:123-138. - 1990. Two species of Paracaloceras from the Canadense Zone (Hettangian-Sinemurian) in Nevada (U.S.A.). Bulletin de Geologie Lausanne, 309: 211-219.  References  167  Taylor, D.G., Callomon, J.H., Hall, R., Smith, P.L., Tipper, H.W. and Westermann, G.E.G. 1984. Jurassic ammonite Biogeography of western North America: the tectonic implications. Geological Society of Canada Special Paper 27: 121-141. Thomson, R.C. 1985. Lower to Middle Jurassic (Pliensbachian to Bajocian) stratigraphy and Pliensbachian ammonite fauna of the northern Spatsizi area, north central British Columbia. M.Sc. thesis, University of British Columbia. Thomson, R.C., Smith, P.L. and Tipper, H.W. 1986. Lower to Middle Jurassic (Pliensbachian to Bajocian) stratigraphy of the northern Spatsizi area, north-central British Columbia. Canadian Journal of Earth Sciences, 23, no. 12, p. 1963-1973. Thomson, R.C and P.L. Smith 1992. Pliensbachian (Lower Jurassic) biostratigraphy and ammonite fauna of the Spatsizi area, north-central British Columbia. Geological Survey of Canada, Bulletin 437. Tillman, N. 1917. Die Fauna des unteren und mittleren Lias in Nord und Mittel-Peru. N. Jahrb. Min. 41: 628-712, pi. 21-26. Tipper, H.W. and Richards, T.A. 1976. Jurassic stratigraphy and history of north-central British Columbia. Geological Survey of Canada, Bulletin 270, 73 p. Tipper, H.W., Smith, P.L., Cameron, B.E.B., Carter, E.S., Jakobs, G.K. and Johns, M.J. 1991. Biostratigraphy of the Lower Jurassic formations of the Queen Charlotte Islands, British Columbia. In: Woodsworth, G.J. [ed.]: Evolution and Hydrocarbon potential of the Queen Charlotte basin, British Columbia. Geological Survey of Canada, Paper 90-10: 203-235. Torre, V. and Poggio, T. A. 1986. On edge detection. IEEE Trans, on pattern analysis and machine intelligence 2: 147-162. Tozer, E.T. 1982. Late Triassic (upper Norian) and earliest Jurassic (Hettangian) rocks and ammonoid faunas, Halfway River and Pine Pass map areas, British Columbia. Current Research, Part A, Geological Survey of Canada, Paper 82-1A: 385-391. Wang, Y. and Smith, P. L. 1986. Sinemurian (Early Jurassic) ammonite fauna from the Guangdong region of southern China. Journal of Paleontology, 60: 1075-1085. Ward, P. D. 1981. Shell sculpture as a defensive adaptation in ammonoids. Paleobiology 7(1): 96-100. - 1987. The natural history of Nautilus. Allen and Unwin Inc. Ward, P. D. and Signor, P. W. 1983. Evolutionary tempo in Jurassic and Cretaceous ammonites. Paleobiology 9(2): 183-198.  References  168  Warren, P.S. 1931. A Lower Jurassic fauna from Fernie, B.C. Transactions of the Royal Society of Canada, series 3, 25: 105-111, pi. 1. Westermann, G. E. G. 1966. Covariation and taxonomy of the Jurassic ammonite Sonninia adicra (Waagen). N. Jb. Geol. Palaont. Abh. 124(3): 289-312 — 1971. Form, structure and function of shell and siphuncle in coiled Mesozoic Ammonoids. Royal Ontario Museum Publications in Life Sciences. ~ 1982. The connecting rings of Nautilus and Mesozoic ammonoids: implications for ammonoid bathymetry. Lethaia 15: 373-383. — 1993. Global bio-events in mid-Jurassic ammonites controlled by seaways. In House, M. R. ed. The Ammonoidea — Environment, Ecology, and Evolutionary Change. White, C.A. 1889. On vertebrate fossils from the Pacific Coast. United States Geological Survey Bulletin, pp. 71-98, pi. 13. Whiteaves, J.F. 1876. On some invertebrates from the coal-bearing rocks of the Queen Charlotte Islands. Geological Survey of Canada, Mesozoic Fossils, 1: 1-92 . Whiteaves, J.F. 1884. Mesozoic Fossils: Part Ill-On the fossils of the coal-bearing deposits of the Queen Charlotte Islands collected by Dr. G.M. Dawson in 1878. Geological and Natural History Survey of Canada-Mesozoic Fossils, 1: 1-261,14 pi. Wiedenmayer, F. (1977): Die Ammoniten des Besazio-Kalks (Pliensbachian, Sudtessin). Schweizerische palaontologische Abhandlung, 98: 1-169, 19 pi. ~ 1980. Die Ammoniten der mediterranen Provinz im Pliensbachian und unteren Toarcian aufgrund neuer Untersuchungen im Generoso-Becken (Lombardischen Alpen): Denkshriften Schweizerischen Naturforschenden Gessellschaft, 93, 34 pi. Willard, B. 1963. Ontogeny of the Jurassic ammonite Arietites from Peru. Pennsylvania Academy of Science, 37: 211-215 Younker, J. L. and Ehrlich, R. 1977. Fourier biometrics: harmonic amplitude as multivariate shape descriptors. Syst. Zoology 26: 336-346.  Appendix 1  16<J  Various morphological parameter value combinations and their abundance in the database Ammon The number in table represents the number of occurrences for each pair , light shaded cells show areas of few occurrence, dark shaded cells show areas of particular interest. 1. Expansion Rate~W: (1) Degree of involution ~ VolutionO (V) W/V <1.5 1.5-1.7 1.7-1.9 1.9-2.1 2.1-2.3 2.3-2.5 2.5-2.7 2.7-3.0  <0.1 0.10.2 24 14 139 114 155 207 96 139 45 64 20 19 11  0.20.3  0.30.4  84 207  0.80.9  25  10  57 78  25 35  III!  53  27  42  72 22  18  17  27 23  19 14 11  0.50.6  0.60.7  37  18 85  87 40  41  134 118 56  10 49 113 90 65  I  185  160 180  19  30  34  13  14  84  *.'.'.'.'VV'.'-  3.0-3.3 >3.3  0.70.8  0.40.5  —  .;!.: :.:::. :  12 26  >0.9  11  1  >fc::::::::::::':::::::::::£  (2)WWWH WXWWWH <1.5 1.5-1.7 1.7-1.9 1.9-2.1 2.1-2.3 2.3-2.5 2.5-2.7 2.7-3.0 3.0-3.3 >3.3  <0.6  o 5 23 64 75 66 34 23 5 5  (3) Fineness R a t i o - W W D  0.6-0.8 1 34 163 207 139 82 54 22 6 4  0.8-1.0 5 70 167 163 81 37 7 5 4 7  1.0-1.2 18 67 123 86 32 16 9 5 4 Q  >1.2 10 101 139 79 36 7 5 4 4 :-V^ : : : : : : : : : : : ^ , >: , :->>>v. : . : :. ; :-. : : : : : : ; :; : : : : : :  Appendix 1  (2) Fineness Ratio V\WWD  <0.2  0.20.25  0.250.3  <0.1 0.1-0.2  15 13  60  76 98  0.2-0.3 0.3-0.4 0.4-0.5  54 87  60 38 21  0.5-0.6 0.6-0.7  33  0.7-0.8  19  0.8-0.9 >0.9  10 20  82 80 78  67 51 28 23  0.30.35 48  0.350.4  0.40.45  26  67 81 67 51  37  16 21  49  28  34  17  47  35 18 12  21 18 12  0.450.5  0.50.55  >0.55  10  11 8  m  ... 111ii.111i n  illfc  ill I ' I  12  ;  14  2111  I  ""ill  (3) Primary Rib Density V\PRHW <0.1 0.1-0.2  <10 10 14  0.2-0.3 0.3-0.4 0.4-0.5  20 27 23  0.5-0.6 0.6-0.7  19 14  10-20 170 261 298 254  221 194 139 87  0.7-0.8  30-40  185 185 201 127 106  59  74  57 39  43  0.8-0.9 >0.9  20-30  54  59 60 55 47 24  40-50 12 17 18 19 13 15  50-60 13  >60 14  11  23  (4) Rib Width V\RIB WIDTH <0.1 0.1-0.2  <0.1  0.2-0.3 0.3-0.4  42 48 75 83 73  0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8  0.8-0.9 >0.9  38  39  51 51 10  0.1-0.15 112 127 192 160 143 131 95 69 24  0.15-0.2 132 170 171 150 125 82  62 21 11  0.2-0.25 108 136 122 89 61 45 15 14 ...  >0.25  79 72 78  45 26 19  Appendix 1  171  (5) Primary Rib Form VXPFORM <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  straight 335 378 315 190 98 59 36 34 18 4  concave 36 17 19 32 22 13 9  1111111 0  convex 0 1 2 1 0 2 0 0 0  sinuous 72 87 160 162 148 139 94 48 23 4  projected 8 15 27 29 30 36 17 7 8 1  falcate 4 8 11 11 14 5 6 1  falcoid 11 33 72 68 113 103 87 60 36 4  0  (6) Primary Rib Trend VXPTREND <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  rursiradiate 14 19 16 10 4 1 2  oilii  Ss  01.  grursiradiate rectiradiate 289 38 50 354 416 53 346 33 309 19 257 9 177 5 117 4 57 10  gprorsiradiate 84 80 79 59 56 61 43 20 15  prorsiradiate 37 23 28 27 18 12 5  iiisfpit ..  riP  K  (7) Primary Rib Profile V\PPROF  non weak  <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  11 14 10 37 26 18 21 26 25 29  8 12 24 36 31 39 36 24 22 9  round +weak 2 10 21 28 25 38 36 29 17 1  round  angular  89 168 184 189 194 180 126 57 30 4  62 59 80 60 31 15 3 3  round +strong 38 50 72 38 28 8 4 4 2  a lllllll 0  strong 166 157 125 68 47 14 6 7 0 0  angular +strong 7 7 3 3 1 0 0 0 0  i  Appendix 1  172  (8) Rib Furcation bundled  VXFURC non <0.1 376 423 0.1-0.2 0.2-0.3 459 0.3-0.4 431 0.4-0.5 356  bi  intercalatory  80  0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9  310 224 152 102  >0.9  44  12 31 18 19  99 97 66 68  22 19  42 29 16  multi  tn 15 18 15 16  ioo£_  o:  —r-r  •  li  •iVii'iYriYivriii'iiiVi'iTit  1  niiHiHnnYiYi;  (9) Tuberculation VYTUBERC <0.1 0.1-0.2  non 316  0.2-0.3 0.3-0.4 0.4-0.5  466 458  0.5-0.6 0.6-0.7  346 256 164 110  0.7-0.8  0.8-0.9 >0.9  387  400  urn 145 154 139 68 46 34 20  bi  bullate  clavate  23  25 17 17 10 11  13 10  *  n ntut  ."'•  17 HWWWI  45  (10) Furcation Position V\FURCPOS <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  non 376 423 459 431 355 310 224 151 102 44  I  <0.25 8 14 36 28 28 20 16 4 0 MMmMmmm  0.25-0.5 6 16 31 36 51 45 30 16 6 0  0.5-0.75 30 46 44 33 15 4 7 3 3  >0.75 57 58 42 11 4 3 1 4  &&*?'•" 4  0  -  ItWIII.IIMHI  Appendix 1  173  (11) Unituberculate Position <0.25  WJNITUBPOS <0.1 0.1-0.2  non  0.2-0.3 0.3-0.4  482 474  24 20  0.4-0.5 0.5-0.6 0.6-0.7  409 357 260 181 118  21 21 14  0.7-0.8  0.8-0.9 >0.9  0.5-0.75  >0.75 108 111 79 26  338  412 15 12 11  36 19 17  47  (12) Venter VWENTER <0.1 0.1-0.2  plain 184  0.2-0.3 0.3-0.4  176 128  0.4-0.5 0.5-0.6 0.6-0.7  84 57 38  0.7-0.8  39 26  0.8-0.9 >0.9  carinate-sulcate 85 93 117 102  cannate 131 174 239 248 239  204  sulcate  tncannate  10 12 17  77 28  247  187 112  13 3  ii  55  m  (13) Whorl Shape VYWHORL coro SHAPE <0.1 10 0.1-0.2 14 0.2-0.3 10 0.3-0.4 0.4-0.5  0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  trape  tn  lanceo  0  Wi«M«l.tt.M.i.l.t  11 15  II am i.i.i.i.i.i,i.im  0  33 33 30  quadrate  round  rect  ellips  ogival  oval  42  76 71  16 18  40  66  29 12  52  112 132 142 107  25  49  57 95 154 128 99 71  26 10  35  10 23  74 57  36 16  fiffWW.**}}****  iO  36 48  87 90 87  76 29  28 30 30 42 44 34 22  Appendix 1  174  (14) Shell Diameter VXD <0.1 0.1-0.2 0.2-0.3 0.3-0.4 0.4-0.5 0.5-0.6 0.6-0.7 0.7-0.8 0.8-0.9 >0.9  <3 63 101 146 160 143 111 56 46 12 2  3-6 211 252 270 243 201 171 135 79 43 12  6-9 114 112 136 80 70 64 48 39 27 17  12-15 14 18 19 7 14 6 11 5 6 7  9-12 61 58 39 38 27 24 18 12 18 6  >15 24 31 26 23 11 16 14 7 12 3  3.WWWH (1) Fineness Ratio WWWHXWWD  <0.2  <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  36 29 7  111!!  0.20.25 130 189 84 31 5  0.250.3 87 286 173 67 21  0.30.35 22 127 161 118 53  0.35 -0.4 0 31 61 71 81  0.40.45  li £i 6 11 26 79  0.45 -0.5 1  1  5 7 38  0.50.55  >0.55  ill  I  7 8 39  3 8 62  Bllllli  (2) Primary Rib Density WWWHXPRHW <10 <0.6 \_4 0.6-0.8 23 0.8-1.0 23 1.0-1.2 31 >1.2 53  10-20 J 112 348 327 217 177  20-30 67 206 156 96 88  30-40 51 85 34 28 38  40-50 11 25 7 10 17  50-60 9 12 5 2 4  >60 10 8 5 8 8  (3) Rib Width WWWHXRIBWIDTH <0.6 0.6-0.8 0.8-1.0  <0.1 81 96 45  0.1-0.15 91 223 111  0.15-0.2 40 201 155  0.2-0.25 12 100 140  >0.25 2 26 62  n&  Appendix 1  97 77  63 74  23 21  1.0-1.2 >1.2  79 96  82 92  (4) Primary Rib Form WWWHXPFORM <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  straight 28 164 288 257 319  concave 4 16 38 26 13  convex projected 111111111 19 56 2 24 1 8 1 6 2  sinuous 82 257 121 37 16  falcoid 87 132 29 6  falcate 5 20 8 7 0  (5) Primary Rib Trend WWWH \PTREND <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  rursiradiate  grursiradiate  rectiradiate  gprorsiradiate  2 11 16 11 7  11 43 49 27 11  163 468 343 230 217  35 99 62 49 72  prorsiradiate 2 9 34 20 Lao,  j | j  (6) Primary Rib Profile WWWTTXPPROF  non  weak  <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  43 37 17 6 17  43 57 21 11  round +weak 32 68 16 5 0  round  angular  108 306 154 76 67  4 31 73 46 33  round +strong 5 52 47 34 22  strong  angular +strona  ->  49 110 115 176  6 2 3  (7) Rib Furcation WWWHXFURC <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  non 280 595 470 307 214  bundled 8 55 12 10 3  bi 13 84 84 65 131  intercalatory 3 6 3 3 0  tri 10 5 4 14 41  multi 3 4 3 2 12  loop 2 7 4 4  Appendix 1  176  (8) Tuberculation WWWHXTUBE RC <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  non  uni  bi  bullate  354 650 431 275 197  21 111 127 106 193  18 45 34 30  11 8 8 2  clavate  i>. i)  0  :Q;:m:^y-  (9) Furcation Position non 279 595 469 307 214  WWWHYFURCPOS <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  <0.25 6 56 19 17  4 W  0.25-0.5 18 70 26 12 14  0.5-0.75 4 11 30 20 76  >0.75 7 13 30 43 94  0.5-0.75 3 8 23 17 81  >0.75 7 50 86 78 105  (10) Unituberculate Position WWWHMJNITUBPOS <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  <0.25 7 48 17 12 3  non 354 668 476 309 225  0.25-0.5 5 16 9 7 11  (11) Venter WWWHWENTER  plain  carinate  <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  46 159 235 214 332  261 479 225 108 46  carinatesulcate 13 114 117 78 34  sulcate  tricarinate  8 16 17 12 3  M^WSMh^ 2 6 7 7  Appendix 1  177  (12) Whorl Shape WWWHX WHORL SHAPE <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  coro  trape tri  0 0 2 7 51  0 4 9 3 6  lanceo  77 10 14 12 1 1 0 0 2 0  quad -rate 0 0 140 82 0  round  rect  ellips  ogival  oval  0 0 167 169 83  69 220 40 35 91  42 226 74 59 164  116 183 53 15 1  49 92 45 22 3  (13) Shell Diameter WWWHXD <0.6 0.6-0.8 0.8-1.0 1.0-1.2 >1.2  <3 39 128 125 93 139  4. Fineness Ratio (1) Primary Rib Density  3-6 121 311 252 178 188  6-9 94 170 128 80 67  9-12 51 91 52 29 11  12-15 26 39 17 12 6  >15 44 51 37 31 14  Appendix 1  178  (2) Rib Width 0.1-0.15 21 122 165 120 47 23 10 11 10  <0.1 11 64 88 42 17 8 4 8 11  WWD\RIBWIDTH <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  0.15-0.2 21 88 183 129 60 31 10 10 8  0.2-0.25 6 65 110 103 56 23 12 9 19  >0.25 2 34 49 55 46 28 12 11 16  (3) Primary Rib Form WWDVPFORM  straight  <0.2 0.2-0.25 0.25-0.3  27  0.3-0.35 0.35-0.4 0.4-0.45  0.45-0.5 0.5-0.55 >0.55  156 222 233  153 88 39  concave  convex  projected 22 44 22  15 19 26 15  sinuous 15 109  falcoid  200  63 90  110  47  34  15  falcate  15 11  13  37  49  (4) Primary Rib Trend WWDVPTREND rursiradiate <0.2 0 0.2-0.25 10 0.25-0.3 13 0.3-0.35 9 0.35-0.4 6 0.4-0.45 3 0.45-0.5 iiiiiiiiii 0.5-0.55 0 >0.55 1  grursiradiate 10 38 34 29 12 4 4  7,  T~"'  rectiradiate 33 257 419 311 156 70 30 33 38  gprorsiradiate prorsiradiate iplllltiiiiisssi 15 48 12 89 20 68 24 26 26 23 11 ! 11 3 8 5 9 9  Appendix 1  179  (5) Primary Rib Profile WWD\ PPROF <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  non weak 10 37 20 22 12 7 2 2 9  round +weak :2 ., : 32 45 23 10  6 43 41 24 9 2 4  111111 111  llllll! UL 0 0  round  angular  round+strong  strong  24 154 244 143 49 23 8 21 11  5 20 47 56 31 10 1 3  ;  4 44 89 98 71 53 26 19 34  llllll!  27 49 39 16 5 2 2 3  angular +strong ; 0 2 2 2  1111111 0 1 0 1  (6) Furcation WWD\FURC <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  non 66 338 473 378 165 66 22 18 28  bundled  llllllllll 27 33 12 8 3 2 0 i  bi 3 41 95 72 54 39 21 21 18  intercalatory $  2 2 3 4  ;0i;lllllllll!llll| |ll i;'lllllllllll 0  iiiiiiiiiiiii  tri 3 6 12 10 9 11 4 5 12  multi  loop 0 1 3 0 1 1  0 •:  4 5 *  0 1 2 3 8  Ills 4 6  (7) Tuberculation WWDYTUBERC <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  non 71 344 490 369 153 57 21 22 20  uni 10 83 122 89 78 52 25 20 29  bi  bullate  WiMmmmWm  wmmmm  ii 13 21 12 12 5 12 23  6 13 4 2 2  clavate mm  0 0  WmWmWi,:M 1  °  ll;i;illl||| 1 o o 0  l  !  Appendix 1  180  (8) Furcation Position WWD\FURCPOS <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  0.25-0.5 1 I 216 27 58 30 27 18 16 9 8 6 2 2 \ 16 3  0.5-0.75  <0.25  non 66 338 473 377 164 66 22 18 28  o ' ;;|ff|| 15 22 19 17 14 14 13 23  >0.75 4 20 38 34 30 26 11 9 12  (9) Unituberculate Position WWD\UNITUBPOS <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55 (10) Venter  non 71 355 503 389 165 69 25 34 43  <0.25 1 24 29 12 7 6  ft ' 0  0.25-0.5 5 15 8 6 5 1 2 5  0.5-0.75  III 111111 13 14 15 21 13 14 11 18  >0.75 9 47 77 59 47 30 11 7 7  Appendix 1  181  (11) Whorl Shape WWD\ WHORL SHAPE <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4  coro trape  lanceo  tn  quad -rate  round  rect  ellips  14 116 129 86  27  13  1  17  31  19 10  27  52 74 58 27  56  1 H  14 12  0.4-0.45 0.45-0.5 0.5-0.55  48  1  44 23  23  104 145 96 51  11  27  >0.55  2  (12) Shell Diameter  <3  <0.2 0.2-0.25 0.25-0.3 0.3-0.35 0.35-0.4 0.4-0.45 0.45-0.5 0.5-0.55 >0.55  1  6-9 15 119 144 91 34 12 6 6 9  3-6 22 140 295 219 112 61 23 18 19  40 100 121 83 41 20 26 39  >15 11 17 29 43 16 26 11 18 1 10 4 3 ;6:.:Il!III§lf 0 3 11 3 0  9-12  12-15  15 73 57 23 6 2 3  o 3  5. Primary Rib Density (1) Rib Width PRHWXRIBWIDTH <10 10-20 20-30 30-40 40-50  50-60 >60  <0.1 108 105 148 76 54 56  0.1-0.15 16 411 475 209  30 53 43 22  :  28 40  WWDVD  oval  25  .••  i  ogival 18 71 166 58 10  0.15-0.2 29 571 397 69  0.2-0.25  >0.25  29  78 307 32  502  167 10  54 "in  11  0  MIMIMIMMMIIM  Appendix 1  182  (2) Primary Rib Form PRHWXPFOR M <10 10-20 20-30 30-40 40-50 50-60 >60  straig ht 114 947 572 167 44 17 20  concav conve e X 2 1 105 5 59 11 5 fci- '"••  111111 i> m"  projecte d 8 121 41 13 ||  iinn  Hip  sinuou falcoid s 30 .1 495 172 300 186 144 92 42 40 15 29 14 22  falcate 0 33 12 7 4 1 3  (3) Primary Rib Trend PRHWXPTREND <10 10-20 20-30 30-40 40-50 50-60 >60  rursiradiat e 5 52 28  grursiradiate 10 147 71 18 5  rectiradiate gprorsiradiat e 112 17 1302 212 787 215 302 80 89 27 39 9 29 16  (4) Primary Rib Profile PRHW\ PPROF <10 10-20 20-30 30-40 40-50 50-60 >60  weak 9 101 61 28 9 5 2  round+ weak 7 90 69 32 7 6  o m  round  angular  45 673 373 148 49 19 24  10 175 151 28 12 7 3  round +strong 14 152 78 19 4 I  strong 48 363 228 87 18 11 8  angular +strong 2 9 7 4 4 •iSSSSif:  prorsiradiate 6 83 37 22 8 10 14  Appendix 1  183  (5) Rib Furcation  (6) Tuberculation PRHWYTUBERC <10 10-20 20-30 30-40 40-50 50-60 >60  non 76 1464 1003 384 120 54 52  uni 62 411 204 74 22 12 11  bi 27 99 28 :  i  ;""»  i. > 2 3  clavate 2 1  bullate 2 35 10 ill 1 • 1 0 0  in .0  W" 0  (7) Furcation Position PRHWXFURCPOS <10 10-20 20-30 30-40 40-50 50-60 >60  non 120 1527 1002 372 115 57 60  <0.25 16 128 6 3 3 1 1  0.25-0.5 19 181 36 9 2 1  llllllll  0.5-0.75 7 80 89 31 8 V . ,.  2  >0.75 7 71 99 42 15 8 2  (8) Unituberculate Position PRHWYUNITUBPOS non 102 <10 1560 10-20 20-30 1031 30-40 385 120 40-50 50-60 56 >60 55  <0.25 17 99 3 1 3  0 0  0.25-0.5 15 47 5 4 -,7;---•--;-•;--  6' *  0.5-0.75 17 77 49 14 6 6 7  >0.75 18 227 157 56 14 6 4  -m  Appendix 1  184  (9) Venter PRHWWENTER  plain  carinate  <10 10-20 20-30 30-40 40-50 50-60 >60  65 524 296 115 40 28 31  72 888 484 203 54 20 22  carinatesulcate 11 256 239 81 29 9 5  sulcate  tricarinate  2 32 44 7  2 11 9 "  6  (10) Whorl Shape PRHW\ WHORL SHAPE <10 10-20 20-30 30-40 40-50 50-60 >60  coro  trape tri  6 27 16 6  11 8 2 0 111111 0 0 1 0 0  lanceo  •  0 36 35 24 9 11 0 3 0 8 £> 5 0  quad roun -rate d  rect  ellips  24 132 49 16 4 2 5  13 230 225 138 53 15 8  40 394 272 80 20 11 9  21 212 116 25 9 5 10  ogival 19 279 126 55 13 6 8  (11) Shell Diameter PRHW\D <10 10-20 20-30 30-40 40-50 50-60 >60  <3 79 540 220 67 10 2 1  6. Rib Width  3-6 66 893 584 183 46 17 6  6-9 19 301 234 133 58 29 22  9-12 4 129 109 42 15 14 16  12-15  .0  45 41 18 6 3 8  >15  I 90 55 17 7 3 13  oval 9 148 81 25 6  ill 5  185  Appendix 1  (1) Primary Rib Form RIBWIDTH \PFORM <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  straight  concave  convex  projected  sinuous  falcoid  falcate  148 459 525 433 320  16 45 57 46 17  0 *P  30 50 50 37 16  141 382 286 131 48  188 222 134 39 13  11 11 18 19 1  0 1 4 1  (2) Primary Rib Trend RIBWIDTH \PTREND <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  rursiradiate  grursiradiate  rectiradiate  gprorsiradiate  prorsiradiate  4 20 18 33 11  13 73 63 63 40  347 791 760 469 296  102 195 146 89 47  30 47 55 32 17  (3) Primary Rib Profile RIBWIDTHXPPROF weak <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  74 81 39 16 3  round +weak 49 93 52 13 4  non 393 837 844 593 370  bundled 21 60 29 11 6  round 185 392 397 234 124  angular round+ strong 6 37 39 159 74 119 77 49 20 73  strong 56 176 197 190 151  angular+ strong 9 8 5 3 3  (4) Rib Furcation RIBWIDTHXFURC <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  bi 95 217 171 82 31  intercalatory 5 16 5 4  IlllllllllII  tri 18 39 15 16 8  multi 5 8 7 5 6  loop 15 3 3 2 1 $!  186  Appendix 1  (5) Tuberculation RIBWIDTHMUBERC <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  non 454 924 824 507 261  bi 29 21 30 30 45  uni 65 216 207 167 111  bullate 4 19 12 9 3  clavate 0  s& 1 0 2  (6) Furcation Position <0.25 23 82 41 8 4  non 392 837 844 593 369  RIBWIDTH\FURCPOS <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  0.25-0.5 53 90 67 25 12  0.5-0.75 39 78 59 26 14  >0.75 28 83 57 55 21  (7) Unituberculate Position RLBWIDTH\UNITUBPOS <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  non 483 943 853 537 305  <0.25 13 60 34 7 3  0.25-0.5 10 21 19 12 8  0.5-0.75 20 50 40 27 32  >0.75 26 106 128 130 74  (8) Venter RIBWIDTHWENTER <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  plain 138 243 246 225 170  carinate 243 542 462 271 129  carinate-sulcate 60 193 188 99 53  sulcate 19 26 19 9 3  tricarinate 2 5 7 6 3  187  Appendix 1  (9) Whorl Shape RTBWTDTHX WHORL SHAPE <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  coro  trape  tri  lanceo  2 10 14 19 8  3 3 11 3 0  42 32 7 3 0  *  17 20 5  ill!!*  quad -rate 15 40 56 62 49  round  rect  ellips  27 63 86 76 94  117 230 166 99 33  55 222 241 148 92  ogival 87 164 134 78 21  oval 53 86 58 34 22  (10) Shell Diameter RTBWIDTHVD <0.1 0.1-0.15 0.15-0.2 0.2-0.25 >0.25  3-6 191 561 492 309 181  <3 57 205 254 220 149  9-12 68 99 80 41 16  6-9 162 234 184 103 61  12-15 32 36 20 12 6  >15 38 39 42 25 9  7. Primary Rib Form (1) Primary Rib Trend PFORMXPTREND straight concave convex projected sinuous falcoid  rursiradiate 56 3 0 11 11  falcate  5  1  grursiradiate 126 7 2 18 54 33 12  rectiradiate gprorsiradiate 1229 336 42 74 fi 2 100 26 89 784 73 458 24 13  (2) Rib Profile PFORMX PPROF straight concave convex  projected sinuous falcoid falcate  weak 66 7 0 7 81 46 2  round+ weak 23 3 0 2 81 100 3  round  angular  422 33 4 92 480 284 17  239 52 0 14 62 19 0  round+ strong 91 4 ,  11 90 54 19  strong 637 27 £ 15 60 12 12  angular+ strong 22 2 0  1 2 0 1  prorsiradiate 101 48 1 8 21 I 0  Appendix 1  188  (3) Rib Furcation PFORMXFURC straight concave convex projected sinuous falcoid falcate  non 1362 163 5 162 744 540 56  bundled 12  &P 1 '""  3 101 10 0  bi 408 11 1 4 120 39 5  intercalatory 9 3 .....  *  tri 78 4  multi 21  o  1:  1•  U  0  6 5  -  H  1iO  4 7 3  4 9 5  o"  loop 9  (4) Tuberculation  (5) Furcation Position  PFORMXFURCPOS straight concave convex projected sinuous falcoid falcate  non 1361 163 5 162 743 540 56  0.25-0.5 0.5-0.75 >0.75 194 226 74 3 7 6 0 i 1111 1 ^ 3 7 4 4 15 105 112 5 12 E&^^HI^SS^EA^^H 1 1 3 0  <0.25 34 1  (6) Unituberculate Position PFORMXUMTUBPOS  non  <0.25  0.25-0.5  straight concave convex projected sinuous falcoid falcate  1285 164 5 170 821 589 60  24 i:  31  |  1  lj§§|f ro 0 86 5  0.50.75 152  37 2  11111 i  ;  lilt  iilllll  3 14 •  •I  >0.75 407 16 1 10 33 iliiii  0  :;.V*:•:.>;•:•:-:•.  5  ••/  ••••  ;•:•:•:••:•;'::•>  189  Appendix 1  (7) Venter plain 824 60 4 34 77 24  PFORMXVENTER straight concave convex projected sinuous falcoid falcate  carinate-sulcate 200 40 0  carinate 445 31 2 109 627 397 | 36  K£2i-:-:v:-:-Xv '  .:-:•:-:•::--'-'-:-'-'  sulcate 55 12  tricarinate 8 5  ft sp m *>  IB l:o  18  167 154 23  1*  (8) Whorl Shape PFORMX WHORL SHAPE straight concave convex projected sinuous falcoid falcate  coro  trape  tri  lanceo  51  18  III 1 1  0  11 2  lllllll  0  •  wzii 0  16 o 28 4 26 39 1 0  iiii 1 2 111111111111 111111 1 1 1 1 1 1  quad -rate 146 10  •5 1  111!  43 9 4  round  rect  ellips  283 40 1 4 16 2  155 4 1 15 227 211 31  451 44 2 20 198 45 2  lllllll  ogiva 1 94 4 1 58 227 95 6  (9) Shell Diameter PFORMXD straight concave convex projected sinuous falcoid falcate  <3 468 26 3 41 227 112 6  8. Primary Rib Trend  3-6 814 66 3 74 472 270 22  6-9 357 38 0 33 170 130 15  9-12 129 23 Q 20 76 48 7  12-15 48 4 : • : • •  :  :  •  10 18 21 3  .  >15 76 21 0 5 28 15 8  oval 88 11  Ml 10 82 61 1  Appendix 1  (1) Rib Profile PTRENDV PPROF rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  weak 3 9 144 27 5  rounds- round weak III 22 5 85 173 981 23 171 50 1  angular roundsstrong 19 15 40 40 244 182 52 19 31 4  strong  angular+ strong  16 45 497 147 47  111111 4 19 4  (2) Rib Furcation PTRENDVFURC rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  non 78 206 2071 409 146  bundled 1 4 111 9 0  intercalatory 0  bi 4 29 376 136 29  22 5  •llllliill  tri 2 9 64 12 5  multi 1 2 19 8  t>  (3) Tuberculation PTRENDYTUBERC rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  non 64 182 2021 423 132  uni 16 46 515 134 49  bi 4 19 102 18  bullate 2 4 35 6  0  i::iiiiiiii  clavate 0 1 2 0 0  (4) Furcation Position PTREND\FURCPOS  non  <0.25  rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  78 206 2069 409 146  3 16 112 19  1  0.250.5 2 8 167 43 8  0.5-0.75  >0.75  1 1 145 56 12  2 19 157 50 13  loop 0 1 12 2 1  .  Appendix 1  191  (5) Unituberculate Position non 68 200 2120 441 132  PTREND\UNITUBPOS rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  <0.25  0.25-0.5  umM l l l l l l l ii 90 12  2 56 9  i)  0.5-0.75  £.. 7 112 30 17  >0.75 12 32 297 89 32  (6) Venter plain 7 22 623 222 126  PTRENDWENTER rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  carinate 35 117 1235 198 23  carinate-sulcate 29 80 396 66 9  sulcate  tricarinate •0: 111111 2 lllllll 4 17 61 7 1 2  (7) Whorl Shape PTRENDVWHORL SHAPE rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  llllll lllll 27 16 10  lanceo quad -rate 0 9 0 0 2 2 lllllll 24 163 11 59 41 18 5 11 10 o ••": 11 o' 111 3  trape  coro  tri  roun d 4 15 207 76 37  rect  ellips  ogival  oval  20 55 473 85 4  15 34 520 119 65  9 34 364 58 6  8 11 187 34 8  (8) Shell Diameter PTREND\D rursiradiate grursiradiate rectiradiate gprorsiradiate prorsiradiate  <3 8 29 656 114 36  9. Primary Rib Profile  3-6 33 114 1179 265 76  6-9 22 56 479 120 42  9-12 12 28 187 48 20  12-15 5 10 57 14 5  >15 6 13 109 18 2  Appendix 1  192  (1) Rib Furcation PPROFVFURC non weak round+weak round angular round+strong strong angular+strong  non 230 215 184 1081 336 231 440 15  bundled (j "jjjg 8 6 79 5 5 6  l l * >':  bi  intercalatoiy  0  0  23 17 133 34 29 253 13  4 3 5 |K„ 3 3  W8M  >\ r ,  • f  tri 0 1 2 21 6 1 44  multi  loop  ill 0  0 ,^ : 1  b 10 4 U 14  WHH 6 1 0 10  •til  W  (2) Tuberculation PPROFYTUBERC non weak round+weak round angular round+strong strong angular+strong  non 225 232 195 1046 312 237  uni 3 16 7 220 62 25  bi 1 3 7 54 3 5  bullate 1 1 3 15 9 2  21  6  $  wmmm  clavate  10 0 '" »  >  ;0"'i  0 0 1 1  (3) Furcation Position  (4) Unituberculate Position PPROFttJNITUBPOS non weak round+weak  non 226 235 202  <0.25 §§§§; 6 9  0.25-0.5 0 • 4 1  0.5-0.75 3 0 Q ;:"."  >0.75  1  7  •  Appendix 1  round angular round+strong strong angular+strong  30 10 8 100 3  28 3 3 13 1  72  1099 315 241 439 21  193  I7lllll 7 0  106 57 10 211 3  (5) Venter plain 85 59 16 235 82 29 444 9  PPROFWENTER non weak round+weak round angular round+strong strong angular+strong  carinate-sulcate 5 15 24 174 96 77 71 5  carinate 50 124 161 787 114 136 130 6  sulcate 3  tricarinate  0  3 2 4 2 6 2 1  6 43 0 3 3  "  (6) Whorl Shape PPROFWVHORL SHAPE non weak round+weak round angular round+strong strong angular+strong  coro  trape  lance  tri  0  1  2  ill! 1.6 0  4 13  BB 31 |3  6  | |f 1 6  46 22 11 27 3  jjjj 0  7 5 2 29 0 5 0  Illlll  quad -rate  •  2 1 49 20 34 78 6  roun d 28 14 2 68 53 15 110 2  rect  ellips  ogival  oval  13 29 41 251 68 81 74 5  33 47 46 259 64 59 171 5  28 46 53 265 29 15 44  10 31 32 96 25 14 20 1  Illlll!  (7) Shell Diameter PPROFXD <3 non 53 weak 64 round+weak 46 286 round 76 angular round+strong 42 171 strong angular+strong 2  3-6 82 110 98 550 194 118 355 13  6-9 37 35 39 274 62 61 160 5  9-12 21 20 16 128 24 25 46 3  12-15 11 11 5 42 7 11 14 1  >15 25 12 8 53 21 12 16 4  Appendix 1  194  10. Rib Furcation (1) Tuberculation FURC\TUBERC non bundled bi intercalatory tri multi loop  non 3017 31 326 26 18 7 2  uni 386 85 243 1 67 18 7  bi 113 1 14 3 10 7 14  bullate 25 10 14  clavate 2 B  if*! 0  1 •0  1  0  (2) Unituberculate Position FURCUJNITUBPOS non bundled bi intercalatory tri multi loop (3) Venter  non 3130 32 336 29 28 14 16  <0.25 11 68 37  0.25-0.5 2 27 27 111 0 6 10 111 5 0  o '"K  0.5-0.75 67  >0.75 333  111  Hfc  79 1 21 12 1  118 Q  31  ililllli! 7  Appendix 1  195  (4) Whorl Shape  (5) Shell Diameter FURC\D non bundled bi intercalatory tri multi loop  3-6 1501 46 279 7 39 10 13  <3 802 8 147 4 13 9 0  9-12 285 19 35 4 8 4 0  6-9 665 32 111 7 28 4 4  12-15 106 7 10 0 3 5 3  >15 174 15 9 8 5 0 4  11. Tuberculation (1) Furcation Position non 3017 384 113 25 2  TUBERCVFURCPOS non uni bi bullate clavate  <0.25 57 82 5 14  0.25-0.5 163 70 6 9  illillll o  0.5-0.75 110 97 8 2 0  >0.75 61 169 14  Illliill!  (2) Venter TUBERCWENTER non uni bi bullate clavate  plain 699 448 112  1 0  carinate 1647 219 31 10 0  carinate-sulcate 557 50 7 34 1  sulcate 91 2  0 0 0  tricarinate 19 <J 1 2 2  Appendix 1  196  (3) Whorl Shape  (4) Shell Diameter TUBERCVD non uni bi bullate clavate  3-6 1528 353 54 15 1  <3 810 168 26 5 2  9-12 273 77 18 11  6-9 665 159 50 5  12-15 111 25 6 4 0  0  W ;o  <0.25 11 98 14  0.25-0.5 2  0.5-0.75 67  62 7  2 89 23  >15 174 37 14 10 0  12. Furcation Position (1) Unituberculate Position FURCPOS\UNITUBPOS non <0.25 0.25-0.5 0.5-0.75 >0.75  non 3130 59 168 118 75  ill;;!:  Bill •  >0.75 331 1 2 3 146  (2) Venter FURCPOSWENTER  plain  carinate  carinate-sulcate  sulcate  tricarinate  non <Q,25 0.25-0.5  761 3 24  1541 89 150  542 55 36  71 1 13  22 j. . " 1  Appendix 1  197  (3) Whorl Shape FURCPOSV WHORL SHAPE non <0.25 0.25-0.5 0.5-0.75 .0.75  lanceo  coro trape tri 16  15 1 2  0 2 13 27  128 51 5 %»> 3 0 0  a11111ii ii  quad -rate 154 17 12 9  im •  round  rect  ellips  358 3 7 28 31  591 35 36 15 13  652 29 38 82 68  ogival 422 41 54 12 16  oval 222 10 37 4 10  (4) Shell Diameter FURCPOSVD non <0.25 0.25-0.5 0.5-0.75 >0.75  <3 801 10 46 71 50  6-9 665 43 43 34 58  3-6 1501 52 118 92 115  9-12 285 29 15 11 12  12-15 106 7 10 4 5  >15 173 16 13 3 4  13. Unituberculate Position (1) Venter UNITUBPOSWENTER non <0.25 0.25-0.5 0.5-0.75 >0.75  carinate 1678 84 33 20 92  plain 811 1 14 141 293  carinate-sulcate 561 34 19 5 30  sulcate 91 1 0 0 1  tricarinate 19 1 O :  e:!lllllilllll 4  (2) Whorl Shape UNITUBPOS\ WHORL SHAPE non <0.25 0.25-0.5 0.5-0.75 >0.75  coro trape  tri  lanceo  8  21 4 1  135 4 1  54  0  fli 1  111 4 16 35  0  111 o i>  pSK;  quad -rate 135 14 8 13 71  roun d 376 3 2 26 53  rect  ellips  622 25 9 16 59  719 19 13 65 100  ogival 479 41 9 6 28  oval 280 7 10 5 7  Appendix 1  198  (3) Shell Diameter UNITUBPOSU) non <0.25 0.25-0.5 0.5-0.75 >0.75  <3 836 4 14 53 104  6-9 715 36 10 25 93  3-6 1580 37 35 81 218  9-12 290 27 5 12 45  12-15 116 6 4 8 12  >15 188 14 3 5 25  14. Venter (1) Whorl Shape VENTER\ WHORL SHAPE plain carinate carinate-sulcate sulcate tricarinate  coro  trape  tri  63  13 11 2  26 $< 50 48  1 11111 0 ill! III 111111ill!!  i"  0 0  lanceo  ;  11 0 0  quad -rate 92 60 75 1 10  round  rect  279 96 56 17 3  79 395 229 8 2  ellips ogi- oval val 398 55 71 365 445 179 106 19 35 27 24 8 3 5 0  (2) Shell Diameter VENTER\D plain carinate carinate-sulcate sulcate tricarinate  15. Whorl Shape  <3 326 381 77 36 2  3-6 512 854 264 35 10  6-9 247 366 141 10 2  9-12 88 156 70 4 5  12-15 28 64 34 1 0  >15 58 85 63 5 5  199  Appendix 1  (1) Shell Diameter WHORL SHAPEXD coro trape tri lanceo quadrate round rect ellips ogival oval  <3 11 7 19 14 49 114 113 228 98 64  3-6 38 7 43 26 98 210 280 363 277 128  6-9 7 7 35 8 49 75 193 183 88 53  9-12 2 1 19 4 14 30 77 68 55 26  12-15 1 1 12 2 10 12 31 22 21 10  >15 4 3 13 0 21 19 37 52 23 28  Appendix 2 Source code for the user interface of Ammon  200  Appendix 2 Source code for the graphics interface of Ammon There are 13filesin this program: ammon.h, retrieve.h, retrieve.c, amenu.h, amenu.c, display.c, query.c, dbms.c, misc.c, utility.h, utility.c, win.h, win.c: 1. ammon.h: /* Header file for Ammon graphics interface * and interactive image measurement module. *  * Author: Bo Liang * Department of Geological Sciences * The University of British Columbia * Date: September 1992 * Modifications: April 1994 *  */  #include <stdio.h> #include <ctype.h> #include <math.h> #include <suntool/tty.h> #include <suntool/alert.h> #include <suntool/sunview.h> #include <suntool/panel.h> #include <suntool/canvas.h> #include <suntool/scrollbar.h> #include <suntool/textsw.h> /* the maximum number of specimens allowed for each query return */ #define MAX_SP 1000 /* the maximum number of images allowed for each query return, since one specimen can have multiple images, MAXNUM+1000 gives extra room to accomondate images */  #define MAXJMAGE  MAX_SP+1000  /* define the array index for descriptor_name */ #define IMAGE #define SCALE #define WHORLSHAPE #define ONTOGENY #define APPROX  35 36 52 61 68  /* active descriptors in Ammon */  Appendix 2 Source code for the user interface of Ammon  char*  descriptor_narne[]={MSUPERFAMILY^"FAMILY","SUBFAMILY",,,GENUS,,, "SUBGENUS", "QUALIFIER", "SPECIES","SUBSPECIES", "TAXAUTHYEAR", "REFAUTHYEAR", "SYNONYMY", "SYNSPECIES","STAGE","SUBSTAGE","EURZONE", "EURSUBZONE","ZONE","SUBZONE", "HORIZON", "FORMATION", "MEMBER","SITU",,,ASSOCSPEC","AREA", "COUNTRY","PROVINCE","SECTNAME","SECTNO","LOCNO", "OTHERNO","REPOSITORY",,,TYPE", "GENERALOC", "SPECNO", "REMARKS 1", "IMAGE","SCALE", "DMAX", "D", "UD","U", "EXP","WH","WHD", "WW","WWD","WWWH", "PRHW", "SRHW","THW","BISPACE","CHWH,"WHORL_SHAPE", "UWALLHT", "UWALLANG","VENTER",,,PTREND","PFORM", "PPROF","FURC","TUBERC","ONTOGENY","MAXWH", "RIBWIDTH","FURCPOS0","UNITUBPOS0",HEXP0,,, "VOLUTION0", "APPROX"};  #define NUM_OF_DESCRIPTOR  sizeof descriptor_name/sizeof descriptor_name[0]  /* the field length of the above descriptors */ short  201  len[]={ 19,17,22,20,20,15,30,20,30,40,22,30,25,40,30,30,30,20,25,30,20,2, 6,20,20,30,50,25,20,14,40,14,80,30,200,50,4,6,6,6,5,5,6,5,6,5,5, 4,4,4,5,4,30,4,8,16,14,30,16,12,10,4,3,3,5,3,4,3,40};  /* The following data arrays are used to initialize the menu */ /* ammanite family list in Ammon, new families may be added */ static char  *farnily[]={"Psiloceratidae","Schlotheimiidae","Arietitidae", "Echioceratidae"," Oxynoticeratidae"," Cymbitidae", "Eoderoceratidae","Coeloceratidae","Phricodoceratidae", "Polymorphitidae","Liparoceratidae","Amaltheidae", "Dactylioceratidae", "Hildoceratidae", "Phymatoceratidae", " Graphoceratidae"," Sonniniidae"," Cardioceratidae", "Erycitidae","Kosmoceratidae","Otoitidae", "Sphaeroceratidae","Stephanoceratidae","Oppeliidae", "Perisphinctidae", "Reineckeiidae", "Discophyllitidae", "Phylloceratidae", "Lytoceratidae", "Family uncertain"};  /* genus list in Ammon, if add new genus, make sure you update num_of_j*enus_in_family which can be tedious, better way to do it ? */  static char  *genus[]={"Alsatitoides","Badouxia","Caloceras", "Discamphiceras","Euphyllites","Laqueoceras","Mullerites",  Appendix 2 Source code for the user interface of Amnion "Paradiscamphiceras","Parapsiloceras","Psiloceras", "Psilophyllites","Saxoceras","Transipsiloceras", " Angulaticeras", "Kammerkaroceras"," Schlotheimia", "Sulciferites","Waehneroceras","Aegasteroceras", "Agassiceras","Alsatites","Arietites","Arnioceras", "Asteroceras","Caenisites","Canavarites","Coroniceras", "Defossiceras'V'Eparietites'V'Epophioceras'V'Euagassiceras", "Metarnioceras","Pompeckioceras","Pseudaetomoceras", "Pseudasteroceras", "Pseudotropites"," Sunrisites", "Tmaegoceras","Vermiceras,,5"Dubariceras","Echioceras", "Gagaticeras","Leptechioceras",',PalaeoechiocerasH, "Paltechioceras", "Protechioceras"," Tmaegophioceras", "Cheltonia", "Fanninoceras"," Gleviceras"," Oxynoticeras", "Paracymbites'V'Paroxynoticeras'V'Radstockiceras", H Slatterites","Cymbites","Bifericeras","Crucilobiceras", "Eoderoceras","Exomiltoceras","Metaderoceras", "Microderoceras"J"Miltoceras","Promicroceras", "Pseudoskirroceras", "Xipheroceras"," Apoderoceras", " Coeloceras", "Hyperderoceras", "Pimelites", "Praesphaeroceras", "Tetraspidoceras","Epideroceras","Phricodoceras", "Acanthopleuroceras","Dayiceras","Eoamaltheus", "Gemmellaroceras","Parinodiceras","Peripleuroceras", "Platypleuroceras","Polymorphites","Tropidoceras","Uptonia", "Aegoceras","Androgynoceras","Liparoceras","Amaltheus", "Amauroceras","Pleuroceras","Catacoeloceras","Collina", "Dactylioceras","Nodicoeloceras","Peronoceras","Porpoceras", "Preperonoceras","Prodactylioceras","Reynesoceras", "Reynesocoeloceras", "Zugodactylites"," Arctomercaticeras", "Arieticeras","Atacamiceras")"Bouleiceras","Canavarella", "Canavaria"," Cylicoceras", "Dumortieria", "Eleganticeras", "Fieldingiceras", "Fontanelliceras", "Frechiella", "Fuciniceras","Grammoceras","Harpoceras","Hildaites", "Hildoceras", "Hildaitoides", "Hudlestonia", "Leioceras", "Leptaleoceras", "Leukadiella", "Lioceratoides", "Mercaticeras", "Neolioceratoides"," Oregonites"," Onychoceras"," Ovaticeras", "Parahildaites","Paroniceras","Phlyseogrammoceras", "Pleydellia","Podagrosites","Polyplectus","Protogrammoceras", "Pseudogrammoceras","Pseudolioceras","Renziceras", "Sphenarpites","Staufenia","Taffertia")"Tiltoniceras", "Tmetoceras","Bredyia","Brodieia","Erycites","Erycitoides", "Esericeras","Eudmetoceras","Hammatoceras","Haplopleuroceras", "Haugia", "Nej dia", "Phymatoceras", "Planammatoceras", "Podagrosiceras", "Pseudomercaticeras", "Puchenquia", "Sphaerocoeloceras","Yakounia","Brasilia","Costileioceras", "Darellia"," Graphoceras", "Hyperlioceras", "Ludwigia", "Reynesella", "Dorsetensia", "Euhoploceras", "Fissilobiceras",  202  Appendix 2 Source code for the user interface of Ammon "Fontannesia">HGuhsania",MShirbuirnia","Sonninia", "Witchellia","Zurcheria","Arcticoceras,,,"Arctocephalites", "Cadoceras","Cardioceras","Paracadoceras","Pseudocadoceras", "Podagrosiceras", "Kepplerites", "Kosmoceras", "Docidoceras", "Emileia","Pseudotoites","Chondroceras","Eocephalites", "Eurycephalites","Iniskinites","Lilloettia","Loucheuxia", "Megasphaeroceras"," Stehnocephalites", "Xenocephalites", "Stephanoceras","Stemmatoceras","Oecotraustes","Oxycerites", "Prohecticoceras"," Choffatia", "Neuqueniceras", "Rehmannia", "Harpophylloceras","Juraphyllites","Tragophylloceras", " Adabofoloceras"," Calaiceras"," Calliphylloceras", "Fergusonites", "Holcophylloceras", "Nevadaphyllites", "Partschiceras","Phylloceras","Procliviceras","Sowerbyceras", "Zetoceras","Alocolytoceras","Audaxlytoceras","Derolytoceras", "Holcolytoceras", "Kallilytoceras", "Lytoceras", "Pleurolytoceras", "Pterolytoceras"," Asaphoceras", "Diplesioceras"}; short  num_of^enus_in_family[]={13,5,21,8J8,l,10,6,2)10,3,3,ll,43,17,7,9,6,l, 2,3,9,2,3,1,2,3,11,8,2};  /* stage list for Lower Jurassic and part of Middle Jurassic */ static char  *stage[]={"Hettangian","Sinemurian","Pliensbachian", "Toarcian"," Aalenian'V'Bajocian"};  /* European zones in the above stages */ static char  *zone[]={"Planorbis,,,"Liasicus","Angulata","Bucklandi", "Semicostatum","Turneri","Obtusum","Oxynotum", "Raricostatum","Jamesoni","Ibex","Davoei","Margaritatus", "Spinatum","Tenuicostatuni","Falcifer","Bifrons", "Variabilis","Thouarsense","Levesquei","Opalinum", "Murchisonae","Concavum","Sowerbyi","Sauzei", "Humphriesianum"};  short  num_of_zone_in_stage[]={3,6,5,6,3,3};  /* large geographic regions in the Ammon */ static char  *area[]={"Western Pacific","Western Tethyan", "North American'V'South American","N.W Europe"};  /* all countries represented in the Ammon */ static char  *country[]={"Argentina","Austria","Britain","Canada", "Chile","China","Ecuador","France","Germany","Greece",  203  Appendix 2 Source code for the user interface of Ammon  204  "Hungary","Iran","Ireland","Italy","Japan","Malagasay", "Mexico","Peru,,,"Portugar,,"Russia","Saudi Arabia", "Switzerland","UnitedStatesH,"Turkey"}; /* rib form classification based on treatise */ static char  *ribForm[]={"straight","concave","convex","sinuous", "falcoid","falcate","biconcave","projected"};  /* rib furcation terms following Smith 1986 */ static char  *ribFurc[]-{"intercalatory","bi","tri","multiH,"poly", "loop2",,,loop3","loopn","bundled"};  /* tubercle classification following Smith 1986 */ static char  *tubercie[]={"uni,,,"bi","tri,,,,,multi","bullate","clavate"};  /* whorl shape classification following Smith 1986 */ static char  *whorlShape[]={"oval","ogivar',"ellipsoid","rounded", " lanceolate"," rectangular"," quadrate", "triangular", "trapezoid","coronate","wellipsoid","wrectangular", "wtriangular"};  /* umbilical wall height */ static char  *wallHeight[]={"highM,"low"};  /* umbilical wall slope */ static char  *wallAng[]={"shallow","steep","vertical","undercut"};  /* venter shape following Smith 1986 */ static char  *venter[]={"plain","carinate","sulcate","carinate-sulcate", "bicarinate"};  /* source for the data in Ammon, should be reorganized in a more structured way, such as a two level menu system */ static char  *reference[]={"Arkell Etc 1957","Arthur 1985", "Atlas Ed. By Repin 1968","Blasco 1978","Crickmay","Dagis", "Dean,Donovan,Howarth 1961","Erben 1956","Frebold", "Frebold and Mountjoy etc 1967","Gabb 1869","Gabilly 1976", "Geczy 1976","Geyer","Guex","Hall 1987",  Appendix 2 Source code for the user interface of Ammon  205  "Hall And Westerman 1980","Hall and Howarth 1983", "Hillebrandt","Hirano","Imlay 1968","Imlay 1981", "Jakobs 1992","Kalacheva 1980","Mclearn 1932","Meister 1986", "O'brien 1985","Palfy 1991","Poulton", "Poulton And Tipper 1991","Quinzio Sinn 1987","Repin 1974", "Schlatter 1991","Schlegelmilch ^ e y S m i t h 1976","Smith 1981", "Smith And Tipper","Stankevich 1964","Taylor 1988", "Thomson And Smith 1992","Tilmann 1917", "Tipper and Smith etc 1991","Wang And Smith 1986", "White 1889","Whiteaves 1884","Wiedenmayer 1977", "Wiedenmayer 1980","Others"}; Frame Frame Canvas Pixwin  command_frame; /* root frame to host menus and utilities*/ display_window; /* window for image display */ image_canvas; /* area in the display_window for image display */ *pw;  /* text window for diplaying the textual information of the selected specimen */ Textsw text_win; Panel Panel  command_win; /* left window hosting all menus and utilities */ info_panel; /* top window hosting query field and other textual information */  /* define sizes of the above windows, its location can be infered */ struct size  { int width; int height; } screen_rect = {1152, 900};  struct size struct size  command_rect = {175, 900}; info_rect = {980, 300};  struct point  { int x; int y; }between[2]={{0,0},{0,0}};  struct point  control_point[100];  Panel_item PaneMtem Pixfont unsigned char colormapt  condition_text, show_num, wait_num; bright, contrast; *font; red [256], green [256], blue [256]; colormap = { RMTEQUALRGB, 256, red, green, blue };  Appendix 2 Source code for the user interface of Ammon  206  /* use the shell icon as the system icon */ static short icon_data[] = { #include <images/cmdtool.icon> };  static static char char char char int int int int int int int int int int int  mpr_static(ammon_icon, 64, 64, 1, icon_data); interface_image = "/home/liang/interface.ras";  *path; /* record which menu has been selected */ *image_name[MAX_IMAGE]; *query_statement, *search_condition[12]; num_of_Items; /* number of specimens retrieved */ choice; /* record which menu item has been selected */ cs; /* base brightness of image */ start_status=0;/* info panel is not initialized yet */ In_sublist = 0; /* specimen is not in the sub (species) list instead it is in the main (genus) list */ display_from, displayto; /* display status */ from_menu; /* whether query is issued from menu */ num_control_point; rel[MAX_IMAGE]; /* index conversion between image_name and descriptor_value */ displayed[MAX_IMAGE]; /* image hasn't been displayed (0);forward displayed (1); backward displayed (-1) */ seq[MAX_IMAGE]; /* order images by height */  double  image_scale;  /* global functions */ void void void void void void void void void void void void void void  create_menu_button(); create_command_button(Frameframe_local); init menu(); init_info_panel(Frame frame local); menu_handler(); /* action upon menu item selection */ query_frorn_menu(); query_from_text(); execute_query(); sort_image_list(); build_full_name(); adjust_display_window(); display_images(); query_to_plain(char *buf) stop_op();  2. retrieve.h /* specific data declarations for retrieve.c, not shared by morph.c */  Appendix 2 Source code for the user interface of Ammon  /* define the array index for descriptor_name */ #define SYNSPECIES  11  /* image is in the main (genus) list instead of species sublist */ #define MAINLIST  2  /* after the first query, the display window splits into three subwindows */ from top to bottom, they are info panel, text subwindow and image canvas */ all three windows have the same width and their heights add up to screen height */ struct size int int  { width; height; } text_rect = {980, 128};  struct size  canvas_rect = {980, 720};  int int  Sublist[MAX_IMAGE]; /* whether the image is in species sublist */ break_point_u\j*enus; /* point where program get into the species sublist */  /* functions not shared with morph module */ void void void void  main_list(); gotospecimenO; find_species(); save_as();  3. retrieve, c /* main program of the Ammon user interface */ #include <ammon.h> main(argc, argv) int argc; char **argv; {  207  Appendix 2 Source code for the user interface of Ammon int  i, j ;  Scrollbar  vertical_sb;  /* create a frame to host the left command window */ command_frame = window_create(NULL, FRAME, FRAME_LABEL, "Ammon Image Database", FRAME_SHOW_LABEL, TRUE, WIN_WIDTH, command_rect.width, WINHEIGHT, command_rect.height, WIN_X,0, WTN_Y, 0, FRAMEJCON, icon_create(ICON_IMAGE, &ammon_icon, 0), 0); /* create the command window to host the menu and command buttons */ command_win = window_create(command_frame, PANEL, PANEL_LABEL_BOLD, TRUE, PANEL_SHOW_MENU, TRUE,  o); /* load font to label menu and command buttons */ font=pf_open("/apps/sundesk/fonts/sunview/lucida-19. v"); create_menu_button(); create_command_button(); init_menu(); /* create a frame to host the info and canvas window at the right side of the command window */ display_window = window_create(NULL, FRAME, FRAME_LABEL, " Welcome Window", FRAME_SHOW_LABEL, TRUE, WIN_X, command_rect.width, WIN_Y, 0, WIN_SHOW,TRUE, WIN_WIDTH, screenrect.width-commandrect. width, WIN_HEIGHT,screen_rect.height, 0);  208  Appendix 2 Source code for the user interface of Ammon  /* create the info panel giving an introduction to the system */ init_info_panel(display_windo w); vertical_sb = scrollbar_create(SCROLL_LINE_HEIGHT, 5, (char *)0); /* 5 is the width of the scrollbar */ image_canvas=windo w_create(display_windo w, CANVAS, WIN_VERTICAL_SCROLLBAR, vertical_sb, CANVAS_RETAINED, FALSE, CANVAS_AUTO_SHRTNK, FALSE, WIN_CONSUME_PICK_EVENT, MS_LEFT, WIN_EVENT_PROC, canvasjiandler, WIN_X, 0, WIN_Y, info_rect.height+5, /* canvas under info panel */ WTNWIDTH, screenrect.width-commandrect. width, WIN_HEIGHT, screen_rect. height-info_rect. height- 5, 0);  /* make the image_canvas a color canvas with 253 colors */ pw=(Pixwin *) window^get(image_canvas, WINPIXWIN); pw_putcolormap(pw, 0, 253, red, green, blue); /* reserve 3 color entries for bg and fg */ window_set(image_canvas, CANVAS_RETAINED, TRUE,  o); /* load the interface image into the canvas */ load_interface_image(); /* allocate memory for retrieval results of database query */ for (i=0; i<NUM_OF_DESCRIPTOR; i++) for (j=0; j<MAX_SP; j++) descriptor_value[i][j] = (char *)malloc(len[i]+2); for (i=0; i<MAX_IMAGE; i++) image_name[i]=(char *)malloc(len[IMAGE]+2); signal(SIGURG, stop_op);  209  Appendix 2 Source code for the user interface of Ammon window_main_loop(command_frame); exit(0); } /* load the interface image into the image_canvas */ static void load_interface_image() { Pixrect *image; FILE *fp; register int w, h; clear_canvas(); /* don't move the interface image file to other location */ if ((fp=fopen(interface_image, "r")) = NULL) printfC'Can't open %s\n",interface_image); return;  { }  image=pr_load(fp, colormap); w=image->pr_size.x; h=image->pr_size.y; red[252]=255; /* color entry 252 gives pure red */ green[252]=blue[252]=0; pw_setcmsname(pw, "image_cmp"); pw_putcolormap(pw, 0, 253, red, green, blue); cs=red[l]; /* as an indicator of the brightness */ /* display the image in the middle of the canvas */ if (h<screen_rect. height-inforect. height) pw_rop(pw,(screen_rect.width-command_rect.width-w)/2, (screen_rect. height-inforect. height-h)/2, w, h,PIX_SRC, image, 0,0); else pw_rop(p w, (screen_rect. width-commandrect. width-w)/2,0, w,h,PIX_SRC,image,0,0); prclose(image); fclose(fp);  210  Appendix 2 Source code for the user interface of Ammon  211  4. amenu.h /* Header file for creating the menu */ #include <suntool/walkmenu.h> #define MENU_START_ROW #define MENU_INCREMENT  0 2  /* row where menu items start */ /* increment in terms of number of rows */  /* trace which family has been selected, taxonomy starts with 'a' */ static char  *family_path[]={"aa","ab","ac",,,ad,,,"ae",,,af,,"ag","ah", ,, ,, ai ,"aj,,,"akH,"al",,,am,,),,an,,)"ao",,,ap,,,,,aq",,,ar","as", "atVWVWVWVWVV/'azV'aAVaB'V'aCVaD"};  /* trace which stage has been selected, stratigraphy starts with 'b' */ static char  *stage_path[]={ "ba","bb","be","bd","be","bf'};  /* five menu buttons */ static Panelitem static Panelitem  button_Taxonomy,button_Stratigraphy,button_Geography; button_Morphology,button_Reference;  /* five root-level menus associated with the buttons */ static Menu  taxonomy_menu, stratigraphymenu, geographymenu;  static Menu  morphology_menu, referencemenu;  /* two geography submenus */ static Menu  area_menu, country_menu;  /* nine morphology submenus */ static Menu rib_menu, ribformmenu, ribfurcjnenu; static Menu tubercle_menu, whorlshapemenu, wallmenu; static Menu wallheightmenu, wallangmenu, venter_menu; /* family menus under taxonomy, number of submenus is determined by the size of the family array */ #define numoffamily static Menu  (sizeof family/sizeof family[0]) family_menu[num_of_family];  Appendix 2 Source code for the user interface of Amnion /* stage menus under stratigraphy, number of submenus is determined by the size of the stage array */ #define numofstage (sizeof stage/sizeof stage[0]) static Menu stage_menu[num_of_stage]; / * The followings are menu related functions */ static void  find_path();  5. amenu.c ^include <ammon.h> #include <amenu.h> /* create the menu buttons for five root level menus */ extern void create_menu_button() { panel_create_item(command_win,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_Y,ATTR_ROW(MENU_START_ROW), PANEL_LABEL_STRING, "Retrieve by:", 0);  buttonTaxonomy = panel_create_item(command_win,PANEL_BUTTON, PANELJTEMX, ATTRCOL(O), PANEL_ITEM_Y, ATTR_ROW(MENU_START_ROW+MENU_INCREMENT), PANEL_EVENT_PROC, menu_handler, PANELLABELJMAGE, panel_button_image(command_win," Taxonomy =>", 13,font),  o); button_Stratigraphy = panel_create_item(command _win,PANEL_BUTTON, PANEL_ITEM_X, ATTR_COL(0), PANELJTEMY, ATTR_ROW(MENU_START_ROW+2*MENU_INCREMENT), PANEL_LABEL_FONT, font, PANEL_EVENT_PROC, menu_handler, PANEL_LABEL_IMAGE, panel_button_image(command_win," Stratigraphy =>", 13,font),  o);  212  Appendix 2 Source code for the user interface of Ammon buttonGeography = panel_create_item(command_win,PANEL_BUTTON, PANEL_ITEM_X, ATTR_COL(0), PANEL_ITEM_Y, ATTR_ROW(MENU_START_ROW+3*MENU_INCREMENT), PANEL_EVENT_PROC, menu_handler, PANEL_LABEL_IMAGE, panel_button_image(command_win, "Geography =>", 13,font), 0); button_Morphology = panel_create_item(command_win,PANEL_BUTTON, PANEL_ITEM_X, ATTRCOL(O), PANEL_ITEM_Y, ATTR_ROW(MENU_START_ROW+4*MENU_INCREMENT), PANEL_EVENT_PROC, menu_handler, PANELLABELJMAGE, panel_button_image(command_win, "Morphology =>", 13,font), 0); button_Reference = panel_create_item(command_win,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(MENU_START_ROW+5*MENU_INCREMENT), PANELEVENTPROC, menujiandler, PANEL_LABEL_IMAGE, panel_button_image(command_win, "Reference =>", 13, font),  o); } extern void init_menu() { register int  i, j , from, to;  /* Create Taxonomy Menu */ from=to=0; for (i=0;i<num_of_family;i++) { family_menu[i]=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA,family_path[i], MENU_FONT,font, MENU_STRING_ITEM, "Genera Menu", 0,0); to += num_of_genus_in_family[i]; for(j=from;j<to;j++) menu_set(family_menu [i], MENU_STRING_ITEM,genusG],  213  Appendix 2 Source code for the user interface of Ammon j-from+1,0); from += num_of_genus_in_family[i];  }  taxonomy_menu=menu_create(MENU_FONT,font, MENU_STRING_ITEM, "Family Menu", 0,0); /* attach family menu to taxonomy menu */ for (i=0;i<num_of_family;i++) menu_set(taxonomy_menu,MENU_PULLRIGHT_ITEM, family[i],family_menu[i],  o); /* create Stratigraphy Menu */ from=to=0; for (i=0;i<num_of_stage;i-H-) { /* create a menu for each stage */ stage_menu[i]=menu_create(MENU_GEN_PROC,find_path, MENU_CLD3NT_DATA,stage_path[i], MENU_FONT,font, MENU_STRING_ITEM,"Zone Menu", 0,0); to += num_of_zone_in_stage[i]; for(j=from;j<to;j++) menu_set(stage_menu[i], MENU_STRING_ITEM,zone[j], j-from+1,0); from += num_of_zone_in_stage[i]; } stratigraphy_menu=menu_create(MENU_FONT,font, MENU_STRING_ITEM,"Stage Menu", 0,0); /* attach stage menu to stratigraphy menu */ for (i=0;i<num_of_stage;i++) menu_set(stratigraphy_menu,MENU_PULLRIGHT_ITEM, stage[i],stage_menu[i],  o); /* create Geography Menu */  214  Appendix 2 Source code for the user interface of Ammon /* create area submenu */ area_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLffiNT_DAT A, "ca", MENU_FONT,font, MENU_STRING_ITEM,"Area Menu", 0,0); for (i=0; area[i] != NULL; i++) menu_set(area_menu, MENU_STRING_ITEM, area[i], i+1, 0); /* create country submenu */ country_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA,"cb", MENU_FONT,font, MENU_STRING_ITEM, "Country Menu", 0,0); for (i=0; country[i] != NULL; i++) menu_set(country_menu, MENU_STRING_ITEM, countiyp], i+1, 0); geographyjnenu=menu_create(MENU_FONT,font, MENU_STRING_ITEM, "Geography Menu", 0,0); /* attach area and country submenus to geography menu */ menu_set(geography_menu, MENU_PULLRIGHT_ITEM,"Area",area_menu, MENU_PULLRIGHT_ITEM,"Country",country_menu,  o); /* create Morphology Menu */ /* create rib form submenu, 'daa' records the path upon menu event */ ribform_menu=menu_create(MENU_GEN_PROC,find_path, MENUCLIENTDATA, "daa", MENUFONT.font, MENU_STRINGJTEM,"Rib Form", 0,0);  215  Appendix 2 Source code for the user interface of Amnion  for (i=0; ribForm != NULL; i++) menu_set(ribform_menu, MENU_STRING_ITEM, ribForm[i], i+1, 0); /* create rib furcation submenu, 'dab' records the path upon menu event */ ribfurc_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA, "dab", MENU_FONT,font, MENU_STRING_ITEM,"Rib Furcation", 0,0); for (i=0; ribFurc[i] != NULL; i++) menu_set(ribfurc_menu, MENU_STRING_ITEM, ribFurcp], i+1, 0); rib_menu=menu_create(MENU_FONT,font, MENU_STRING_ITEM,"Rib Menu", 0,0); /* attach rib form and rib furcation submenus to rib submenu */ menu_set(rib_menu, MENTJPULLRIGHTITEM, "Rib Form",ribform_menu, MENU_PULLRIGHT_ITEM, "Rib Furcation", ribfurcjnenu,  o); /* create tubercle submenu, 'db' records the path upon menu event */ tubercle_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA,"db", MENU_FONT,font, MENU_STRING_ITEM, "Tubercle Form", 0,0); for (i=0; tubercle[i] != NULL; i++) menu_set(tubercle_menu, MENU_STRING_ITEM,tubercle[i], i+1,0); /* create whorl shape submenu, 'dc' records the path upon menu event */ whorlshape_menu=menu_create(MENU_GEN_PROC,find_path,  216  Appendix 2 Source code for the user interface of Ammon MENU_CLIENT_DAT A, "dc", MENU_FONT,font, MENU_STRING_ITEM,"Whorl Shape", 0,0); for (i=0; whorlShape[i] != NULL; i++) menu_set(whorlshape_menu, MENU_STRING_ITEM,whorlShape[i], i+1,0); /* create umbilical wall height submenu, 'dda' records the path upon menu event */ wallheight_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA,"dda", MENU_FONT,font, MENU_STRING_ITEM,"Wall Height", 0,0); for (i=0; wallHeight[i] N NULL; i++) menu_set(wallheight_menu, MENU_STRING_ITEM,wallHeight[i], i+1,0); /* create umbilical wall slope submenu, 'ddb' records the path upon menu event */ wallang_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLffiNT_D ATA, "ddb", MENU_FONT,font, MENU_STRTNG_ITEM,"Wall Slope", 0,0); for (i=0; wallAng[i] != NULL; i++) menu_set(wallang_menu, MENU_STRING_ITEM,wallAng[i], i+1,0); wall_menu=menu_create(MENU_FONT,font, MENU_STRTNG_ITEM, "Umbilical Wall", 0,0); /* attach umbilical height and slope submenus to wall submenu */ menu_set(wall_menu, MENUPULLRIGHTITEM, "Wall Height ",wallheight_menu, MENU_PULLRIGHT_ITEM,"WallSlope",wallang_menu, 0);  217  Appendix 2 Source code for the user interface of Ammon  218  /* create venter shape submenu, 'de' records the path upon menu event */ venter_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLffiNT_DATA, "de", MENU_FONT,font, MENU_STRING_ITEM,"Venter Shape", 0,0); for (i=0; venter[i] != NULL; i++) menu_set(venter_menu, MENU_STRING_ITEM,venter[i], i+1,0); /* attach rib, tubercle, whorl shape, umbilical wall and venter submenus to morphology menu */ morphology_menu=menu_create(MENU_FONT,font, MENU_STRING_ITEM, "Morphology Menu", 0,0); menu_set(morphology_menu, MENU_PULLRIGHT_ITEM,"Rib",rib_menu, MENU_PULLRIGHT_ITEM,"Tubercle",tubercle_menu, MENU_PULLRIGHT_ITEM,"Whorl Shape",whorlshape_menu, MENU_PULLRIGHT_ITEM, "Umbilical Wall", wall_menu, MENU_PULLRIGHT_ITEM,"Venter",venter_menu, 0); /* Create Reference Menu, 'e' records the path upon menu event */ reference_menu=menu_create(MENU_GEN_PROC,find_path, MENU_CLIENT_DATA, "e", MENU_FONT,font, MENU_STRING_ITEM, "Reference Menu", 0,0); for (i=0; reference[i] != NULL; i++) menu_set(reference_menu, MENU_STRING_ITEM,reference[i], i+1,0); } /* find_path determine which submenu has been selected and record the path */ static void find_path(menu, operation) Menu  menu;  Appendix 2 Source code for the user interface of Ammon Menuj^enerate operation; { switch (operation) { case MENU_NOTIFY: path=menu_get(menu,MENU_CLIENT_DATA); break; case MENU_DISPLAY: case MENUJDISPLAY DONE: case MENU_NOTIFY_DONE: break; } }  /* menuhandler determine which menu item has been selected and store the value in choice (int) */ extern void menu_handler(item, event) PaneMtem item; Event *event; { if (event_action(event) = MS_RIGHT && eventisdown(event) && eventisbutton(event)) { path=,,M; if (item=button_Taxonomy) { panel_begin_preview(item, event); choice = (int)menu_show(taxonomy_menu, command_win,event, 0); } else if (item=button_Stratigraphy) { panel_begin_preview(item, event); choice = (int)menu_show(stratigraphy_menu, command_win,event,0); } else if (item=button_Geography) { panel_begin_preview(item, event); choice = (int)menushow(geographymenu, commandwin, event, 0); } else if (item=button_Morphology) { panel_begin_preview(item, event); choice = (int)menushow(morphologymenu, command_win, event, 0); } else if (item=button_Reference) { panel_begin_preview(item, event); choice = (int)menu_show(reference_menu, commandwin, event, 0); } panel_accept_preview(item, event); panel_update_preview(item, event);  219  Appendix 2 Source code for the user interface of Ammon if(*path) { query_from_menu(); num_of_ltems=0; execute_query(); if(num_of_Items) { from_menu=l; sort_image_list(); build_full_name(); display_images(); } } } else panel_default_handle_event(item, event); }  6. display.c #include <ammon.h> static int static int static int static int  x, y; width[MAX_IMAGE], height[MAXJMAGE]; current_page[200]; /* conversion between index on the page and general image list */ num_in_page; /* number of images on the page */  /* initialize and display the first screen of the images */ extern void display_images() { register int i, j , k; char tmp[10]; FILE *fp; Pixrect * image; struct rasterfile rh; /* read width and height for all retrieved images */ for (i=0; i<num_of_Items; i++) { if ((fp=fopen(image_narne[i],"r")) = NULL) goto next; pr_load_header(fp, &rh); width[i]=rh. raswidth; height[i]=rh. rasheight; fclose(fp);  220  Appendix 2 Source code for the user interface of Ammon next:  ; }  if (!start_status) /* if this is the first query issued, rearrange the windows */ adjust_display_window(); if (frommenu) /* if query is issued from menu, display the query in the text field */ { buf=&query_statement[42]; query_to_plain(buf); i=strlen(buf); buf[i-2]=0; tmp[0]=O; sprintf(tmp,"%s%s",buf,search_condition[0]); panel_set(condition_text, PANEL_VALUE, tmp, 0); } /* display the number of images retrieved */ sprintf(tmp,"%d",num_of_Items); panel_set(show_num, PANEL_VALUE, tmp, 0); /* reorder the image based on height so images are nicely tiled */ for (i=0; i<num_of_Items; i++) seq[i]=i; for (i=0; i<num_of_Items-l; i++) for (j = i + l; j<num_of_Items; j++) if (height[seq[j]]>height[seq[i]]) k=seq[i]; seq[i]=seq[j]; seq[j]=k; } clear_canvas();  {  /* make ready for display */  /* if the height of the largest image > canvas height, increase the canvas height */ if (height[seq[ 1 ]]>screen_rect.height-info_rect.height-20) (void)window_set(image_canvas, CANVAS_HEIGHT, height[seq[l]]+20, 0); cs=rx=y=display_to=0;  221  Appendix 2 Source code for the user interface of Amnion  222  display_from=l; num_in_page=0; displayto = num_of_Items; for (i=0; i<num_of_Items; i++) if (displayed[seq[i]] != 1) if (!display_specimen(i, 1)) {/* display images of this specimen, 1 - forward */ break; /* end of the page */ displayto = i; } modifycolormapO; /* adjust brightness based on all images of the page */ /* show the number of images still waiting to display */ sprintf(tmp,"%d",num_of_Items-num_in_page); panel_set(wait_num, PANELVALUE, tmp, 0); } /* turn to the next page */ extern void next_page() { int char  i, k; tmp[10];  /* haven't reached the end of the image list */ if (display_to<num_pf_Items && display_from<num_of_Items-1)  {  clear_canvas(); /* record where it starts */ if (display_from>display_to) /* following previous page operation */ k=display from=display_to=display from+1; else k=display_from=display_to; num_in_page=cs=:x=y=j=0; displayto = numofltems; for (i=k; i<num_of_Items; i++)  /* start of a new page */  Appendix 2 Source code for the user interface of Ammon  223  if (displayed[seq[i]] != 1) /* hasn't been forward displayed */ if (!display_specimen(i, 1)) { /* display images of this specimen 1 - forward */ displayto = i; break; /* end of the page */ } modifycolormapO; /* adjust brightness based on all images of the page */ /* show the number of images still waiting to display */ if(display_to<num_of_Items) { if (displayto >= display from) k = num_of_Items-display_to-l; else if (displayto < display_from) k=display_to-l; } else k = 0; sprintf(tmp,"%d",k); panel_set(wauVnum, PANELJVALUE, tmp, 0);  } else panel_set(wait_num, PANELVALUE, "No!", 0);  } /* turn the page backwards */ static void previous_page() { int char  i, k; tmp [10];  /* haven't reached the begining of the image list */ if (displayto && display_from) clear_canvas(); /* record where it starts */  {  Appendix 2 Source code for the user interface of Ammon if (display_to<display_from) k=display_from=display_to; else k=display_from=display_to=display_from-1; num_in_page=cs=x=y=j=0; /* start of a new page */ display_to = 0; for (i=k; i>0; i - ) if (displayed[seq[i]] != -1) /* hasn't been displayed backwards */ if (!display_specimen(i, -1)) { /* -1 -> display backwards */ displayto = i; break; /* end of the page */ } modify_colormap(); /* adjust brightness based on all images of the page */ /* show the number of images still waiting to display */ if(displayto) k = display_to; else k = 0; sprintf(tmp,"%d",k); panel_set(wait_num, PANEL_VALUE, tmp,  o); } else panel_set(wait_num, PANEL_VALUE, "No!", 0); } /* find all images of the speciemn sp and display them */ static int display_specimen(sp, direction) int sp, direction; { register int i, j , j 1, j 2, k, order[ 10]; FILE *fp; Pixrect * image;  224  Appendix 2 Source code for the user interface of Ammon /* images from the same specimen are sequential */ /* find the lower limit */ i=seq[sp]; while (rel[~i]==rel[seq[sp]]) ; ji=i+i; /* find the upper limit */ i=seq[sp]; while (rel[++i]=rel[seq[sp]]) ; J2=i-1; /* reorder the images of the specimen by height */ ifG2>jl) { for(i=jl;i<=j2;i++) order[i-jl]=i; for(i=0;i<j2-jl;i++) for(j=i+l;j<=j2-jl;j++) if (height[order[j]]>height[order[i]]) { k=order[i]; order[i]=order[j]; order[j]=k; } } else order[0]=seq[sp]; /* display the images in order */ k=0; /* the current height reached by tiled images */ for(i=0;i<j2-jl+l;i++) if (displayed[order[i]] != 1) /* hasn't been displayed */ { if ((fp=fopen(image_name[order[i]], V')) == NULL ) { printf("Can't open image file %s\n",image_name[order[i]]); goto next_image; } image=pr_load(fp, colormap); if (num_in_page && x+width[order[i]]>wid) { x=0; y+=k; k = height[order[i]]; } if (y+height[order[i]]<screen_rect.height-info_rect.height || !y) { if(j<height[order[i]]) j=height[order[i]];  225  Appendix 2 Source code for the user interface of Ammon cs += red[l]; pw_rop(pw,x,y,width[order[i]],height[order[i]],PIX_SRC,image,0,0); x += width[order[i]]; prclose(image); fclose(fp); displayed[order[i]] = direction; current_page[num_in_page++]=order[i]; } else { display_to=sp; prclose(image); fclose(fp); return 0; /* end of the page */ } nextimage: ; } return 1; /* more room on the page */ } /* cs - the base of brightness, adjust brightness by modifying colormap */ static void modify_colormap() { register int i; if (num_in_page) cs /= num_in_page; for(i=l;i<252;i++) red[i]=blue[i]=green[i]=(cs+i-l>255) ? 255:cs+i-l; green[252]=blue[252]=0; panel_set_value(bright,0); panel_set_value(contrast, 10); pw_setcmsname(pw, "image_cmp"); pw_putcolormap(pw, 0, 253, red, green, blue); } /* locate the selected image in the image list * extern int image_index(xo, yo) int xo,yo; { register int i, k, x 1, y 1, j=-1;  226  Appendix 2 Source code for the user interface of Ammon xl=yl=0; k=height[current_page[0]]; for (i=0; i<num_in_page; i++) { if(x+width[current_page[i]]>wid) { yl+=k; k = height[current_page[i]]; xl=0; } /* (xo, yo) falls within the range of image j */ if (xo>xl && xo<xl+width[current_page[i]] && yo>yl && yo<yl+height[current_page[i]]) { j=current_page[i]; break; } x += width[current_page[i]]; if (k<height[current_page[i]]) k=height [current_page[i] ]; return j ;  /* return the index number of the selected image */  } /* display all information of the selected specimen */ extern void show_descriptors(index_of_image) int index_of_image; { register int i, k; float f; char tmp[200]; textsw_normalize_view(text_win, (Textswindex) window_get(text_win, TEXTSW_INSERTION_POINT)); /* display image name, quantitative descriptors and qualitative descriptors */ for (i=0; KNUMOFDESCRIPTOR; i++) if(i=IMAGE) { sprintf(tmp,"%s:%s. ",descriptor_name[i], image_name[index_of_image]);  227  Appendix 2 Source code for the user interface of Amnion  228  textsw_insert(text_win, tmp, strlen(tmp)); } else if ((i>IMAGE && i<WHORL_SHAPE || i>ONTOGENY && KAPPROX) && (f=atof(descriptor_value[i][rel[index_of_image]]))>0) /* quantitative parameters */ { /* data exists for this descriptor */ sprintf(tmp,"%s:%5.2f",descriptor_name[i],f); textsw_insert(text_win, tmp, strlen(tmp)); } elseif(descriptor_value[i][rel[index_of_image]][0] !=")  {  /* data exists for this descriptor */ k=len[i]-2; while (descriptor_value[i][rel[index_of_image]][k~] = ") ; descriptor_value[i][rel[index_of_image]][k+2]=^'; sprintf(tmp,"%s:%s. ",descriptor_name[i], descriptor_value[i][rel[index_of_image]]); textsw_insert(text_win, tmp, strlen(tmp)); } textsw_insert(text_win, "\n", 1); }  7. query.c #include <ammon.h> /* construct a query statement from a selected menu item */ extern void query_from_menu() { register int i, j , depth, entry; char tmp[ 150]; depth = 1; while (path[depth] != M)') depth++;  /* the depth of the menu item */  Appendix 2 Source code for the user interface of Ammon j='A'-('z'-'a'+l); /* upper case conversion */ switch (path[0]) { case 'a': /* a menu item in taxonomy */ if (depth=2 && Ichoice) { /* select a family */ query_statement=" select * from OP S $liang. ammonjmage where family= :"; if (path[ 1 ]>'a'-1) /* lower case */ search_condition[0]=family[path[ 1 ]-'a']; else /* upper case */ search_condition[0]=family[path[l]-j]; } else if (depth=2 && choice) { /* select a genus */ query_statement=" select * from OPS$liang.ammon_image where synonymy= :"; if (path[ 1 ]>'a'-1) /* lower case */ depth=path[l]-'a'; else depth=path[l]-j; /* upper case */ entry=0; for (i=0; Kdepth; i++) entry += num_of_^enus_in_family[i]; entry += choice-1; /* genus at entry is selected */ search_condition[0]=genus[entry]; •}  break; case V:  I* a menu item in stratigraphy */ if (depth=2 && Ichoice) {/* select a stage */ querystatement-'select * from OPS$liang. ammon_image where stage=:"; search_condition[0]=stage[path[l]-'a']; } else if (depth=2 && choice) { /* select a zone */ query_statement-'select * from OPS$liang. ammonjmage where eurzone= :"; depth=path[l]-'a'; /* lower case */ entry=0; for (i=0; i<depth; i++) entry += num_of_zone_in_stage[i]; entry += choice-1; /zone at entry is selected */ search_condition[0]=zone[entry]; }  229  Appendix 2 Source code for the user interface of Ammon break; case 'c':  /* a menu item in geography */ if (depth==2 && choice) { if(path[l]-V) { query_statement="select * from OP S $liang. ammonimage where country= :"; search_condition[0]=country[choice-1 ]; } else { query_statement=" select * from OP S $liang. ammonimage where area=:"; search_condition[0]=area[choice-1 ]; } }  break; case 'd': /* a menu item in morphology */ if(depth>=2) { switch (path[l]) { case 'a': /* rib */ if (path[2]-'a') { query_statement=" select * from OPS $liang. ammonimage where fiirc like:"; search_condition[0]= (char *)strdup(ribFurc[choice-1 ]); elseif(path[2]-'a'-l) { query_statement=" select * from OP S $liang. ammonjmage where pform like :"; search_condition[0]= (char *)strdup(ribForm[choice-l]); } break; case 'b': querystatement-' select * from OP S $liang. ammonimage where tuberc like:"; search_condition[0]= (char *)strdup(tubercle[choice-1 ]); break; case 'c': querystatement-'select * from  230  Appendix 2 Source code for the user interface of Ammon  231  OPS $liang. ammonjmage where whorlshape like :"; search_condition[0]= (char *)strdup(whorlShape[choice-1 ]); break; case 'd': if (path[2]-'a') { querystatement-' select * from OPS$liang.ammon_image where uwallang like :"; search_condition[0]= (char *)strdup(wallAng[choice-l]); } else if (path[2]-'a'-l) { query_statement="select * from OPS$liang.ammon_image where uwallht like :"; search_condition[0]= (char *)strdup(wallHeight[choice-1 ]); break; case 'e': query_statement="select * from OP S $liang. ammon_image where venter like :"; search_condition[0]= (char *)strdup(venter[choice-1 ]); break; } tmp[0]=0; /* bd is the bind variable in Oracle dynamic SQL statement */ sprintf(tmp, "%s bd",query_statement); query_statement=(char *)strdup(tmp); /* SQL 'like' operator needs % to indicate containing */ sprintf(tmp,"%s%s%s","%",search_condition[0],"%"); search_condition[0]=(char *)strdup(tmp); } break; case 'e': /* a menu item in reference */ if (choice) { query_statement=" select * from OP S Sliang. ammonjmage  Appendix 2 Source code for the user interface of Ammon where refauthyear like :"; search_condition[0]=(char *)strdup(reference[choice-1 ]); i=strlen(search_condition[0]); search_condition[0] [i]='%'; search_condition[0] [i+1 ]=*\0'; tmp[0]=0; sprintfXtmp,"%sbd",query_statement); query_statement=(char *)strdup(tmp); } break; } if (!strstr(query_statement, "like :")) { tmp[0]=0; sprintf(tmp, "%s bd",query_statement); query_statement=(char *)strdup(tmp); } } /* construct a query statement from the text field */ extern void query_from_text() { int register char  i, j , k, ind, nl=0; *buf, *replace(), tmp[200],tmpl[200];  if(lstartstatus) { adjust_display_window(); return; } ln_sublist=0; /* construct the query statement from condition field */ buf=panel_get_value(condition_text); buf=substitute(buf,,,= :",,,="); buf=substitate(buf, "like: "/'like''); buf=substitute(buf, »>;»;•>»); buf=substitute(buf,"< :","<"); /* replace the bind variable value with bdl, bd2,  */  sprintfftmp 1 ,"%s",replace(buf)); sprintf(tmp,"select * from OPS$liang.ammon_image where %s",tmpl);  232  Appendix 2 Source code for the user interface of Ammon query_statement=(char *)strdup(tmp); sprintf(tmp, "%s",buf); i=0; if (buf=(char *)strtok(tmp,":")) { ifCstrstrCbuClike")) nl=l; else nl=0; while (buf=(char *)strtok(NULL,":")) { j=k=0; if(nl) trnplU-t+l^/o'; else tmpl[j]=0; ind=l; while (ind || (buf[k] \="&& buf[k] !=')' && buflk] !=*\0')) if (buflk] !="){ tmpl[j-H-]=buf[k-H-]; ind=0; } else k++; if(nl) trnplD-H+^/o'; tmpiDH; if(strstr(buf)"like")) nl=l; else nl=0; search_condition[i++]=(char *)strdup(tmp 1); } execute_query(); if (num_of_Items) { from_menu=0; sort_image_list(); build_full_nameO; display_images(); } else { panel_set_value(show_num,"None !"); panel_set_value(wait_num,"0"); } } else panel_set_value(condition_text,"Invalid Search Statement!"); } /* replace ': bind variable value1 in s with bdl, bd2,.. */  233  Appendix 2 Source code for the user interface of Ammon extern char * replace(s) char *s; { register int i, j , k, ind; char  tmp[200], tp[10], *buf;  i=strlen(s); tmp[0]=0; while (buf=(char *)strstr(s,":")) strncat(tmp, s,i-strlen(buf)); sprintfCtp," : bd%d"j++); strcat(tmp,tp); k=ind=l; /* skip bind variable value */  {  while (ind || (buf[k] !='' && buf[k] !='\0' && buf[k] !=')')) { if(buf[k]!= M ) ind=0; k++; } s=&buf[k]; i=strlen(s); } strcat(tmp,s); s=(char *)strdup(tmp); return s; }  8. dbms.pc /* all database related operations are in this file which need to be compiled by Oracle precompiler before proceeding with cc and combine with other source code */ #include <stdio.h> #include <ammon.h>  EXEC SQL BEGIN DECLARE SECTION; extern char *query_statement; extern char *search_condition[12]; char oracleid = V; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA;  234  Appendix 2 Source code for the user interface of Ammon EXEC SQL INCLUDE SQLDA; /* Declare the bind and select descriptors. */ SQLDA *bind_dp; SQLDA *select_dp; extern SQLDA  *sqlald();  extern void  sqlprc();  extern void int  sqlnul(); nullok;  extern void execute_query() { register int int float double  i j,k; precision, scale; tmp; atof();  /* Automatic log on to ORACLE */ EXEC SQL CONNECT :oracleid; /* Set up ORACLE error handling. */ EXEC SQL WHENEVER SQLERROR GOTO sqlerror;  bind_dp = sqlald(12, 30,0); bind_dp->N = 12; /* the maximum number of binding variables */ select_dp = sqlald (NUM_OF_DESCRIPTOR, 15, 0); select_dp->N = NUMOFDESCRIPTOR;  /* Prepare the statement and declare a cusor. */ EXEC SQL PREPARE S FROM :query_statement; EXEC SQL DECLARE C CURSOR FOR S; EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp; /* If F is negative, there were more bind variables than originally  235  Appendix 2 Source code for the user interface of Amnion  236  allocated by sqlald(). */ if(bind_dp->F<0) { printf("\nToo many bind variables for descriptor."); goto sqlerror; } /* Set the maximum number of array elements in the descriptor to the number found. bind_dp->N = bind_dp->F; for (i=0; i<bind_dp->F; i++) { bind_dp->L[i] = strlen(search_condition[i]); bind_dp->V[i] = search_condition[i]; bind_dp->I[i] = 0; bind_dp->T[i]=l; /* Open the cursor and define the active set. */ EXEC SQL OPEN C USING DESCRIPTOR bind_dp; EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp; /* If F is negative, there were more select-list items than originally allocated by sqlald(). */ if (select_dp->F <0) { printf("\nToo many select-list items for : %d", -(select_dp->F)); goto sqlerror; } /* Set the maximum number of array elements in the descriptor to the number found. */ select_dp->N = select_dp->F; /* Allocate storage for each select-list item. */ printf("\n\n"); for (i=0; i<select_dp->F; i++) { /* Turn off high-order bit of datatype. */ sqlnul (&(select_dp->T[i]), &(select_dp->T[i]), &null_ok);  Appendix 2 Source code for the user interface of Ammon  237  switch (select_dp->T[i]) { case 1: /* CHAR datatype: no change in length needed. */  break; case 2: /* NUMBER datatype: use sqlprc() to extract precision and scale. */ sqlprc (&(select_dp->L[i]), &precision, &scale); /* Allow for maximum size of NUMBER. */ if (precision == 0) precision = 40; /* Also allow for decimal point and possible sign. */ select_dp->L[i] = precision + 2; /* Allow for a negative scale. */ if(scale<0) select_dp->L[i] += -scale; break; } /* Allocate space for the select-list data values. */ select_dp->V[i] = (char *)malloc(select_dp->L[i]); /* Coerce all datatypes to character. */ select_dp->T[i] = 1; } printf("\n\nM); /* Fetch each row selected */ EXEC SQL WHENEVER NOT FOUND GOTO end_query; j=MAX_SP-l; for(;;) { EXEC SQL FETCH C USING DESCRIPTOR select_dp; for (i=0; i<select_dp->F; i++) sprintf(descriptor_value[i] [j ],"%-.* s", select_dp->L[i]+1, select_dp->V[i]); j--; if G<0) { printf("\n Warning:Too many images meet the the search conditionVn The rest of images skipped.W); break; } } endquery: printf("\nNumber of rows processed: %d\n",sqlca.sqlerrd[2]); num_of_Items=sqlca.sqlerrd[2]; /* Free space used by descriptors. */ for (i=0; i<select_dp->F; i++) free (select_dp->V[i]);  Appendix 2 Source code for the user interface of Ammon /* Free space used by the descriptors themselves. */ sqlclu (binddp); sqlclu (select_dp); EXEC SQL CLOSE C; EXEC SQL COMMIT WORK; puts(" HAVE A GOOD DAY!\n"); /* disconnect from Oracle database engine */ EXEC SQL COMMIT RELEASE; return; /* ORACLE error handler */ sqlerror: printf("\n\n%. 70s\n",sqlca. sqlerrm. sqlerrmc); EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK; EXEC SQL COMMIT RELEASE; }  9. misc.c  /* functions specific for user interface */ #include <ammon.h> #include <retrieve.h> /* go back to main (genus) list from species sublist */ extern void main_list() { register int char  i, j ; tmp[10];  i=display_from=num_control_point=0; j=seq[break_point_in_genus]; Sublist[break_pointjn_genus]=displayed|j]-0; for (i=break_point_in_genus+l; i<num_of_Items; i++) if(displayed[seq[i]]==MAIN_LIST) {  238  Appendix 2 Source code for the user interface of Ammon displayed[seq[i]]=0; /* make it ready for display */ j++; } else { displayed[seq[i]]=1; Sublist[i]=0; } display_to=break_point_in_genus; num_remained=j; ln_sublist=0; sprintf(tmp, "%d", num_remained); panel_set_value(wait_num,tmp); sprintf(tmp, "%d" ,num_of_Items); panel_set_value(show_num, tmp); next_page(); } /* jump to the specified specimen */ extern void goto_specimen() { register int  i, j ;  display_from=0; j=image_index(control_point[0] .x,control_point[0] .y); num_control_point=displayed[j]=0; for (i=0; i<num_of_Items; i++) if(seq[i]=j) break; /* find it */ display_to=i; num_remained += 1; next_page(); } /* get a species sublist out of the genus list by clicking on a specimen of the species */ extern void find_species() { register int char  i,iO,j, k; tmp[10];  /* locate the specimen */  239  Appendix 2 Source code for the user interface of Ammon  240  display_from=0; j=image_index(control_point[0].x,control_point[OJ.y); num_control_point=0; for (i=0; i<num_of_Items; i++) if (seq[i]=j) /* And it */ break; display_to=break_point_in_genus=i; for (i=0; i<num_in_page; i++) if (current_page[i] = j) break; /* find its index on the current page */ for (i0=i+l; iO<num_in_page; i0++) displayed[current_page[iO]]=MAIN_LIST; k=i0=0; while (descriptor_value[SYNSPECffiS][rel[j]][iO] != " && descriptorjvalue[SYNSPECffiS][relU]][iO]) i0++; descriptor_value[SYNSPECffiS][rel[j]][iO]=0; for (i=break_point_injgenus; i<num_of_Items; i++) if (! strncmp(descriptor_value[SYNSPECIES] [rel[seq[i]]], descriptor_value[SYNSPECffiS][rel[j]],iO)) { /* find all specimens belonging to species descriptor_value[SYNSPECIES][rel[j]] */ displayed[seq[i]]=0; Sublist[i]=l; k++; } else if (!displayed[seq[i]]) { displayed[seq[i]]=MAIN_LIST; /* needed for going back to main list */ Sublist[i]=0; } In_sublist=l; /* currect display status */ num_remained=k; sprintf(tmp,,,%d",k); panel_set_value(show_num,tmp); next_page(); }  /* save area in the canvas defined by two corner points between[0] and between[l] as image file */ extern void save_as()  Appendix 2 Source code for the user interface of Amnion  241  { Pixrect *image_out; int xO,yO; char *filename; FILE *fp; filename = panel_get_value(file_name); if (filename) { if ((fp=fopen(filename, "w") = NULL); { printf("Can't open file %s\n",filename); return; } xO=yO=0; if (between[ 1 ] .x>between[0] .x && between[ 1 ] .y>between[0] .y) { xO=between[0].x; yO=between[0].y; image_out=mem_create(between[ 1 ] .x-xO,between[ 1 ] .y-y0,8); pw_read(image_out,0,0,between[ 1 ] .x-xO,between[ 1 ] .yyO,PIX_SRC,pw,xO,yO); } else {/* save the whole image canvas */ image_out=mem_create(canvas_rect.width, canvas_rect.height,8); pw_read(image_out,0,0,canvas_rect.width,canvas_rect.height,PIX_SRC,pw,0,0); } pr_dump(image_out,fp,colormap, RTSTANDARD, 1); pr_close(image_out); fclose(fp); } else printf("Please Choose a File Name!"); } 10. utility.h /* this is a list of image file directories, data sources with a few plates are lumped into directory'others' */ static char  *imageDir[] = {"andrew", "crickmay", "dagis", "donovan", "erben", "frebold","gabilly","geczy","guex","hall",,'hiUebrandt", "hirano", "howarth", "imlay", "jakob", "jaworski", "Jennifer", "jozsef, "kalacheva", "meister", "poulton", "quinzio", "repin", "riccardi", "robert", "Schlatter", "schleg", "smith", "stankevich", "taylor", "tilmann", "treatise", "westermann", "whiteaves", "white",  Appendix 2 Source code for the user interface of Ammon "wiedenmayer", "zeiss", "McLearn"};  11. utility.c #include <ammon.h> #include <utility.h> /* specimen may have multiple images which need to be separated before displaying */ extern void sort_image_list() { register int char char  i, k, connect, j=0; *buf, *bufl; bufy[30], tmp[30];  /* image list starts with MAX NUM-1 */ for (i=MAX_SP-num_of_Items; KMAXSP; i++) { bufl=(char *)strdup(descriptor_value[35][i]); ifO>MAX_IMAGE-5) break; if (strchr(bufl,'|') != NULL) {/* multiple images in bufl separated by '|' */ buf=(char *)strtok(bufl,T); /* save the first image into the sorted image list */ sprintf(image_name|j++],"%s",buf); relD-l]=i; sprintf(bufy,M%s",buf); /* find the base of the image file name */ if(strchr(bufy,'-,)!=NULL)  {  /* there is a'-' in the image name */ connect=l; truncate(bufy,"-"); else  }  {  /* there is no'-' in the image name */  242  Appendix 2 Source code for the user interface of Ammon  connect=0; k=strlen(bufy)-l; while (isdigit(bufy[k]) || bufy[k]= M ) k-; bufy[k+l]^0'; } /* repeat the above process */ while ((buf=(char *)strtok(NULL,"|")) != NULL) { if (connect) { if (isdigit(buf[0]) && strchrCbuf,'-') !=NULL) { k=strlen(bufy)-l; while (isdigit(bufy[k])) k--; strncpy(tmp,bufy,k+1); tmpfk+lHO"; sprintf(image_name[j-H-],"%s%s",tmp,buf); rel[j-l]=i; sprintf(bufy,"%s",image_name[j-l]); truncate(bufy,"-"); } elseif(isdigit(buf[0])){ sprintf(image_name[j++],"%s-%s",bufy,buf); relD-l]=i; } else { k=strlen(bufy)-l; while (isdigit(bufy[k])) k--; if(bufy[k]==1p•) k~; strncpy(tmp,bufy,k+1); tmp[k+l]=A0'; sprintf(image_nameO++],"%s%s",tmp,buf); rel[j-l]=i; if (strchr(buf/-') != NULL) { sprintf(bufy,"%s",image_name[j-l]); truncate(bufy,"-"); } else { connect=0; bufy[++k]='f; bufy[++k]=*\0'; } } } /* end of if (connect) */ else {  243  Appendix 2 Source code for the user interface of Ammon if (isdigit(buf[0]) && strchr(buf,'-') !=NULL) { sprintf(image_name[j-H-]j"%s-%s",bufy,buf); rel[j-l]=i; connect=l; sprintf(bufyJ"%s",image_name[j-l]); truncate(bufy,"-"); } else if (isdigit(buf[0]» { sprintf(image_name[j-H-],ll%s%s",bufy,buf); rel[j-l]=i; } else { k=strlen(bufy)-l; if(bufy[k]='p') k-S strncpy(tmp,bufy,k+1); tmp[k+l]=^'; sprintf(image_name[j-H-],"%s%s",tmp,buf); rel[j-l]=i; if (strchr(buf,'-') != NULL) { connect=l; sprintf(bufy,"%s",image_name[j-l]); truncate(bufy,"-"); } else \ if (bufy[k]='p') { bufy[++k]='f; bufy[++k]=,\0';} } } } k=0; while (image_name[j-l][k] != ") ++k; image_name[j-1 ] [k]=I\0'; else  } { /* single image in the name */ k=0; while ((image_name[j][k]=bufl[k]) !='') ++k; image_name[j ] [k]=l\0'; rel[j]=i;  } } /* end of for loop */  244  Appendix 2 Source code for the user interface of Ammon  num_pf_Items=j; /* prepare for show_descriptor */ for (i=0; i<NUM_OF_DESCRIPTOR; i++) *descriptor_value[i][0]=0; /* none of the images have been displayed */ for (i=0; i<num_of_Items; i++) displayed[i]=0; } /* image name from Ammon is relative path, file dir need to be added as prefix */ extern void build full_name() { register int char  i, num_of_dir; tmp[60];  num_of_dir = sizeof imageDir / sizeof imageDir[0]; for (i=0; i<num_of_Items; i++) { tmp[0] = 0; for (j=0; j<num_of_dir; j++) if (strstr(image_name[i], imageDir[j])) sprintf(tmp,"/home/images/%s/%s.ras",imageDir|j],image_name[i]); if(!tmp[0]) sprintf(tmp, "/home/images/other s/%s. ras", image_name[i]); sprintf(image_name[i],"%s",tmp); } /* adjust the image brightness by modifying colormap */ extern void adjust_brightness() { register int  i, j , k;  k=(int) panel_get_value(bright);  245  Appendix 2 Source code for the user interface of Ammon for(i=l;i<252;i++) if ((j=cs+k+i)>0 && j<256) /* cs is the brightness of color entry 1 */ red[i]=green[i]=blue[i]=j; elseif(j<0) red[i]=green[i]=blue[i]=0; elseif(j>255) red[i]=green[i]=blue[i]=255; pw_setcmsname(pw, "image_cmp"); pw_putcolormap(pw, 0, 253, red, green, blue); } /* adjust the image brightness by modifying colormap */ extern void adjust_contrast() { register int  i, j , k;  k=(int) panel_j*et_value(contrast); for(i=l;i<252;i++) if ((j=cs+k*i/10)>0 && j<256) /* cs is the brightness of entry 1 */ red[i]=green[i]=blue[i]=j; elseifO<0) red[i]=green[i]=blue[i]=0; elseifG>255) red[i]=green[i]=blue[i]=25 5; pw_setcmsname(pw, "imagecmp"); pw_putcolormap(pw, 0, 253, red, green, blue); } /* produce negative of the image */ extern void reverse() { register int  i;  for(i=l;i<252;i-H-) red[i]=green[i]=blue[i]=255-red[i]; pw_setcmsname(pw, "imagecmp"); pw_putcolormap(pw, 0, 253, red, green, blue);  246  Appendix 2 Source code for the user interface of Ammon } extern void quit(item, event) { /* quit without user confirmation */ if(textwin) textsw_reset(text_win, 0,0); (void)window_set(command_frame, FRAME_NO_CONFIRM, TRUE, 0); (void)window_destroy(command_frame); (void)window_set(display_window, FRAME_NO_CONFIRM, TRUE, 0); (void)window_destroy(display_window); } extern void help(client, event) Notify_client Event {  client; *event;  alert_prompt( (Frame)client, NULL, ALERT_MESSAGE_STRINGS, "To be implemented", 0, ALERTBUTTONNO, "Cancel", ALERT_OPTIONAL, 1, ALERT_NO_BEEPING, 1,  o); } /* convert query statement into plain text */ extern query_to_plain(buf) char *buf; { buf=substitute(buf,"=","= :"); buf=substitute(buf, "like","like :"); buf=substitute(buf,"> ","> :"); buf=substitute(buf,"< ","< :"); buf=substitute(buf,"","%");  247  Appendix 2 Source code for the user interface of Ammon } /* replace string pattern s2 with si in s */ static char * substitute^, sl,s2) char *s, *sl, *s2; { register int i, j ; char tmp[200], *buf, *bufy; buf=s; i=strlen(buf); j=strlen(s2); tmp[0]=0; while (bufy=(char *)strstr(buf,s2)) { strncat(tmp,buf,i-strlen(bufy)); strcat(tmp,sl); buf=&bufy[j]; i=strlen(buf); } strcat(tmp,buf); s=strdup(tmp); return s; } static char * truncate(sl,s2) char *sl, *s2; { register int i; i=0; while (si[i++] != s2[0]) sl[--i]=:\0'; }  return si;  /* if lots of specimens meet the search condition, it will take a long time to complete the query, if you want to quit before it finishes simply press the STOP key */ extern void * stop_op()  248  Appendix 2 Source code for the user interface of Ammon { exit (0); }  12. win.h /* button locations */ #define COMMAND_START_ROW  12  #define COMMANDINCREMENT  2  /* introductory text locations */ #define X_START 140 #define Y_START 90 #define YJNCREMENT 25 static void adjust_info_panel(Panel local_panel);  13. win.c /* windows, buttons related functions */ #include <ammon.b> #include <icon.h> #include <win.h> /* introductory text locations */ #define X_START 140 #define Y_START 90 #defme Y INCREMENT 25  extern void create_command_button(frame_local) Frame framelocal; { panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTEFY_PROC, queryfromjext, PANEL_LABEL_IMAGE, panel_button_image (frame_local,"Combination",13,font),  249  Appendix 2 Source code for the user interface of Amnion 0);  panel_create_item(frame_local,PANEL_MESSAGE, PANELJTEMY, ATTR_ROW(COMMAND_START_ROW+COMMAND_INCREMENT), PANEL_LABEL_FONT, font, PANEL_LABEL_STRING,"Some Utility:", 0);  panelcreate item(frameJocal,PANEL_BUTTON, P A N E L J T E M Y , ATTR_ROW(COMMAND_START_ROW +2*COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANELJsTOTIFYPROC, next_page, PANEL_LABEL_IMAGE, panelbuttonjmage (frame_local,"Next Page", 13,font),  o); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW +3 *COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANELJsTOTIFYPROC, previous_page, PANEL_LABEL_IMAGE, panel_button_image (frame_local, "Previous Page",13,font),  o); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW +4*COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, goto_specimen, PANELLABELIMAGE, panelbuttonimage (frame_local,"Goto Specimen", 13,font),  o); panel_create_item(frame_local,PANEL_TEXT, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW +5*COMMAND_INCREMENT), PANEL_LABEL_STRING, "Brightness:", 0); bright=panel_create_item(frame_local,PANEL_SLIDER, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW +6*COMMAND_INCREMENT+l), PANEL_SHOW_VALUE, FALSE,  250  Appendix 2 Source code for the user interface of Ammon PANEL_VALUE, 0, PANEL_MIN_VALUE, -50, PANEL_MAX_VALUE, 50, PANELSLIDERJWIDTH, 94, PANEL_NOTIFY_PROC, adjustbrightness, 0); panel_create_item(frame_local,PANEL_TEXT, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW +7*COMMAND_INCREMENT+l), PANEL_LABEL_STRING, "Contrast:", 0); contrast=panel_create_item(frame_local,PANEL_SLIDER, P A N E L J T E M Y , ATTRJlOW(COMMAND_START_ROW +8 *COMMAND_INCREMENT), PANEL_SHOW_VALUE, FALSE, PANEL_VALUE, 10, PANEL_MTN_VALUE, 1, PANEL_MAX_VALUE, 20, PANEL_SLIDER_WIDTH, 94, PANEL_NOTIFY_PROC, adjust_contrast, 0); panel_create_item(frame_local,PANEL_BUTTON, P A N E L J T E M Y , ATTR_ROW(COMMAND_START_ROW +9*COMMAND_INCREMENT+1), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, mainjist, PANEL_LABEL_IMAGE, panel_button_image (frame_local,"MainList",13,font), 0);  panel_create_item(ftame_local, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, P A N E L J T E M Y , ATTR_ROW(COMMAND_START_ROW +10*COMMAND_INCREMENT+1), PANEL I T E M X , ATTRCOL(O), PANELNOTEFYJ R O C , find_species, PANELLAJBELIMAGE, paneljutton image (frameJocal,"Speci Sublist", 13,font). 0);  panel_create item(frame local,PANEL_BUTTON,  251  Appendix 2 Source code for the user interface of Amnion PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW + 11 *COMMAND_INCREMENT), PANELJ T E M X , ATTR_COL(0), PANEL_NOTIFY_PROC, reverse, PANEL_LABEL_IMAGE, panel_button_image (frameJocal, "Reverse Image", 13,font), 0);  panel_create_item(frame_local,PANEL_BUTTON, PANEL I T E M Y , ATTR_ROW(COMMAND STARTROW +12 *COMMAND_INCREMENT), P A N E L J T E M X , ATTR_COL(0), PANELNOTIFY PROC, saveas, PANELLABEL IMAGE, panelbuttonimage (frame_local,"Save Image As", 13,font), 0);  file_name=panel_create_item(frame_local,PANEL_TEXT, PANEL_ITEM_Y,ATTR_ROW(COMMAND_START_ROW +13 *COMMAND_INCREMENT), PANELLABELFONT, font, PANELJLABEL_STPJNG, "File:",  o); panel_create_item(frame_local,PANEL_BUTTON, P A N E L I T E M Y , ATTR_ROW(COMMAND_START_ROW +14*COMMAND_rNCREMENT), PANELJ T E M X , ATTRCOL(O), PANEL NOTIFYPROC, help, P ANEL_L ABEL_IMAGE,panel_button_image(frame_local, "Help" ,4,font), 0); buttonQuit = panel_create_item(frame_local,PANEL_BUTTON, / P A N E L I T E M Y , ATTR_ROW(COMMAND_START_ROW +14 * COMMANDINCREMENT), P A N E L J T E M X , ATTR_COL(12), PANEL NOTIFYJROC, quit, PANEL_LABEL_IMAGE,panel_button_image(frameJocal,"Quit",4,font), 0);  extern void initJnfo_panel(frame_local) Frame frame local;  252  Appendix 2 Source code for the user interface of Ammon  /* font for displaying title */ font=pf_open("/apps/sundesk/fonts/sunpaint/R.24"); /* create info window to display the introduction text */ info_panel=window_create(frame_local, PANEL, PANEL_LABEL_BOLD, FALSE, WIN_X, 0, WIN_Y, 0, WIN_WH)TH, screen_rect.width-command_rect.width, WIN_HEIGHT, info_rect.height, 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, X_START-20, PANEL_ITEM_Y, Y_START-40, PANEL_LABEL_STRING, "WELCOME AMMONITE  TO JURASSIC IMAGE DATABASE",  o); /* font for displaying introductory text */ font=pf_open("/apps/sundesk/fonts/sunview/lucida-19.v"); panel_create_item(info_panel,PANEL_MESSAGE, PANELJLABELFONT, font, PANEL_ITEM_X, X_START+80, PANEL_ITEM_Y, Y_START, PANELLABELSTRING, "You can retrieve Jurassic ammonites by", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, P A N E L J T E M X , X_START, P A N E L I T E M Y , YSTART+YINCREMENT, PANEL_LABEL_STRING, "1. Taxonomy: Family, Genus, and Species", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANELJTEM_X, X_START, PANEL ITEM_Y, Y_START+2*Y_INCREMENT, PANEL_LABEL_STRING, "2. Stratigraphy: Stage and Standard Zone",  253  Appendix 2 Source code for the user interface of Ammon  254  0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, P A N E L I T E M X , XSTART, PANEL_ITEM_Y, YSTART+3 * YINCREMENT, PANEL_LABEL_STRING, "3. Geography: Geographic Area and Country.", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, P A N E L I T E M X , XSTART, P A N E L J T E M Y , Y_START+4*YJNCREMENT, PANEL_LABEL_STRING, "4. Morphology: Volution, Expansion Rate, Whorl Shape, and Rib Form", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, X_START, PANEL_ITEM_Y, Y_START+5*YJNCREMENT, PANELLABELSTRING, "5. Reference: in which the figure of the specimen appears.", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, P A N E L I T E M X , XSTART+40, PANELJTEMY, Y_START+6*YJNCREMENT, PANELLABELSTRING, "You can also retrieve by combining the above criteria. ",  o); }  static void adjust_info_panel(local_panel) Panel local_panel { int i; char tmp[40], *buf; Panelitem item; /* destroy all old panel items in the info panel */ panel_each_item(local_panel, item)  Appendix 2 Source code for the user interface of Amnion panel_destroy_item(item); panel_end_each inforect. height = screen_rect.height-text_rect.height-canvas_rect.height; info_rect.width = screenrect.width-commandrect. width; window_set(local_panel, WINJHEIGHT, info_rect.height, WINWIDTH, info_rect. width, 0); /* display the query statement of the menu selection */ if(num_of_Items)  {  /* translate from SQL query to plain text, eliminate':' */ /* skip 'select * from OPS$liang.ammon_image where' in query statement */ buf=&query_statement[42]; query_to_plain(buf); i=strlen(buf); buf[i-2]=0; tmp[0]=0; sprintf(tmp,"%s%s",buf,search_condition[0]); } else tmp[0]=0; /* condition_text is the text field for query text display or input, you can type in a query and press the Combination button to search the database */ condition_text = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 180, PANEL_VALUE_DISPLAY_LENGTH, 200, PANEL_LABEL_X, ATTRCOL(O), PANELJLABELY, ATTRROW(O), PANEL_LABEL_STRING, "Search :", PANEL_VALUE, tmp,  o); /* display number of images retrieved */ if (num_of_Items) sprintf(tmp,"%4d",num_of_Items); shownum = panel_create_item(local_panel, PANELTEXT,  255  Appendix 2 Source code for the user interface of Ammon PANEL_VALUE_DISPLAY_LENGTH, 5, PANEL_LABEL_X, ATTR_COL(0), PANELLABELY, ATTR_ROW(l), PANEL_LABEL_STRTNG, "Images Returned", PANEL_VALUE, tmp, 0); /* number of images wait to be displayed */ wait_num = panel_create_item(local_panel, PANEL TEXT, PANEL_VALUE_DISPLAY_LENGTH, 5, PANEL_LABEL_X, ATTR_COL(22), PANEL_LABEL_Y, ATTR_ROW(l), PANEL_LABEL_STRING, "Remained:",  o); panel_paint(local_panel, PANEL_CLEAR); } extern void adjust_display_window(local_panel) Panel local_panel; { start_status=l;/* now the system has gone through at least one query */ adjust_info_panel(); /* adjust imagecanvas size due to the creation of a new text window */ window_set(image_canvas, WIN_X, 0, W I N Y , screen_rect.height-canvas_rect.height, WIN_WIDTH, canvas_rect.width, WINHEIGHT, canvas_rect.height, 0); text_win=window_create(display_window, TEXTSW, W I N X , 0, W I N Y , screen_rect. height-canvas_rect. height-textrect. height, WINWIDTH, text_rect.width, WINHEIGHT, text_rect.height, 0);  256  Appendix 2 Source code for the user interface of Ammon  }  extern void canvas_handler(event) Event * event; { register int i, j ; if (event_is_up(event)) return; switch (event_action(event)) { case MS_LEFT: /* locate the image and display related info */ i=image_index(event_x(event),event_y(event)); if(i>=0) sho w_descriptors(i); break; case MSMIDDLE: /* mark the point with color 252 and determine the image scale */ pw_put(p w, event_x(event), event_y(event), 25 2); control_point[num_control_point].x=event_x(event); control_point[num_control_point].y=event_y(event); if(!num_control_point) { image_scale-atof(descriptor_value[SCALE][rel[image_index (event_x(event),event_y(event))]]); if (!image_scale) image_scale=1.0; } num_control_point++; case MS_RIGHT: /* mark two points for ploting brightness profile */ if(between[l].x || between[l].y) { i=between[l].x; j=between[l].y; between[ 1 ] .x=event_x(event); between[ 1 ] .y=event_y(event); between[0].x=i; between[0].y=j; } else if (between[0].x || between[0].y) { between[l].x=event_x(event); between[l].y=event_y(event); } else { between[0] .x=event_x(event); between[0]. y=event_y( event);} break; default: break; }  257  Appendix 2 Source code for the user interface of Ammon  258  extern void clear_canvas() { (void)pw_writeback:ground(pw,0,OXint)(LINT_CAST(window_get(image_canvas, CANVAS_WIDTH)))J (int)(LINTj:AST(window^et(image_canvas, CANVAS_HEIGHT))), PIX_CLR); }  Appendix 3 Source code for program imageEdit Appendix 3 Source code for program imageEdit There are 5 files in this program: imagedit.h, main.c, utility.c, file.c, modify.c. 1. imagedit.h /* header file for imageEdit *  * Author: Bo Liang * Department of Geological Sciences * The University of British Columbia * Date: May 1991 * Modifications: April 1994 */  #include <stdio.h> #include <math.h> #include <suntool/tty.h> #include <sys/types.h> #include <sunwindow/attr.h> #include <sunwindow/defaults.h> #include <suntool/seln.h> #include <suntool/expand_name.h> ^include <suntool/alert.h> #include <suntool/frame.h> #include <suntool/sunview.h> ^include <suntool/panel.h> #include <suntool/canvas.h> #include <suntool/walkmenu.h> #include <suntool/scrollbar.h> /* maximum number of characters in the file path name */ #define MAXJPATHLEN #definePi #define MIN_WIDTH 700 #define MAX_IMAGE  1024 3.14159 /* minimum width of the window */ 3000 /* maximum size of the image */  #define LOCATE #define CLEAN  /* locate the area of interest */ /* clean the image */  Frame Canvas Pixwin  0 1  base_frame, canvas; *pw;  /* indicate the amount of change wanted */  259  Appendix 3 Source code for program imageEdit  Panelitem  rotate, bright, contrast;  /* clean or locate the image of interest */ Panelitem  status;  /* color used to erase noise or mark the border of the image */ Panel_item  bordercolor, erasercolor, eraser_width;  /* file name and directory */ Panelitem  dirjtem, fnameitem;  int  w, h, bpp;  /* image width, height and depth */  /* size of the base frame and canvas */ struct size { int width; int height; } frame_size = { 700, 900}; struct size canvas_size= {800, 1000}; unsigned char red [256], green [256], blue [256]; colormap_t colormap = { RMTEQUALRGB, 256, red, green, blue}; int int float float  x[2], y[2]; /* corner coords */ edge[4][MAX_IMAGE]; /* buffer for old data of the four sides */ aver, var, fct[2]; *a; /* array to hold raw data of the image */  /* panel notify procs */ void void void void void void void void void  load_image(); save_image(); quit(); rotate_proc(); rightness_proc(); contrast_proc(); image_edit(Event*, short, short, short); init_data(); reset_image();  /* canvas procs */  260  Appendix 3 Source code for program imageEdit  void void void  261  modify_canvas(); clear_canvas(); handle_event();  2. main.c /* main entry for imageEdit */ #include "imagedit.h" main(argc, argv) int argc; char **argv; { int i; void  init_panel(), init_canvas();  /* create a base frame to hold the panel and image canvas. */ baseframe = window_create((Window) 0, FRAME, FRAME_LABEL, "INTERACTIVE IMAGE EDITOR", WIN_WIDTH, frame_size.width, WIN_HEIGHT, frame_size. height, FRAMEJCON, icon_create(ICON_IMAGE, &canvas_demo_pr, 0), FRAME_NO_CONFIRM, TRUE, FRAMEARGS, argc, argv, 0); /* initialize the info and command panel. */ init_panel(); init_canvas(); window_main_loop(base frame); exit(0); }  static void init_panel() {  Appendix 3 Source code for program imageEdit Panel panel; char current_dir[MAX_PATH_LEN]; panel = window_create(base_frame, PANEL, PANELLABELBOLD, TRUE, 0); bright = panel_create_item(panel, PANELSLIDER, PANEL_LABEL_STRING, "Brightness Adjustment: ", PANEL_SLIDER_WIDTH, 100, PANEL_VALUE, 50, PANELMINVALUE, 0, PANEL_MAX_VALUE, 100, PANEL_NOTIFY_PROC, brightness_proc,  o); contrast = panel_create_item(panel, PANELSLIDER, PANELLABELSTRING, "Contrast Adjustment: ", PANELSLIDERWIDTH, 100, PANEL_VALUE, 50, PANELMINVALUE, 0, PANELMAXVALUE, 100, PANELNOTIFYPROC, contrast_proc,  o); rotate = panel_create_item(panel, PANELSLIDER, PANELLABELSTRING, "Rotate image: ", PANELSLIDERWIDTH, 100, PANELVALUE, 0, PANEL_MIN_VALUE, -90, PANEL_MAX_VALUE, 90, PANELNOTIFYPROC, rotate_proc,  o); status = panel_create_item(panel, PANELCHOICE, PANEL_LABEL_X, ATTRCOL(O), PANELLABELY, ATTR_ROW(3), PANEL_LABEL_STRING, "Edit Options:", PANELCHOICESTRINGS, "Locate image", "Erase noise", 0,  o); bordercolor = panel_create_item(panel, PANELTEXT, PANELLABELX, ATTR_COL(0), PANELLABELY, ATTR_ROW(4),  262  Appendix 3 Source code for program imageEdit PANEL_VALUE_DISPLAY_LENGTH, 3, PANELLABELSTRING, "Border color:", 0);  eraser_color = panel_create_item(panel, PANELTEXT, PANEL_LABEL_X, ATTR_COL(19), PANEL_LABEL_Y, ATTR_ROW(4), PANEL_VALUE_DISPLAY_LENGTH, 3, PANEL_LABEL_STRING, "Eraser color:", 0);  eraser_width = panel_create_item(panel, PANELTEXT, PANEL_LABEL_X, ATTR_COL(36), PANEL_LABEL_Y, ATTR_ROW(4), PANEL_VALUE_DISPLAY_LENGTH, 3, PANEL_LABEL_STRING, "Eraser width:", 0);  diritem = panel_create_item(panel, PANEL_TEXT, PANEL_LABEL_X, ATTR_COL(55), PANEL_LABEL_Y, ATTR_ROW(0), PANEL_VALUE_DISPLAY_LENGTH, 23, PANEL_VALUE, getwd(current_dir), PANEL_LABEL_STRING, "Dir: ", 0);  fhame_item = panel_create_item(panel, PANELTEXT, PANEL_LABEL_X, ATTR_COL(55), PANEL_LABEL_Y, ATTR_ROW(l), PANEL_VALUE_DISPLAY_LENGTH, 23, PANEL_LABEL_STRING, "File:", 0);  (void) panel_create_item(panel, PANELBUTTON, PANELLABELX, ATTR_COL(55), PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE, panel_button_image(panel, "Load", 0, 0), PANEL_NOTIFY_PROC, load_image, 0);  (void) panel_create_item(panel, PANELBUTTON, PANEL_LABEL_X, ATTR_COL(62),  263  Appendix 3 Source code for program imageEdit PANEL_LABEL_Y, ATTR_ROW(2), PANELLABELJMAGE, panel_button_image(panel, "Save", 0, 0), PANEL_NOTIFY_PROC, save_image, 0); (void) panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(69), PANEL_LABEL_Y, ATTR_ROW(2), PANEL_LABEL_IMAGE, panel_button_image(panel, "Quit", 0, 0), PANEL_NOTIFY_PROC, quit, 0); (void) panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(55), PANEL_LABEL_Y, ATTR_ROW(4), PANELLABELJMAGE, panel_button_image(panel, "Reset", 0, 0), PANEL_NOTIFY_PROC, reset_image, 0); (void) panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(69), PANEL_LABEL_Y, ATTR_ROW(4), PANEL_LABEL_IMAGE, panel_button_image(panel, "Clear", 0, 0), PANEL_NOTIFY_PROC, clear_canvas,  o); window_set(panel, PANELCARETITEM, fhameitem, 0); (void) window_fit_height(panel); }  static void init_canvas() { Scrollbar  verticalsb, horizontalsb;  /* loaded image may be larger than the window size, need a scrollable canvas. */ vertical_sb = scrollbar_create(SCROLL_LINE_HEIGHT, 5, (char *) 0); horizontal_sb = scrollbar_create(SCROLL_LINE_HEIGHT, 5, (char *) 0); canvas = window_create(base frame, CANVAS, WIN_VERTICAL_SCROLLBAR, vertical_sb, WIN_HORIZONTAL_SCROLLBAR, horizontal_sb,  264  Appendix 3 Source code for program imageEdit CANVAS_RETAINED, FALSE,  /* necessary for the following * modification */ CANVAS_AUTO_SHRINK, FALSE, WIN_EVENT_PROC, handle_event, CANVAS_FIXED_IMAGE, FALSE, CANVAS_WIDTH, canvas_size.width, CANVAS_HEIGHT, canvas_size. height, 0); window_set(canvas, WIN_CONSUME_PICK_EVENT, LOC_TRAJECTORY, 0); /* declare the canvas has 256 colors */ pw = (Pixwin *) windowj>et(canvas, WINPIXWIN); pw_setcmsname(pw, "rainbow"); pw_putcolormap(pw, 0, 256, red, green, blue); /* make it a color, retained canvas. */ window_set(canvas, CANVAS_RETATNED, TRUE, CANVAS_AUTO_CLEAR, TRUE, WIN_VERTICAL_SCROLLBAR, vertical_sb, WIN_HORIZONTAL_SCROLLBAR, horizontal_sb, 0);  } 3. utility.c /* responses to mouse event */ #include "imagedit.h" extern void handle_event(canvas_local, event) Canvas canvaslocal; Event *event; { short upper_corner = FALSE; short lower_corner = FALSE; short erase = FALSE; if (event_is_up(event)) return; switch (event_action(event)) { case MS LEFT:  265  Appendix 3 Source code for program imageEdit  266  upper_corner = TRUE; break; case MS_MIDDLE: erase = TRUE; break; case MS_RIGHT: lowercorner = TRUE; break; case LOCTRAJECTORY: if (window_get(canvas_local, WIN_EVENT_STATE,MS_MIDDLE)) erase = TRUE; break; default: break; } image_edit(event, lower_corner, upper_corner, erase); } extern void modify_canvas(width, height) int width, height; { if (width<MIN_WIDTH) width=MIN_WIDTH; (void)window_set(canvas, CANVAS_WIDTH, width+20, /* 20 - margin */ CANVAS_HEIGHT, height+20, 0); }  extern void clear_canvas() { (void)pw_writebackground(pw,0,0,(int)(LE^T_CAST(windowjget(canvas, CANVAS_WIDTH))), (int)(LINT_CAST(window_get(canvas, CANVAS_HEIGHT))), PDC_CLR); } extern void quitO {  Appendix 3 Source code for program imageEdit  /* quit without user confirmation */ (void)window_set(base_frame, FRAME_NO_CONFIRM, TRUE, 0); (void)window_destroy(base_frame); } 4. file.c #include "imagedit.h" /* load the specified image, and initialize parameters */ static void load_image() { Pixrect *image_orig; FILE *fp; char * filename; if (!strlen(filename = panel_get_value(fname_item))) { printf( "Please specify a file name to load !"); return; } clear_canvas(); x[0]=x[l]=y[0]=y[l]=0; /* reset the corner coordinates */ var=aver=0.0; /* initialization for the average and variance */ if ((fp=fopen(filename, V ) ) = N U L L ) { printfC'Can't open this file !"); return; } /* read image attribute */ image_orig=pr_load(fp, colormap); w=image_orig->pr_size.x; h=image_orig->pr_size. y; bpp=image_orig->pr_depth;  267  Appendix 3 Source code for program imageEdit modify_canvas(w,h); /* adjust canvas size */ panel_set_value(status,0); /* default status: locate area of interest */ /* let color entry 255 be green, easily visible in a grey scale image */ */ green[255]=255; red[255]=blue[255]=0; pw_setcmsname(pw, "rainbow"); pw_putcolormap(pw, 0, 256, red, green, blue); /* copy the image to window pw */ pw_rop(pw, 10,10,w,h,PIX_SRC,image_orig,0,0); pr_close(image_orig); fclose(fp); } /* save the specified area of pw as an image file */ static void save_image() { Pixrect *image_mody; int i, j , k; char *filename; FILE *fp; filename = panel_get_value(fname_item); /* get the file name */ if((fp=fopen(filename, "w")) = NULL) { printfC'Can't open this file !"); return; } if (!x[l] && !y[l]) /* if no specified area of interest, save the whole pw */ { x[0]=y[0]=0; x[l]=w; y[l]=h; } w=x[l]-x[0]-l; h=y[i]-y[0]-l;  268  Appendix 3 Source code for program imageEdit image_mody=mem_create(w,h,bpp); /* change the color map back to normal, entry 255 is white now */ red[255]=green[255]=blue[255]=255; if(bpp>l) { /* x[0]+l,y[0]+l help to skip the color border */ pw_read(image_mody,0,0, w,h,PIX_SRC,pw,x[0]+1 ,y[0]+1); pr_dump(image_mody,fp,&colormap, RT_BYTE_ENCODED, 1); } else /* black and white image */ { for (i=0; i<h; i++) forG=0;j<w;j++) { k = pw_get(pw,x[0]+l+j,y[0]+l+i); if(k=255) pr_put(image_mody, j , i, 1); } pr_dump(image_mody,fp,NULL,RT_B YTE_ENCODED, 1); } pr_close(image_mody); clear_canvas(); fclose(fp); } static void reset_image() { /* simply reload the image */ load_image(); } 5. modify.c /* image edit related functions */ #include "imagedit.h" /* rotate the image around the center by angle */ extern void rotate_proc()  269  Appendix 3 Source code for program imageEdit { Pixrect *image_mody; register int i, j , k, wl, wO, hi, hO, register int xmin, xmax, ymin, ymax, xx[6], yy[6]; double angle; k = (int) paneljjet_yalue(rotate); if(k<90){ angle = (double) -PI * k / 180; /* convert to radius */ xx[0] = w / 2; yy[0] = h / 2 ; xmin = ymin = MAXIMAGE; xmax = ymax = 0; /* compute the coordinates of the four corners after rotation */ xx[l yy[i xx[2 yy[2 xx[3 yy[3 xx[4 yy[4  = -w / 2 * cos(angle) - h / 2 * sin(angle); = w / 2 * sin(angle) - h / 2 * cos(angle); = w / 2 * cos(angle) - h / 2 * sin(angle); = -w / 2 * sin(angle) - h / 2 * cos(angle); = -w / 2 * cos(angle) + h / 2 * sin(angle); = w / 2 * sin(angle) + h / 2 * cos(angle); = w / 2 * cos(angle) + h / 2 * sin(angle); = -w / 2 * sin(angle) + h / 2 * cos(angle);  /* compute the coordinates of the four new corners */ for(i= l ; i < 5 ; i + + ) { if(xx[i] <xmin) xmin = xx[i]; else if (xx[i] > xmax) xmax = xx[i]; if(yy[i] <ymin) ymin = yy[i]; else if (yy[i] > ymax) ymax = yy[i]; } wl = xmax - xmin + 1; /* width of the rotated image */ hi = ymax - ymin + 1; /* height of the rotated image */ wO = wl / 2; h0 = h l / 2 ; image_mody = mem_create(wl, hi, bpp); /* locate the coord, in the orig. image for each point in the new one */ fbr(i = 0 ; i < w l ; i + + ) for(j = 0 ; j < h l ; j + + ) {  270  Appendix 3 Source code for program imageEdit xx[5] = (i - wO) * cos(angle) - (j - hO) * sin(angle) + xx[0]; yy[5] = (i - wO) * sin(angle) + (j - hO) * cos(angle) + yy[0]; if (xx[5] >= 0 && xx[5] < w && yy[5] >= 0 && yy[5] < h) k = pw_get(pw, xx[5], yy[5]); else k = 254; pr_put(image_mody, i, j , k); } w = wl; h = hl; } else  { /* exactly 90 degree */ i = h; h = w; w = i; image_mody = mem_create(w, h, bpp); for (i = 0; i < w; i++) for(j = 0;j<h;j++) pr_put(image_mody, i, j , pw_get(pw, j , w - i)); }  modify_canvas(w, h); clearcanvasO; pw_rop(pw, 0, 0, w, h, PIX_SRC, imagemody, 0, 0); pr_close(image_mody); }  extern void brightness_proc() { register int float  i, j , k; tmp;  if(!aver) /* thefirsttime */ initdataO; k = (int) panel^etvalue^right); /*  * increase the average brightness without change the contrast (variance) * it is much slower than simply change color map but offer some nice effect */  fct[0] = k / 50.0; /* brightness scale factor */ tmp = fct[0] * aver; tmp -= fct[l] * aver; /* fct[l] - contrast scale factor */  271  Appendix 3 Source code for program imageEdit for (i = 0; i < w; i++) for(j = 0;j<h;j++){ k = fct[l] * a [ i * h + j ] + tmp; if(k>254) k = 254; /* entry 255 is reserved */ elseif(k<l) k=l; pw_put(pw, i, j , k); } } extern void contrast_proc() { register int float  i, j , k; tmp;  if (!var) /* the first time */ init_data(); k = (int) panel^get_value(contrast); fct[l] = k / 5 0 . 0 ; tmp = (fct[0] - fct[l]) * aver; for (i = 0; i < w; i++) for(j = 0;j<h;j++){ k = fct[l] * a [ i * h + j ] + tmp; if(k>254) k = 254; elseif(k<l) k=l; pw_put(pw, i, j , k); } } /* compute the average brightness and contrast (variance) for the image */ static void init_data() { register int float if (a != NULL) free(a);  i, j , k; tmp;  272  Appendix 3 Source code for program imageEdit /* allocate memory to hold the raw image data */ a = (float *) malloc(w * h * sizeof(float)); fct[0] = fct[l] = 1.0; for (i = 0; i < w; i++) for(j=0;j<h;j++){ a[i * h + j] = pw^etfcw, i, j); aver+=a[i * h + j ] ; var += sqr(a[i * h + j]); } tmp = aver; k = w * h; aver /= k; var = var + k * sqr(aver) - 2 * aver * tmp; var = sqrt(var / (k - 1)); } /* erase noise in the image or locate area of interest to save */ extern void image_edit(event, lowercorner, uppercorner, erase) Event *event; short lower_corner, uppercorner, erase; { register int i, colorindex; long op; brush = (struct pr_brush *) malloc(4); if (status == CLEAN) { brush->width = atoi(panel_get_value(eraser_width)); if (brush->width < 0 || brush->width > w) brush->width = w /10; /* actually it is the height of the brush */ brush_wid = w / 20; /* real width of the brush, fixed for each image */ color_index = atoi(panel_get_value(eraser_color)); } else colorindex = atoi(panel^get_value(border_color)); if (colorindex < 0) color_index = 0; else if (colorjndex > 255) color_index = 255; if (bpp > 1)  273  Appendix 3 Source code for program imageEdit op = PIX_SRC | PIX_COLOR(color_index); else op = PIX_SRC | PIX_COLOR(0); /* use bg color */ /* take proper action based on mouse event */ if (status = CLEAN && erase) (void) pw_line(pw, eventx(event) - brush_wid, event_y(event), event_x(event) + brush_wid, event_y(event), brush, NULL, op); else if (status = LOCATE && uppercorner) { if (!x[0] && !y[0]) { /* the first time */ x[0] = event_x(event); y[0] = event_y(event); /* save original border data in edge */ for(i = 0 ; i < h -y[0];i++) edge[0][i] = p w ^ e t ^ w , x[0], y[0] + i); for(i = 0 ; i < w -x[0];i++) edge[l][i] = pw_get(pw, x[0] + i, y[0]); /* draw the upper border using the color of color_index */ (void) pw_vector(pw, x[0], y[0], x[0], h, op, 1); (void) pw_vector(pw, x[0], y[0], w, y[0], op, 1); } else { /* undo the old border before drawing a new one */ for (i = 0; i < h - y[0]; i++) pw_put(pw, x[0], y[0] + i, edge[0][i]); for (i = 0; i < w - x[0]; i++) pw_put(pw, x[0] + i, y[0], edge[l][i]); x[0] = event_x(event); y[0] = event_y(event); for (i = 0; i < h - y[0]; i++) edge[0][i] = pw_jget(pw, x[0], y[0] + i); for (i = 0; i < w - x[0]; i++) edge[l][i] = pw_get(pw, x[0] + i, y[0]); /* draw a new upper border using the color of colorindex */ (void) pw_vector(pw, x[0], y[0], x[0], h, op, 1); (void) pw_vector(pw, x[0], y[0], w, y[0], op, 1);  274  Appendix 3 Source code for program imageEdit } } else if (status = LOCATE && lowercorner) { if (!x[l] && !y[l]) { /* the first time */ x[l] = eventx(event); y[l] = event_y(event); /* save original border data in edge */ for(i = 0;i<y[l];i++) edge[2][i] = pw_get(pw, x[l], i); for(i = 0;i<x[l];i++) edge[3][i] = pw^etfrw, i, y[l]); /* draw the lower border using the color of colorjndex */ (void) pw_vector(pw, x[l], y[l], x[l], 0, op, (void) pw_vector(pw, x[l], y[l], 0, y[l], op, } else { for(i = 0;i<y[l];i++) pw_put(pw, x[l], i, edge[2][i]); for(i = 0;i<x[l];i++) pw_put(pw, i, y[l], edge[3][i]); x[l] = event_x(event); y[l] = event__y(event); for(i = 0;i<y[l];i++) edge[2][i] = pw_get(pw, x[l], i); for(i = 0;i<x[l];i++) edge[3][i] = pw_get(pw, i, y[l]); (void) pw_vector(pw, x[l], y[l], x[l], 0, op, (void) pw_vector(pw, x[l], y[l], 0, y[l], op, } }  1); 1);  1); 1);  275  Appendix 4 Source code for interactive module Appendix 4 Source code for the interactive image measurement module There are 15 files in this program: ammon.h, amenu.h, amenu.c, display.c, query.c, utility.h, utility.c, morph.h, morph.c, icon.h, measure.c, dbms.c, misc.c, win.h, win.c: 1. ammon.h same as in Appendix 2. 2. amenu.h same as in Appendix 2. 3. amenu.c same as in Appendix 2. 4. display.c same as in Appendix 2. 5. query.c same as in Appendix 2. 6. utility.h same as in Appendix 2. 7. utility.c same as in Appendix 2. 8. morph.h /* data, function, and structure declarations for image measurement module */ #define PIXEL_CM #definePi  39.0783 /* the number of screen pixels per centimeter */ 3.141596  /* define the array index for descriptor_name */ #defineDMAX #define D #defme BISPACE #define WWWH #define WH #define WHD #define VOLUTION0 #define UD  37 38 50 46 42 43 67 39  /* the labels of icon items */ static char*  icon_list[]={"biconcave", "concave", "sinuous","falcate", "projected", "straight","bundled", "falcoid", "zigzag", "intercalatory", "bi", "tri", -multi", "poly","loop2", "loop3","loopn","angular", "round", "strong", "weak", "prorsiradiate", "gprorsiradiate", "rectiradiate","grursiradiate", "rursiradiate", "uni", "bi", "tri", "multi", "clavate", "bullate","high", "low", "shallow", "steepV'verticaT, "undercut", "yes", "rounded","ellipsoid",  276  Appendix 4 Source code for interactive module  277  "wellipsoid", "oval","lanceolate", "ogival", "rectangular", "wrectangular", "quadrate", "triangular","wtriangular", "trapezoid", "coronate","plain", "carinate","sulcate", "carinate-sulcate", "bicarinate","bicarinate-sulcate","yes"}; /* the conversion table of icon_list[] to descriptor_name[] */ int  icon_to_descriptor[]={59,59,59,59,59,59,59,59,59,59,61,61,61,61,61,61, 61, 60,60,60,60, 58,58,58,58,58, 62,62,62,62, 62,62,55,55, 56,56,56,56, 63, 54,54,54,54,54,54, 54,54,54,54,54,54,54,57,57,57,57,57,57,70};  /* the conversion table of text fields in the info panel to descriptor_name[] */ int  text_to_descriptor[]={43,68,42,64,49,50,51,65,52,66,67,47,53};  #define #define  NUM_OF_TEXT NUM_OF_ICON  sizeof text_to_descriptor / sizeof text_to_descriptor[0] sizeof iconlist/ sizeof icon_list[0];  /* text window size which is different from the one in retrieve, c, the new info panel size can be computed from command window size and text window size */ struct size  struct points int int int } int  { int int }  width; height; text_rect = {263, 475};  { x; y; z; /* different from definition for point */ curve_points[ 10000];  num_point; /* number of points in the array curve_points *  Panelitem PaneMtem Panelitem  inputlconjpanel, text_item[NUM_OF_TEXT], figurenum; parameterjnfo; /* warning information */ num_of_whorls; /* the number of whorls separating PI and P2 */  /* image measurement related functions */ extern float extern void extern void extern void extern void  distance(); bi_space(); d_max(); finess_ratio(); furc_pos();  Appendix 4 Source code for interactive module extern void extern void extern void extern float extern float extern void extern void extern void extern void static char static void  278  max_wh(); rib_density(); rib_width(); ratio(); ratio_of_three(); simulate_coiling(); sr_hw(); t_hw(); unitub_pos(); *density(); plotO; /* no longer used */  /* update Ammon with the following functions */ static void static void static void extern void extern void extern void extern void  record_info_icon(); record_info_text(); build_modify_statement(); saveO; modify_database(); reset_image(); reset_panel();  9. morph.c /* main program of the interactive image measurement module */ #include <ammon.h> main(argc, argv) int argc; char **argv; { int Scrollbar  vertical sb:  /* create a frame to host the left command window */ command_frame = window_create(NULL, FRAME, FRAME_LABEL, "Ammon Image Database - Measurement module", FRAME_SHOW_LABEL, TRUE, WINWIDTH, command_rect.width, WINHEIGHT, command_rect. height, WINX, 0, WINY, 0,  Appendix 4 Source code for interactive module  279  FRAMEJCON, icon_create(ICON_IMAGE, &ammon_icon, 0), 0);  /* create the command window to host the menu and command buttons */ command_win = window_create(command_frame, PANEL, PANEL_LABEL_BOLD, TRUE, PANEL_SHOW_MENU, TRUE, 0);  /* load font to label menu and command buttons */ font=pf_open(7apps/sundesk/fonts/sunview/lucida-19. v"); create_menu_button(); create_command_button(command_win); init_menu(); /* create a frame to host the info and canvas window at the right side of the command window */ display_window = window_create(NULL, FRAME, FRAME_LABEL, " Welcome Window", FRAME_SHOW_LABEL, TRUE, WIN_X, command_rect.width, WTN_Y, 0, WIN_SHOW,TRUE, WIN_WIDTH, screen_rect.width-command_rect.width, WIN_HEIGHT, screen_rect.height, 0);  /* create the info panel giving an introduction to the system */ init_info_panel(display_window); vertical_sb = scrollbar_create(SCROLL_LINE_HEIGHT, 5, (char *)0); /* 5 is the width of the scrollbar */ image_canvas=window_create(display_window, CANVAS, WIN_VERTICAL_SCROLLBAR, vertical_sb, CANVAS_RETAINED, FALSE, CANVAS_AUTO_SHRINK, FALSE, WIN_CONSUME_PICK_EVENT, MS_LEFT,  Appendix 4 Source code for interactive module  280  WIN_EVENT_PROC, canvasjiandler, WIN_X, 0, WIN_Y, info_rect.height+5, /* canvas under info panel */ WINWIDTH, screen_rect.width-command_rect. width, WIN_HEIGHT, screen_rect.height-info_rect.height-5, 0);  /* make the imagecanvas a color canvas with 253 colors */ pw=(Pixwin *) window^etOmage^anvas, WIN_PIXWIN); pw_putcolormap(pw, 0, 253, red, green, blue); /* reserve 3 color entries for bg and fg */  window_set(image_canvas, CANVAS_RETAINED, TRUE, 0); /* load the interface image into the canvas */ load_interface_image(); /* allocate memory for retrieval results of database query */ for (i=0; i<NUM_OF_DESCRIPTOR; i++) for(j=0;j<MAX_SP;j++) descriptor_value[i][j] = (char *)malloc(len[i]+2); for (i=0; i<MAX_IMAGE; i++) image_name[i]=(char *)malloc(len[IMAGE]+2); signal(SIGURG, stop_op); window_main_loop(command frame); exit(0); } /* load the interface image into the image_canvas */ static void load_interface_image() { Pixrect *image; FILE *fp;  Appendix 4 Source code for interactive module register int  w, h;  clear_canvas(); /* don't move the interface imagefileto other location */ if ((fp=fopen(interface_image, "r")) = NULL) { printfC'Can't open %s\n",interface_image); return; } image=pr_load(fp, colormap); w=image->pr_size. x; h=image->pr_size.y; red[252]=255; /* color entry 252 gives pure red */ green[252]=blue[252]=0; pw_setcmsname(pw, "image_cmp"); pw_putcolormap(pw, 0, 253, red, green, blue); cs=red[l]; /* as an indicator of the brightness */ /* display the image in the middle of the canvas */ if (h<screen_rect. height-info_rect. height) pw_rop(pw,(screen_rect.width-command_rect.width-w)/2, (screen_rect. height-info_rect. height-h)/2,w,h,PIX_SRC,image, 0,0); else pw_rop(pw,(screen_rect.width-command_rect.width-w)/2,0, w,h,PIX_SRC,image,0,0); pr_close(image); fclose(fp); }  10. icon.h static short ribl_image[] = { #include "/home/liang/icon/rib-biconcave" };  mpr_static(rib_biconcave, 64, 64, 1, ribl_image); static short rib2_image[] = { ^include "/home/liang/icon/rib-concave" };  mpr_static(rib_concave, 64, 64, 1, rib2_image); static short rib3_image[] = { ^include "/home/liang/icon/rib-sinuous"  281  Appendix 4 Source code for interactive module }; mpr_static(rib_sinuous, 64, 64, 1, rib3_image); static short rib4_image[] = { #include "/home/liang/icon/rib-falcate" }; mpr_static(rib_falcate, 64, 64, 1, rib4_image); static short rib8_image[] = { #include "/home/liang/icon/rib-falcoid" }; mpr_static(rib_falcoid, 64, 64, 1, rib8_image); static short rib5_image[] = { #include "/home/liang/icon/rib-proj ected" }; mpr_static(rib_proj ected, 64, 64, 1, rib5_image); static short rib6_image[] = { #include "/home/liang/icon/rib-straight" }; mpr_static(rib_straight, 64, 64, 1, rib6_image); static short rib7_image[] = { #include "/home/liang/icon/rib-bundled" }; mpr_static(rib_bundled, 64, 64, 1, rib7_image); static short rib9_image[] = { #include "/home/liang/icon/rib-zigzag" }; mpr_static(rib_zigzag, 64, 64, 1, rib9_image); static short riblO_image[] = { #include "/home/liang/icon/rib-intercalatory" }; mpr_static(rib_intercalatory, 64, 64, 1, riblOimage); static short furcl_image[] = { #include "/home/liang/icon/furc-bi" }; mpr_static(furc_bi, 64, 64, 1, furcl_image); static short furc2_image[] = { #include "/home/liang/icon/furc-tri" };  282  Appendix 4 Source code for interactive module mpr_static(furc_tri, 64, 64, 1, furc2_image); static short furc3_image[] = { ^include "/home/liang/icon/furc-multi" }; mpr_static(furc_multi, 64, 64, 1, furc3_image); static short furc4_image[] = { #include "/home/liang/icon/furc-poly" }; mpr_static(rurc_poly, 64, 64, 1, furc4_image); static short furc5_image[] = { #include "/home/liang/icon/furc-loop2" }; mpr_static(furcJoop2, 64, 64, 1, furc5_image); static short furc6_image[] = { ^include "/home/liang/icon/furc-loop3" }; mpr_static(furc_loop3, 64, 64, 1, fiirc6_image); static short furc7_image[] = { ^include "/home/liang/icon/furc-loopn" }; mpr_static(furc_loopn, 64, 64, 1, furc7_image); static short profl_image[] = { #include "/home/liang/icon/prof-angular" }; mpr_static(prof_angular, 64, 64, 1, profljmage); static short prof2_image[] = { #include "/home/liang/icon/prof-round" }; mpr_static(prof_round, 64, 64, 1, prof2_image); static short prof3_image[] = { ^include "/home/liang/icon/prof-strong" }; mpr_static(prof_strong, 64, 64, 1, prof3_image); static short prof4_image[] = { #include "/home/liang/icon/prof-weak" }; mpr_static(prof_weak, 64, 64, 1, prof4_image);  283  Appendix 4 Source code for interactive module  static short direction l_image[] = { #include "/home/liang/icon/prorsiradiate" }; mpr_static(prorsiradiate, 64, 64, 1, directionl_image); static short direction2_image[] = { #include "/home/Iiang/icon/gprorsiradiate" }; mpr_static(gprorsiradiate, 64, 64, 1, direction2_image); static short direction3_image[] = { #include "/home/liang/icon/rectiradiate" }; mpr_static(rectiradiate, 64, 64, 1, direction3_image); static short direction4_image[] = { #include "/home/liang/icon/grursiradiate" }; mpr_static(grursiradiate, 64, 64, 1, direction4_image); static short direction5_image[] = { #include "/home/liang/icon/rursiradiate" }; mpr_static(rursiradiate, 64, 64, 1, direction5_image); static short tubercl_image[] = { #include "/home/liang/icon/tuberc-uni" }; mpr_static(tuberc_uni, 64, 64, 1, tubercl_image);  static short tuberc2_image[] = { #include "/home/liang/icon/tuberc-bi" }; mpr_static(tuberc_bi, 64, 64, 1, tuberc2_image); static short tuberc3_image[] = { #include "/home/liang/icon/tuberc-tri" }; mpr_static(tuberc_tri, 64, 64, 1, tuberc3_image); static short tuberc4_image[] = { #include "/home/liang/icon/tuberc-multi" }; mpr_static(tuberc_multi, 64, 64, 1, tuberc4_image);  284  Appendix 4 Source code for interactive module  static short tuberc5_image[] = { #include "/home/liang/icon/tuberc-clavate" };  mpr_static(tuberc_clavate, 64, 64, 1, tuberc5_image); static short tuberc6_image[] = { #include "/home/liang/icon/tuberc-bullate" };  mpr_static(tuberc_bullate, 64, 64, 1, tuberc6_image); static short umbilical l_image[] = { #include "/home/liang/icon/shallow" };  mpr_static(shallow, 64, 64, 1, umbilical limage); static short umbilical2_image[] = { #include "/home/liang/icon/steep" };  mpr_static(steep, 64, 64, 1, umbilical2_image); static short umbilical3_image[] = { #include "/home/liang/icon/verticar' };  mpr_static(vertical, 64, 64, 1, umbilical3_image); static short umbilical4_image[] = { ^include "/home/liang/icon/undercut" };  mpr_static(undercut, 64, 64, 1, umbilical4_image); static short umbilical5_image[] = { #include "/home/liang/icon/uwallht-high" };  mpr_static(uwallht_high, 64, 64, 1, umbilical5_image); static short umbilical6_image[] = { #include "/home/liang/icon/uwallht-low" };  mpr_static(uwallht_low, 64, 64, 1, umbilical6_image); static short whorl l_image[] = { ^include "/home/liang/icon/whorl-rounded" };  mpr_static(whorl_rounded, 64, 64, 1, whorll_image);  285  Appendix 4 Source code for interactive module static short whorl2_image[] = { #include "/home/liang/icon/whorl-ellipsoid" };  mpr_static(whorl_ellipsoid, 64, 64, 1, whorl2_image); static short whorl3_image[] = { #include "/home/liang/icon/whorl-wellipsoid" };  mpr_static(whorl_wellipsoid, 64, 64, 1, whorBimage); static short whorl4_image[] = { #include "/home/liang/icon/whorl-oval" };  mpr_static(whorl_oval, 64, 64, 1, whorl4_image); static short whorl5_image[] = { #include "/home/liang/icon/whorl-lanceolate" };  mpr_static(whorl_lanceolate, 64, 64, 1, whorl5_image); static short whorl6_image[] = { #include "/home/liang/icon/whorl-ogival" };  mpr_static(whorl_ogival, 64, 64, 1, whorl6_image); static short whorl7_image[] = { #include "/home/liang/icon/whorl-rectangular" };  mpr_static(whorl_rectangular, 64, 64, 1, whorl7_image); static short whor!8_image[] = { #include "/home/liang/icon/whorl-wrectangular" };  mpr_static(whorl_wrectangular, 64, 64, 1, whorl8_image); static short whorl9_image[] = { #include "/home/liang/icon/whorl-quadrate" };  mpr_static(whorl_quadrate, 64, 64, 1, whorl9_image); static short whorl 1 Oimagef] = { #include "/home/liang/icon/whorl-triangular" };  mpr_static(whorl_triangular, 64, 64, 1, whorl lOJmage); static short whorl 1 l_image[] = {  286  Appendix 4 Source code for interactive module #include "/home/liang/icon/whorl-wtriangular" }; mpr_static(whorl_wtriangular, 64, 64, 1, whorl 1 limage); static short whorl 12_image[] = { #include 'Vhome/liang/icon/whorl-trapezoid" }; mpr_static(whorl_trapezoid, 64, 64, 1, whorl 12_image); static short whorl 13_image[] = { #include "/home/liang/icon/whorl-coronate" }; mpr_static(whorl_coronate, 64, 64, 1, whorl 13_image);  static short venter l_image[] = { #include "/home/liang/icon/venter-plain" }; mpr_static(venter_plain, 64, 64, 1, venterl_image); static short venter2_image[] = { #include "/home/liang/icon/venter-carinate" }; mpr_static(venter_carinate, 64, 64, 1, venter2_image); static short venter3_image[] = { ^include "/home/liang/icon/venter-sulcate" }; mpr_static(venter_sulcate, 64, 64, 1, venter3_image); static short venter4_image[] = { #include "/home/liang/icon/carinate-sulcate" }; mpr_static(carinate_sulcate, 64, 64, 1, venter4_image); static short venter5_image[] = { #include "/home/liang/icon/bicarinate" }; mpr_static(bicarinate, 64, 64, 1, venter5_image); static short venter6_image[] = { #include "/home/liang/icon/tricarinate" }; mpr_static(bicarinate_sulcate, 64, 64, 1, venter6_image); static short ontogeny_image[] = {  287  Appendix 4 Source code for interactive module  288  #include "/home/liang/icon/ontogeny" }; mpr_static(ontogeny, 64, 64, 1, ontogenyimage); static short approx_image[] = { #include "/home/liang/icon/approx" }; mpr_static(approx, 64, 64, 1, approx_image); 11. measure.c #include <math.h> #include "ammon.h" #include "morph.h" /* the following functions are used to measure images */ /* compute BISPACE in Amnion */ extern void bi_space() { char float  tmp[10]; tp;  tp=ratio(); /* use the points in the buffer */ if (tp) { sprintf(tmp,M%4.2f,,tp); sprintf(descriptor_value[BISPACE][0], "%s", tmp); } } /* measure the maximum diameter for the specimen */ extern void dmaxO { float  tp;  tp = distance(control_point[num_control_point-1 ],control_point[num_control_point2]); sprintf(descriptor_value[DMAX][0], "%5.2f', tp/(image_scale*PIXEL_CM)); } /* compute number of secondary ribs per half whorl */  Appendix 4 Source code for interactive module extern void sr_hw() { panel_set_value(text_item[5],density()); } /* compute number of tubercles per half whorl */ extern void t_hwO { panel_set_value(text_item[6],density0); } /* compute number of primary ribs per half whorl */ extern void rib_densityO { panel_set_value(text_item[4],density()); } /* use the number of control points in the buffer and their angular distance to calculate the density */ static char * density() { register int double char  i; sigma 1, sigma2, sigma; tmp[10];  /* angles in terms of coiling axis */ if (!control_point[0].x || !control_point[0].y) { panel_set_value(parameter_info, "Please mark coiling axis!"); num_control_point=0; } else { tmp[0]=0; sigma 1 =atan2((double)(control_point[ 1 ].y-control_point[0] .y), (double)(control_point[ 1 ].x-control_point[0].x)); sigma2=atan2((double)(control_point[num_control_point-1 ].ycontrol_point[0]. y), (double)(control_point[num_control _point- l].x-control_point[0].x)); sigma=fabs(sigma2-sigma 1); sigma=(sigma>Pi) ? 2*Pi-sigma:sigma;  289  Appendix 4 Source code for interactive module i=(num_control_point-2) *Pi/sigma; sprintf(tmp,"%d",i); num_control_point=l;/* reserve the coiling axis, reset other points */ return tmp; } /* measure the maximum whorl height */ extern void max_wh() { char tmp[10]; double tp, u, w; tp=distance(control_point[num_control_point-1 ], control_point[num_control_point-2]); sprintf(tmp,"%4.2f,,tp/(PIXEL_CM*image_scale)); panel_set_value(text_item[3],tmp); /* extrapolate the max diameter of the specimen  */  u=atof(panel_get_value(text_item[2])); /* read the volution from info panel */ w=atof(panel^get_value(text_item[0])); /* read expansion rate from info panel */ if(u&&w) { tp/=(1.0-u); tp*=(1.0+1.0/sqrt(w)); tp /= (image_scale*PIXEL_CM); sprintf(descriptor_value[DMAX][0],"%5.2f,,tp); } /* click 4 points to mark the rib width and length, compute rib width / rib length */ extern void rib_width() { char float  tmp[10]; tp;  tp=ratio(); if (tp) { sprintf(tmp,"%4.2f',tp); panel_set_value(text_item[7], tmp); /* show it in the relevant text field */ }  290  }  Appendix 4 Source code for interactive module  291  } /* mark rib start, furcation and end points, compute the relative rib furcation position */ extern void furc_pos() { char float  tmp[10]; tp;  tp=ratio_of_three(); if (tp) { sprintf(tmp, "%4.2f',tp); panel_set_value(text_item[9], tmp); /* show it in the relevant text field */ } } /* mark the umbilical seam, tubercle and venter, compute the relative uni-tuberculate position */  extern void unitub_pos() { char tmp [10]; float tp; tp=ratio_of_three(); if (tp) { sprintf(tmp,"%4.2f',tp); panel_set_value(text_item[ 10], tmp); } } extern void finess_ratio() { char tmp[10]; double w_out, r[2], distl, dist2, sigma; point p; w_out=atof(panel_jget_value(text_item[0])); /* compute the distance between C and D' (see fig. 3-1) */  Appendix 4 Source code for interactive module  292  distl=distance(control_point[num_control_point-1 ], control_point[num_control_point2]); r[l] = distl/(l+sqrt(l/w_out); /* radius with diameter distl */ /* if p is the middle point between A' and B' */ p.x = (control_point[num_control_point-3].x+ control_point[num_control_point-4].x)/2; p.y = (control_point[num_control_point-3].y+ control_point[num_control_point-4].y)/2; /* compute the distance between D' and p (see fig. 3-1) */ dist2=distance(control_point[num_control_point-1 ], p); /* align OP3 with axis y */ sigma=0.0; /* starting point with radius r[l] */ r[0]=r[l]; y[0] = r[l] -dist2; /* P3Y on page 26*/ while (sigma > -Pi) { sigma-= 1.0/r[0]; r[0]=r[ 1 ] *pow(w_out, sigma/(2*Pi)); y[ 1 ]=r[0] *cos(sigma); if (y[l]<y[0]) /* projection at point p */ break; } dist2 = r[0]*(l+l/sqrt(w_out)) /* shell diameter at point p */ distl = distance(control_point[num_control_point-3], control_point[num_control_point-4]); /* whorl width at point p */ /* compute fineness ratio */ sprintf(tmp,"%4.2f,,distl/dist2); panel_set_value(text_item[l 1], tmp); /* compute whorl width / whorl height */ u=ato%anel_get_value(text_item[2])); /* read the volution from info panel */ dist2 = (l-u)*r[0]; /* whorl height */ sprintf(descriptor_value[WWWH][0],"%4.2f,,distl/dist2); num_control_point= 1;  Appendix 4 Source code for interactive module } /* compute the ratio with 4 control points - P1P2/P3P4 */ extern float ratio() { float char  distl, dist2; tmp[40];  if (num_control_point<4) { panel_set_value(parameter_info,"Too few control points!"); num_control_point= 1; return 0; } else { distl=distance(control_point[num_control_point-3], control_point[num_control_point-4]); dist2=distance(control_point[num_control_point-1 ], control_point[num_control_point-2]); sprintf(tmp,"Ratio=%5.4f.",distl/dist2); panel_set_value(parameter_info,tmp); num_control_point= 1; return distl/dist2;. } } /* compute the ratio with 3 control points P1P2/P1P3 */ extern float ratio_of_three() { float distl, dist2; char tmp[40]; if (num_control_point<3) { panel_set_yalue(parameter_info,"Too few control points!"); num_control_point= 1; return 0; } else { dist 1 = distance(control_point[num_control_point-2], control_point[num_control_point-3]); dist2=distance(control_point[num_control_point-1 ], control_point[num_control_point-3]); sprintf(tmp,"Ratio=%5.4f.")distl/dist2); panel_set_value(parameter_info,tmp);  293  Appendix 4 Source code for interactive module num_control_point= 1; return distl/dist2; } } /* compute the distance between pi and p2 */ extern float distance(pl, p2) point p i , p2; { float dist; char tmp[40]; dist=sqrt((double)sqr(p 1 .x-p2.x)+(double)sqr(p 1 .y-p2.y)); sprintf(tmp, "Distance=%5.4f ",dist); panel_set_value(parameter_info,tmp); num_control_point=l; /* reserve coiling axis, reset other points */ return dist; } /* compute basic shell geometry */ extern void simulate_coiling() { register int double float char  i, num_whorls, x[3], y[3], clock_wise; r[5], sigma, sigmal, sigma2, tp, tpO; w_in, w_out, u; tmp[150];  /* need 5 control points to simulate inner and outer coiling curve */ if (num_control_point<5) { panel_set_value(parameter_info,"Not enough control points !"); num_control_point=0;} else if (num_control_point>5) { panel_set_value(parameter_info,"Too many control points !"); num_control_point=0;} else { sprintf(tmp,"%s", panel_get_value(num_of_whorls)); num_whorls=atoi(tmp); /* PI and P2 are separated by numwhorls */ tmp[0]=0; if (Inumwhorls) { panel_set_value(parameter_info, "Please give number of whorls !");  294  Appendix 4 Source code for interactive module goto end;  295  }  /* coiling axis */ x[0]=control_point[0].x; y [0]=control_point [0]. y; /* calculate distance between each control point and coiling axis */ for (i=l; i<num_control_point; i++) r[i]=distance(control_point[i], control_point[0]); /* compute whorl height */ tp=(r[3]-r[2])/(PIXEL_CM*image_scale); sprintf(descriptor_value[WH][0],"%5.2f,,tp); /* compute the angle between OP4 and OP3 */ sigmal=atan2((double)(control_point[3].y-y[0]), (double)(control_point [3 ]. x-x[0])); sigma2=atan2((double)(control_point[4].y-y[0]), (double)(control_point [4]. x-x[0])); /* determine coiling direction */ if (sigma2-sigmal>0 && sigma2-sigmal<Pi || sigma2-sigmal<-Pi) clock_wise=l; else clock_wise=-l; sigma=fabs(sigma2-sigma 1); if (sigma>Pi) /* angle between OP3 and OP4 must be less than Pi */ sigma = 2*Pi-sigma; /* compute expansion rate and volution */ u=r[2]/r[3]; /* U in Ammon */ /* expansion rate from inner coiling curve */ w_in=pow(r[2]/r[ 1 ], 1.0/(double)num_whorls); w_out=pow(r[3]/r[4],2*Pi/sigma); /* expansion rate from outer coiling curve */ /* display expansion rate and volution in the relevant text field */ sprintf(tmp,"%4.2f',w_out); panel_set_yalue(text_item[0],tmp);  Appendix 4 Source code for interactive module sprintf(tmp, "%4.2f > _ i n ) ; panel_set_value(text_item[ 1 ],tmp); sprintf(tmp,"%4.2f,,u); panel_set_value(text_item[2],tmp); /* compute shell diameter  */  tpO=r[3]*(l+1.0/sqrt(w_out))/(PIXEL_CM*image_scale); sprintftdescriptor_value[D][0],"%5.2f',tpO); /* compute whorl height/diameter */ tpO=tp/tpO; sprintftdescripto^valuefWHDJtOJ/ToS^f^tpO); /* compute quantitative volution */ tpO=(r[3]/w_out-r[2])/(PIXEL_CM*image_scale); if(tpCKO.O) tp=0.0; else tp=tpO/tp; sprintfCdescriptor_value[VOLUTION0][0],"%5.2f',tp); /* compute umbilical diameter */ tp0=r[2] * (1+1.0/sqrt(w_in))/(PIXEL_CM*image_scale); sprintf(descriptor_value[UD][0],"o/o5.2f*,tp0); panel_set_value(num_of_whorls,""); } end: } /* superimpose the simulated coiling cure on top of the image */ static void plot_coiling(x, clock_wise, w i n , w o u t , r, sigmal) int x[], clockwise; float w_in, w o u t ; double r[], sigmal; { register int x[3], y[3]; double tp;  Appendix 4 Source code for interactive module num_point=0; /* number of points on the coiling curve */ x[2]=y[2]=0; /* plot the outer coiling curve */ sigma=1.0/r[3]; /* starting point */ while (sigma<2*Pi) { tp=sigma 1 +clock_wise* sigma; r[0]=r[3]*pow(w_put,-sigma/(2*Pi)); x[l]=x[0]+r[0]*cos(tp); y[l]=y[0]+r[0]*sin(tp); if(x[l]!=x[2]||y[l]!=y[2]){ x[2]=curve_points[num_point].x=x[ 1 ]; y[2]=curve_points[num_point].y=y[l]; /* curve_points can be used to restore the original image */ curve_points[num_point].z=pw_jget(pw,x[ 1 ],y[ 1 ]); pw_put(pw,x[l],y[l],252); /* color entry 252 - red */ num_point++; } sigma += 1.0/r[0];  /* angular increment step */ }  /* plot the inner coiling curve */ sigmal=atan2((double)(control_point[2].y-y[0]),(double)(controlj5oint[2].x-x[0])); x[2]=y[2]=0; sigma=1.0/r[2]; r[0]=r[2]; r[l]=(r[l]<6)?r[l]:6; while (r[0]>r[ 1 ] && num_point< 10000) { tp=sigma 1 +clock_wise*sigma; r[0]=r[2]*pow(w_in,-sigma/(2*Pi)); x[l]=x[0]+r[0]*cos(tp); y[l]=y[0]+r[0]*sin(tp);' if(x[l]!=x[2]||y[l]!=y[2]){ x[2]=curve_points[num_point] .x=x[ 1 ]; y [2]=curve_points[num_point] .y=y[ 1 ]; curve_points[num_point] .z=pwjget(pw,x[ l],y[ 1 ]); pw_put(pw,x[l],y[l],252); num_point++; } sigma += 1.0/r[0]; } }  /* plot brightness profile between two points */  297  Appendix 4 Source code for interactive module static void plotO { register int struct size struct point  i, k, dist, x, y; profile_rect; profile_start;  if (betweenf 1 ] .x 11 between[ 1 ] .y) { dist= distance(between[0], between[l]); profile_rect. width = dist; profile_rect.height = 256; profile_start.x = screen_rect.width-command_rect.width-profile_rect. width; profile_start.y = screen_rect.height-info_rect.height-profile_rect.height; (void)pw_writebackground(pw, profile_start.x, profilestart.y, profile_rect.width, profile_rect.height, PIX_CLR); for (i=0; i<profile_rect.width; i++) { x=between[0] .x+(between[ 1 ] .x-between[0] .x)*i/dist; y=between[0] .y+(between[ 1 ] ,y-between[0] .y)*i/dist; k^pw^etCpw, x, y); pw_put(pw, profile_start.x+i, screen_rect.heightinfo_rect.height-k, 251); } } else if (between[0].x || between[0].y) panel_set(wait_num, PANELVALUE, "Need one more point to plot!", 0);  else panel_set(wait_num, PANEL_VALUE, "Need two points to plot!", 0);  } 12. dbms.pc /* all database related operations are in this file which need to be compiled by Oracle precompiler before proceeding with cc and combine with other source code */ #include <stdio.h> #include <ammon.h> EXEC SQL BEGIN DECLARE SECTION; extern char *query_statement; extern char * search_condition[ 12]; char oracleid = V;  298  Appendix 4 Source code for interactive module VARCHAR modiry_statement[500]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE SQLDA; /* Declare the bind and select descriptors. */ SQLDA *bind_dp; SQLDA *select_dp; extern SQLDA  *sqlald();  extern void  sqlprcO;  extern void int  sqlnulO; nullok;  extern void execute_query() { same as the one in Appendix 2 }  extern void modify_database() { register int  i, j , k;  /* Automatic log on to ORACLE */ EXEC SQL CONNECT :oracleid; /* Set up ORACLE error handling. */ EXEC SQL WHENEVER SQLERROR GOTO sqlerror; bind_dp = sqlald (40, 20, 0); bind_dp->N = 40;  /* Prepare the statement. */ EXEC SQL PREPARE S FROM :modify_statement; EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp;  299  Appendix 4 Source code for interactive module  300  /* If F is negative, there were more bind variables than originally allocated by sqlaldQ.  if(bind_dp->F<0) { printf("\nToo many bind variables for descriptor."); goto sqlerror; } /* Set the maximum number of array elements in the descriptor to the number found. bind_dp->N = bind_dp->F; j=0; /* copy only morph paramters which have been changed */ for (i=DMAX; i<NUM_OF_DESCRIPTOR; i++) if(*descriptor_value[i][0]) { bind_dp->L[j] = strlen(descriptor_value[i][0]); bind_dp->V[j] = malloc(bind_dp->L[j]+l); strcpy (bind_dp->V[j], descriptor_value[i][0]); bind_dp->I[j] = 0; bind_dp->T[j++] = 1; } /* figure out the name of the selected image */ k=rel[image_index(control_point [0]. x, control_point [0]. y)]; i=0; while (image_name[k][i++] != ") ; bind_dp->L[j] = i-1; /* image name as condition. */ bind_dp->V[j] = malloc(bind_dp->LO]+l); strcpy (bind_dp->V[j], image_name[k]); bind_dp->I[j] = 0; bind_dp->T[j] = l; EXEC SQL EXECUTE S USING DESCRIPTOR bind_dp; printf("\nNumber of rows processed: %d\n",sqlca.sqlerrd[2]); /* Free space used by descriptors. */ for (i=0; i<bind_dp->F; i++) free (bind_dp->V[i]j; /* Free space used by the descriptors themselves. */  Appendix 4 Source code for interactive module sqlclu (binddp); EXEC SQL COMMIT WORK; /* disconnect from Oracle database engine */ EXEC SQL COMMIT RELEASE; return; /* ORACLE error handler */ sqlerror: printf("\n\n%. 70s\n", sqlca. sqlerrm. sqlerrmc); EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK; EXEC SQL COMMIT RELEASE; }  13. misc.c /* miscellaneous functions used for updating database */ #include <ammon.h> #include <morph.h> /* save new data into the database */ extern void save() { /* find the morphological information from icon palette. */ record_info_icon(); /* find the morphological information from text items associated with button */ recordinfotextO; /* build database update statement based on descriptors available. */ build_modify_statement();  301  Appendix 4 Source code for interactive module  302  modify_database(); /* Reset */ reset_panel(); } /* scan the icon panel, copy new data */ static void record_info_icon() { register int i; for (i=0; i<NUM_OF_ICON; i++) if (panel^etOnputlconjanel, PANEL_TOGGLE_VALUE, i)) { if (! *descriptor_value[icon_to_descriptor[i]][0]) /* new data */ spiintf(descriptor_value[icon_to_descriptor[i]][0], icon_list[i]); else { strcat(descriptor_value[icon_to_descriptor[i]][0],","); strcat(descriptor_value[icon_to_descriptor[i]][0],icon_list[i]); } } } /* scan the text fields in the info panel, copy data into an array */ static void record_info_text() { register int i; char* tmp; for (i=0; i<NUM_OF_TEXT; i++) if (*(tmp=panel_get_value(text_item[i]))) /* data available */ sprintf(descriptor_value[text_to_descriptor[i]][0], tmp); } /* construct the update query statement for new data */ static void build_modify_statement() { register int i, j=0; char tmp[3];  Appendix 4 Source code for interactive module  sprintf(modify_statement.arr,"%s", "update ammonjmage set"); for (i=DMAX; i<NUM_OF_DESCRIPTOR; i++) /* DMAX - start of morph parameters */ if(*descriptor_value[i][0]) {  ifG) strcat(modify_statement. arr,","); strcat(modify_statement.arr,descriptor_name[i]); strcat(modify_statement.arr," =: v"); /* v - binding variable */ sprintf(tmp,,,%d,,,i); strcat(modify_statement. arr,tmp); } strcat(modify_statement.arr," where image = :v"); modify_statement. len=strlen(modify_statement. arr); } /* erase simulated coiling curve with pre-silmulate points */ extern void reset_image() { register int  i;  /* put the original data points back */ for (i=0;i<num_point; i++) pw_put(pw,curvej3oints[i].x,curve_points[i].y,curve_points[i].z); num_point=num_control_point=0; /* reset counters */ } /* reset the icon panel and text fields in the info panel after saving the new data make them ready for new data input */ extern void reset_panel() { register int  i, j ;  for (i=DMAX; i<NUM_OF_DESCRIPTOR; i++) *descriptor_value[i] [0]=0; for (i=0; i<NUM_OF_TEXT; i++) if(*panel_get_value(text_item[i]))  303  Appendix 4 Source code for interactive module  304  panel_set_value(text_item[i],""); for (i=0; i<NUM_OF_ICON; i++) if (panel_get(inputIcon_panel, PANEL_TOGGLE_VALUE, i)) panel_set(inputIcon_panel, PANEL_TOGGLE_VALUE, i, FALSE, 0); num_control_point=0; } /* jump to display the specified image of figure_num */ extern void goto_figure() { display_from=0; display_to=atoi(panel_^et_value(show_num))-atoi(panel^get_value(figure_num)); next_page(); } 14. win.h /* button locations */ #define COMMAND_START_ROW12 #define COMMAND_INCREMENT 2 /* introductory text locations */ #define X S T A R T #define Y_START #define Y_INCREMENT  140 70 25  /* info panel item locations */ static point pos[] = ((38, 1}, (55, 1}, (0,2}, (11,2}, (16,2}, (26,2}, (31,2}, (35, 2}, (40, 2}, (48, 2}, (54, 2}, (61, 2}, (66, 2}, (73, 2}, (78, 2}, (84, 2}, (0, 3}, (12, 3}, (17, 3}, (27, 3}, (32, 3}, (42, 3}, (47, 3}, (59, 3}, (64, 3}, (70, 3}, (75, 3}, (81, 3}}; static point label_pos[] = ((2, 100}, (2, 170}, (67, 240}, (461, 240}, (202, 304}, (10,370}, (202,432}}; static void static void  adjust_info_panel(Panellocal_panel); create_icon_panel(Panel local_panel);  Appendix 4 Source code for interactive module 15. win.c /* windows, buttons related functions */ ^include "ammon.h" #include "icon.h" ^include "win.h" extern void create_command_button(frame_local) Frame frame_local; { panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, query_from_text, PANEL_LABEL_IMAGE, panel_button_image(frame_local, "Combination", 13,font), 0);  panel_create_item(frame_local,PANEL_MESSAGE, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ COMMAND_INCREMENT), PANEL_LABEL_FONT, font, PANEL_LABEL_STRrNG,"Sorne Utility:", 0); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 2*COMMAND_rNCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, next_page, PANEL_LABEL_IMAGE, panel_button_image (frame_local,"Next Page", 13,font), 0); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y,ATTR_ROW(COMMAND_START_ROW+ 3 *COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, previous_page, PANEL_LABEL_IMAGE, panel_button_image (framelocal, "Previous Page", 13,font), 0);  panel_create_item(frame_local,PANEL_TEXT,  305  Appendix 4 Source code for interactive module PANELITEMY, ATTR_ROW(COMMAND_START_ROW+ 4*COMMAND_INCREMENT), PANEL_LABEL_STRING, "Brightness:", 0); bright=panel_create_item(frame_locaI,PANEL_SLIDER, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 4*COMMAND_INCREMENT+l), PANEL_SHOW_VALUE, FALSE, PANEL_VALUE, 0, PANEL_MIN_VALUE, -50, PANEL_MAX_VALUE, 50, PANEL_SLIDER_WIDTH, 94, PANEL_NOTIFY_PROC, adjust_brightness, 0);  panel_create_item(frame_locaI,PANEL_TEXT, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 5 *COMMAND_INCREMENT+1), PANEL_LABEL_STRING, "Contrast:", 0);  contrast=panel_create_item(frame_local,PANEL_SLIDER, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 6*COMMAND_INCREMENT), PANEL_SHOW_VALUE, FALSE, PANELVALUE, 10, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 20, PANEL_SLIDER_WIDTH, 94, PANELNOTIFYPROC, adjust_contrast, 0);  panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 6*COMMAND_INCREMENT+1), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, goto_figure, PANEL_LABEL_IMAGE, panel_button_image (frame_local,"Goto Figure:", 13, font), 0);  figurenum = panel_create_item(frame_local, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTFL 4, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 7*COMMAND_INCREMENT+1),  306  Appendix 4 Source code for interactive module  307  PANEL_ITEM_X, ATTR COL(0), PANEL_LABEL_STRING, "Number:", 0); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 8*COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(0), PANEL_NOTIFY_PROC, distance (control_point[num_control_point-l],control_point[num_control_point-2]), PANELLABELIMAGE, panel_button_image (framejocal, "Distance", 13,font), 0); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 9*COMMAND_INCREMENT), PANEL_ITEM_X, ATTR COL(0), PANELNOTEFYPROC, ratio, PANEL_LABEL_IMAGE, panel_button_image (framejocal,"Ratio", 13,font), 0); panel_createJtem(framelocal,PANEL_BUTTON, PANEL ITEM_Y,ATTR_ROW(COMMAND_START_ROW+ 10*COMMAND_INCREMENT), PANELJTEM_X, ATTRCOL(O), PANEL_NOTEFY_PROC, reset_panel, PANEL_LABEL_IMAGE, panel_button image (framejocal, "Reset Panel", 13,font), 0); panel_createjtem(frameJocal,PANEL_BUTTON, PANEL ITEM_Y,ATTR_ROW(COMMAND_START_ROW+ 11 *COMMANDJNCREMENT), PANELJTEM_X, ATTRCOL(O), PANEL_NOTIFY_PROC, resetJmage, PANEL_LABEL_IMAGE, panel_button image (framejocal,"Reset image", 13,font),  o); panel_createitem(framelocal,PANEL_BUTTON, PANEL ITEMY, ATTR_ROW(COMMAND STARTROW+ 12*COMMAND_rNCREMENT), PANELJTEM_X, ATTRCOL(O), PANEL_NOTIFY_PROC, reverse,  Appendix 4 Source code for interactive module PANELLABELIMAGE, panelJ>utton image (frame_local,"Reverse Image", 13,font), 0);  panelcreate item(frameJocal,PANELJBUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 13 *COMMAND_INCREMENT), PANEL_ITEM_X, ATTRCOL(O), PANELNOTIFYPROC, save, PANELLABEL IMAGE, paneljiutton image (framejocal, "Save", 13,font), 0); panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 14*COMMAND_INCREMENT), P A N E L I T E M X , ATTRCOL(O), PANELNOTIFYPROC, help, PANEL_LABEL_IMAGE,panel_button_image (framejocal, "Help",4,font), 0);  button_Quit = panel_create_item(frame_local,PANEL_BUTTON, PANEL_ITEM_Y, ATTR_ROW(COMMAND_START_ROW+ 14*COMMAND_INCREMENT), PANEL_ITEM_X, ATTR_COL(12), PANEL_NOTIFY_PROC, quit, PANEL_LABEL_IMAGE,panel_button_image(frameJocal,"Quit",4,font), 0); }  extern void init_info_panel(frame_local) Frame framejocal; { Panel  info_panel;  /* font for displaying title */ font=pf_open("/apps/sundesk/fonts/sunpaint/R.24"); /* create info window to display the introduction text */ info_panel=window_create(frameJocal, PANEL,  308  Appendix 4 Source code for interactive module  309  PANEL_LABEL_BOLD, FALSE, WIN_X, 0, WIN_Y, 0, WINWIDTH, screen_rect.width-command_rect. width, WTN_HEIGHT, info_rect. height, 0); panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANELJTEMX, X_START-30, PANEL_ITEM_Y, YSTART-30, PANEL_LABEL_STRING, " Interactive Ammonite Image Measurement Module",  o); /* font for displaying introductory text */ font=pf_open("/apps/sundesk/fonts/sunview/lucida-19. v"); panel_create_item(infoj3anel,PANEL_MESSAGE, PANELLABELFONT, font, PANEL_ITEM_X, X_START+40, PANEL_ITEM_Y, Y_START, PANELLABELSTRJNG, "First, retrieve the ammonites that you want to measure by:", 0);  panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, X_START, PANEL_ITEM_Y, Y_START+Y_INCREMENT, PANEL_LABEL_STRTNG, "1. Taxonomy: Family, Genus, and Species.", 0); panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, XSTART, PANEL_ITEM_Y, Y_START+2*Y_INCREMENT, PANEL_LABEL_STRING, "2. Stratigraphy: Stage and Standard Zone.", 0); panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, X_START, P A N E L I T E M Y , YSTART+3 * YJNCREMENT, PANELLABELSTRING, "3. Geography: Geographic Area and Country",  Appendix 4 Source code for interactive module 0); panel_create_item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANELJTEMX, XSTART, PANEL_ITEM_Y, Y_START+4*Y_INCREMENT, PANELLABELSTRING, "4. Morphology: Volution, Expansion Rate, Whorl Shape, and Rib Form", 0); panelcreate item(info_panel,PANEL_MESSAGE, PANEL_LABEL_FONT, font, PANEL_ITEM_X, X_START, PANEL_ITEM_Y, Y_START+5*Y_INCREMENT, PANEL_LABEL_STRING, "5. Reference: in which the figure of the specimen appears.", 0); panel_create_item(info_panel,PANEL_MESSAGE, PANELJ.ABELJONT, font, PANELJTEMX, X_START+40, PANEL_ITEM_Y, Y_START+6*Y INCREMENT, PANEL_LABEL_STPJNG, "Second, select the image and do the measurement. ",  o); } extern void adjust info_panel(local_panel) Panel local_panel { int i; char tmp[40], *buf; Panel item item; /* destroy all old panel items in the info panel */ panel_each item(local_panel, item) panel_destroy item(item); panel_end_each inforect. height = textrect. height; /* increase height to accomondate icon panel */ inforect. width = screen_rect.width-command_rect.width-text_rect. width; window_set(local_panel, WIN_HEIGHT, info_rect.height,  310  Appendix 4 Source code for interactive module WINJWIDTH, info_rect.width, 0);  /* display the query statement of the menu selection */ if (num_of_Items)  {  /* translate from SQL query to plain text, eliminate':' */ /* skip 'select * from OPSSliang.ammonimage where' in query statement */ buf=&query_statement[42]; query_to_plain(buf); i=strlen(buf); buf[i-2]=0; tmp[0]=0; sprintf(tmp,"%s%s",buf,search_condition[0]); } else tmp[0]=0; /* condition_text is the text field for query text display or input, you can type in a query and press the Combination button to search the database */ conditiontext = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 180, PANEL_VALUE_DISPLAY_LENGTH, 200, PANEL_LABEL_X, ATTRCOL(O), PANEL_LABEL_Y, ATTR_ROW(0), PANEL_LABEL_STRING, "Search :", PANEL_VALUE, tmp, 0); /* display number of images retrieved */ if (num_of_Items) sprintf(tmp,"%4d",num_of_Items); shownum = panel_create_item(local_panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 5, PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTRROW(l), PANEL_LABEL_STRING, "Images Returned:", PANEL_VALUE, tmp, 0);  311  Appendix 4 Source code for interactive module /* number of images wait to be displayed */ wait_num = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 5, PANEL_LABEL_X, ATTR_COL(22), PANEL_LABEL_Y, ATTR_ROW(l), PANEL_LABEL_STRTNG, "Remained:", 0); /* when simulate the inner coiling curve, the user need to specify the number of whorls which seperate the two control points (PI & P2) */ num_of_whorls = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 2, PANEL_LABEL_X, ATTR_COL(pos[0].x), PANEL_LABEL_Y, ATTR_ROW(pos[0].y), PANEL_LABEL_STRING, "Whorls", 0);  /* text field for displaying some parameter info */ parameterjnfo = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 25, PANELLABELX, ATTR_COL(pos[l].x), PANEL_LABEL_Y, ATTR_ROW(pos[l].y),  o); /* create buttons and text fields for image measurement and result display */ panel_create_item(local_panel, PANEL_BUTTON, PANELLABELX, ATTR_COL(pos[2].x), PANELLABELY, ATTR_ROW(pos[2].y), PANELLABELIMAGE, panelbuttonimage (local_panel,"W (out) =",0, NULL), PANEL_NOTIFY_PROC, simulate_coiling, 0); text_item[0] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[3].x), PANELLABELY, ATTR_ROW(pos[3].y), 0);  312  Appendix 4 Source code for interactive module  313  panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[4].x), PANEL_LABEL_Y, ATTR_ROW(pos[4].y), PANELLABELJMAGE, panel_button_image (local_panel,"W (in) =",0, NULL), PANEL_NOTIFY_PROC, simulate_coiling, 0); text_item[ 1 ]=panel_create_item(local_panel, P ANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[5].x), PANEL_LABEL_Y, ATTR_ROW(pos[5].y), 0); panel_create_item(localj)anel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[6].x), PANEL_LABEL_Y, ATTR_ROW(pos[6].y), PANEL_LABEL_IMAGE, panel_button_image(local_panel,"U-',(), NULL), PANEL_NOTIFY_PROC, simulate_coiling,  o); text_item[2] = panel_create_item(local_panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[7].x), PANEL_LABEL_Y, ATTR_ROW(pos[7].y), 0);  panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[8].x), PANEL_LABEL_Y, ATTR_ROW(pos[8].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"MaxWH=",0, NULL), PANEL_NOTIFY_PROC, maxwh, 0); text_item[3] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 5, PANEL_LABEL_X, ATTR_COL(pos[9].x), PANEL_LABEL_Y, ATTR_ROW(pos[9].y), 0);  panel_create_item(local_panel, PANEL_BUTTON, PANELLABELX, ATTR_COL(pos[10].x), PANEL_LABEL_Y, ATTR_ROW(pos[10].y), PANEL_LABEL_IMAGE; panelbuttonimage (local_panel,"PRHW=",0, NULL),  Appendix 4 Source code for interactive module PANEL NOTIFYPROC, rib_density, 0);  text_item[4] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[ll].x), PANEL_LABEL_Y, ATTR_ROW(pos[ll].y),  o); panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[12].x), PANEL_LABEL_Y, ATTR_ROW(pos[12].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"SRHW=",0, NULL), PANELNOTIFYPROC, srhw, 0);  text_item[5] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[13].x), PANEL_LABEL_Y, ATTR_ROW(pos[13].y), 0);  panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[14].x), PANELLABELY, ATTR_ROW(pos[14].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"THW=",0, NULL), PANELNOTIFYPROC, t_hw,  o); text_item[6] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[ 15] x), PANEL_LABEL_Y, ATTR_ROW(pos[15].y),  o); panel_create_item(local_panel, PANELBUTTON, PANELLABELX, ATTR_COL(pos[16].x), PANEL_LABEL_Y, ATTR_ROW(pos[16].y), PANELLABELIMAGE, panel_button_image (local_panel,"Rib Width=",0, NULL), PANEL_NOTIFY_PROC, ribwidth,  o); text_item[7] = panel_create_item(local_panel, PANELTEXT,  314  Appendix 4 Source code for interactive module PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[17].x), PANEL_LABEL_Y, ATTR_ROW(pos[17].y), 0);  panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[18].x), PANEL_LABEL_Y, ATTR_ROW(pos[18].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"WWAVH",0, NULL), PANEL_NOTIFY_PROC, bi_space, 0);  text_item[8] = panel_create_item(local_panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[19].x), PANEL_LABEL_Y, ATTR_ROW(pos[19].y),  o); panel_create_item(local_panel, PANELBUTTON, PANEL_LABEL_X, ATTR_COL(pos[20].x), PANEL_LABEL_Y, ATTR_ROW(pos[20].y), PANEL_LABEL_IMAGE, panelbuttonimage (local__panel,"Furcpos=",0, NULL), PANEL_NOTIFY_PROC, furc_pos, 0); text_item[9] = panel_create_item(local_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[21].x), PANEL_LABEL_Y, ATTR_ROW(pos[21].y),  o); panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[22].x), PANEL_LABEL_Y, ATTR_ROW(pos[22].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"Unitubpos=",0, NULL), PANEL_NOTIFY_PROC, unitub_pos, 0);  text_item[10] = panel_create_item(locaI_panel, PANELTEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[23].x), PANEL_LABEL_Y, ATTR_ROW(pos[23].y), 0);  315  Appendix 4 Source code for interactive module  316  panel_create_item(local_panel, PANELBUTTON, PANEL_LABEL_X, ATTR_COL(pos[24].x), PANEL_LABEL_Y, ATTR_ROW(pos[24].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"WWD=",0, NULL), PANEL_NOTIFY_PROC, finess_ratio, 0);  textitemfll] = panel_create_item(local_panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[25].x), PANEL_LABEL_Y, ATTR_ROW(pos[25].y), 0); panel_create_item(local_panel, PANEL_BUTTON, PANEL_LABEL_X, ATTR_COL(pos[26].x), PANEL_LABEL_Y, ATTR_ROW(pos[26].y), PANEL_LABEL_IMAGE, panel_button_image (local_panel,"CHW=",0, NULL), PANEL_NOTIFY_PROC, c_hw, 0);  text_item[12] = panel_create_item(local_panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 4, PANEL_LABEL_X, ATTR_COL(pos[27].x), PANELLABELY, ATTR_ROW(pos[27].y), 0);  create_icon_panel(); panel_paint(local_panel, PANELCLEAR); }  static void create_icon_panel(local_panel) Panel local_panel { /* create an icon panel to facilitate the input of morph data */ inputIcon_panel = panel_create_item(local_panel, PANELTOGGLE, PANELCHOICEIMAGES, «&rib_biconcave, «&rib_concave, &rib_sinuous, &rib_falcate, «&rib_projected, «&rib_straight, &rib_bundled,  Appendix 4 Source code for interactive module  317  &rib_faIcoid, &rib_zigzag, &rib_intercalatory, &furc_bi, &furc_tri, &furc_multi, &furc_poly,&furc_loop2, &furc_loop3, &furc_loopn,&profangular, &prof_round, &prof_strong, &prof_weak,&prorsiradiate, &gprorsiradiate, &rectiradiate, &grursiradiate, &rursiradiate, &tuberc_uni, &tuberc_bi, &tuberc_tri, &tuberc_multi, &tuberc_clavate, &tuberc_bullate, &uwallht_high, &uwallht_low, &shallow, &steep, &vertical, &undercut, &ontogeny, &whorl_rounded, &whorl_ellipsoid, &whorl_wellipsoid, &whorl_oval, &whorl_lanceolate, &whorl_ogival, &whorl_rectangular, &whorl_wrectangular, &whorl_quadrate, &whorl_triangular, &whorl_wtriangular, &whorl_trapezoid, &whorl_coronate, &venter_plain, &venter_carinate, &venter_sulcate, &carinate_sulcate, &bicarinate, &bicarinate_sulcate, &approx, 0, PANEL_CHOICE_XS, 76,140,204,268,332,396,460,524,588,652,76,140,204, 268,332,396,460,524,588,652,1,140,204,268,332,396,524,588,652,1, 65, 129, 268,332,396,460,524,588,652,76,140,204,268,332,396,460, 524, 588,652,1, 65,129,268,332,396,460,524,588,652,0, PANEL_CHOICE_YS, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 152,152,152, 152,152,152,152,152,152,152,216,216, 216, 216, 216, 216,216, 216, 216, 280, 280, 280, 280, 280, 280,280, 280, 280,280, 344, 3445 344, 344, 344, 344, 344, 344, 344, 344, 408, 408, 408, 408, 408, 408, 408, 408, 408, 408, 0, 0);  /* label the icon panel */ panel_create_item(local_panel, PANEL_MESSAGE, PANEL_LABEL_X, label_pos[0].x, PANEL_LABEL_Y, label_pos[0].y, PANEL_LABEL_STRING, "RIB FORM", 0);  panel_create_item(local_panel, PANEL_MESSAGE, PANEL_LABEL_X, label_pos[l].x, PANEL_LABEL_Y, label_pos[l].y, PANEL_LABEL_STRING, "RIB FURC", 0);  panel_create_item(local_panel, PANEL_MESSAGE, PANEL_LABEL_X, label_pos[2].x, PANEL_LABEL_Y, label_pos[2].y, PANELLABELSTRING, "RIB TREND", 0);  panel_create_item(local_panel, PANELMESSAGE,  Appendix 4 Source code for interactive module PANEL_LABEL_X, label_pos[3].x, PANELLABEL_Y, label_pos[3].y, PANELLABELSTRTNG, "TUBERCLE",  o); panel_create_item(local_panel, PANEL_MESSAGE, PANEL_LABEL_X, label_pos[4].x, PANEL_LABEL_Y, label_pos[4].y, PANELLABELSTRTNG, "UWALL", 0); panel_create_item(local_panel, PANEL_MESSAGE, PANEL_LABEL_X, label_pos[5].x, PANEL_LABEL_Y, label_pos[5].y, PANEL_LABEL_STPJNG, "WHORL",  o); panel_create_item(local_panel, PANEL_MES SAGE, PANELLABELX, label_pos[6].x, PANEL_LABEL_Y, label_pos[6].y, PANELLABELSTRTNG, "VENTER", 0); } extern void adjust_display_window(local_panel) Panel local_panel; { start_status=l;/* now the system has gone through at least one query */ adjust_info_panel(); /* adjust image_canvas size due to the creation of a new text window */ window_set(image_canvas, WINWIDTH, screen_rect.width-command_rect.width-8, WIN_HEIGHT, screen_rect.height-info_rect.height, WTN_Y, info_rect.height, 0); text_win=window_create(display_window, TEXTSW, WIN_X, screenrect. width-text_rect. width, WTN_Y, 0, WIN WIDTH, text rect.width.  318  Appendix 4 Source code for interactive module WTNHEIGHT, text_rect. height, 0); panel_set(local_panel, PANELCARETITEM, num_of_whorls, 0); } extern void canvas_handler(event) Event * event; { register int i, j ; if (event_is_up(event)) return; switch (eventaction(event)) { case MS_LEFT: /* locate the image and display related info */ i=image_index(event_x(event),event_y(event)); if(i>=0) show_descriptors(i); break; case MS_MIDDLE: /* mark the point with color 252 and determine the image scale */ pw_put(pw,event_x(event),event_y(event),252); control_point[num_control_point].x:=event_x(event); control jointfnumcontroljointj.y^event^event); if (! num_control_point) { image_scale=atof(descriptor_value[SCALE][rel[image_index (event_x(event), event_y(event))]]); if(!image_scale) image_scale=1.0; } num_control_point++; case MS_RIGHT: /* mark two points for ploting brightness profile */ if (between[l].x || between[l].y) { i^betweenflj.x; j=between[l].y; between[ 1 ] .x=event_x(event); between[ 1 ] .y=event_y(event); between[0].x=i; between[0].y=j; } else if (between[0].x || between[0].y) { between[ 1 ] .x=event_x(event); betweenflj.y^event^event); } else { between[0] .x=event_x(event); between[0].y=event_y(event);}  319  Appendix 4 Source code for interactive module  320  break; default: break; } }  extern void clear_canvas() { (void)pw_writebackground(pw,0,0,(int)(LINT_CAST(window_get(image_canvas, CANVAS_WIDTH))), (int)(LINT_CAST(window_get(image_canvas, CANVAS_HEIGHT))), PIXJXR); }  Appendix 5 Source code for automated module  321  Appendix 5 Source code for automated image measurement module There are 9 files in this program: auto.h, main.c, canny.c, thin.c, trace.h, trace.c, utility.c, smooth_form.c, ribbed_form.c. 1. auto.h /*  * Header file for automated image measurement module. *  * Author: Bo Liang * Department of Geological Sciences * The University of British Columbia * Date: May 1991 * Modifications: April 1994 */  #include <stdio.h> #include <math.h> #include <pixrect/pixrect_hs.h> #define MAXNUM 6000 #define MAXWDTH 2048 #defme MINLEN 10 #definePi #define RIBANG #define COILANG  /* maxium number of segments in the image */ /* minimum number of points in segment */  3.1416 Pi/12 /* radial */ 2*Pi/5 /* spiral */  /* label for line segments */ #define RIB 1 #define COILING 2 #define UNKNOWN 3 #define N #define NE #define E #define SE #define S #define SW #define W #define NW #define O  0 1 2 3 4 5 6 7 8  #define MAX(x, y) #define MIN(x, y)  (x>y)?x: y (x < y) ? x: y  Appendix 5 Source code for automated module #define SQR(i) i*i #define D(xO,yO,xl,yl) sqrt(SQR(xl-xO)+SQR(yl-yO)) #define CLOSE(xO,yO,xl,yl) (abs(x0-xl)<2 && abs(y0-yl)<2) /* angle conversion macro */ #define #define #define #define #define #define #define  POSITIVE(alpha) LESSPI(alpha) TWOPI(alpha) HALFPI(alpha) LARGER(alpha, belta) TRUEDIF(alpha, belta) ANGLE(xO, yO, xl, yl)  (alpha < 0) ? 2*Pi+alpha:alpha (alpha > Pi) ? 2*Pi-alpha:alpha (alpha > 2*Pi) ? alpha-2*Pi:alpha (alpha > Pi/2) ? Pi-alpha:alpha (alpha > belta) ? alpha-belta : 2*Pi+alpha-belta (belta>0) ? alpha-belta : alpha+belta (xO = xl) ? Pi/2 : atan((yl-yO)/(xl-xO))  int int int short int float float float float float  imageSize; num_of_seg; /* number of line segments in the image */ *seq; neighbor[2][MAXNUM]; yo, xo; /* coordinates of the coiling axis */ threshold; *theta; ox[MAXNUM], oyfMAXNUM], r[MAXNUM]; rep[MAXNUM], label[MAXNUM];  int  *num_of_point;  /* number of points in the line segment */  struct points { short int x; short int y; short int z; } *segment[MAXNUM] struct point *newseg[MAXNUM], *buf; Pixrect  *new_image;  2. main.c #include <stdio.h> #include "auto.h" main(argc, argv) int argc; char *argv[]; { FILE *fpi, *fpo;  322  Appendix 5 Source code for automated module char Pixrect colormap_t register int  *image_in, *image_out; *orig_image, *screen[2]; *colormap; argn; nrows, ncols,;  if (argn = getarg("i", argc, argv)) image_in = argv[++argn]; if (argn = getarg("o", argc, argv)) image_out = argv[++argn]; /* load original ammon image */ fpi = fopen(image_in, "r"); orig_image = pr_load(fpi, colormap); if (origimage = NULL) { fprintf(stderr, "Can't open %s as image file\n", image_in); exit(l); } ncols = orig_image->pr_size.x; nrows = orig_image->pr_size.y; imageSize = MAX(nrows, ncols); if ((fpo = fopen(image_out, "w")) = NULL); fprintf(stderr, "Can't open %s as output fileVn", imageout); exit(l); /* create a memory pixrect to host the processed image of origimage */ new_image = mem_create(ncols, nrows, 1); if (new_image = NULL) { fprintf(stderr, "2: can't open new_image as image fileVn"); exit(l); } /* prepare screen for display */ screen[0] = pr_open("/dev/fb"); screenfl] = pr_open("/dev/fb");  /* remove some of the background noise */ remove_noise(orig_image); /* use Canny operator to detect edges */  323  Appendix 5 Source code for automated module edge_detector(orig_image, newimage); /* skeletonize edges potentially wider than one pixel */ edge_thinning(new_image); /* group edge points into line segment */ trace_segment(ncols, nrows); /* after all the changes on orig_image, restore it to original state */ pr_close(orig_image); orig_image = pr_load(fpi, colormap); /* connect short line segments based on distance and colinearity */ connect(); /* order segments according to number of points in segment */ order_segment(); /*  * remove redundant segments based on complete overlap along x & y as * well as closeness of end-points */  remove_redundant_segs(); /*  * use the underlying pattern of ribs and coiling curves to locate * coiling axis */  locate_coiling_axis(ncols, nrows); /*  * assign segments to one of the following classes : Rib, coiling * curve and Unknown V if (label_seg() = RIB) /* ribbed form */ process_ribbed_form();  324  Appendix 5 Source code for automated module else  325  /* smooth form */ process_smooth formO;  exit(O);  3. canny.c provided by the Department of Computer Science, UBC. 4. thin.c provided by the Department of Computer Science, UBC. 5. trace, h static int  xx, yy;  struct point int int };  { x; y;  /* orientation data array in terms of {delta x, delta y} for trace_from */ struct point struct point struct point struct point struct point struct point struct point struct point struct point  main_O[]={{0,l},{l,0},{l ) l},{l,-l}}; main_SE[]={{l,l},{l,0},{l,l}}; main_S[]={{l,0},{l,-l},{l,l}}; main_SW[]={{l,-l},{l,0},{0,-l}}; main_W[]={{0,-l},{l,-l},{-l,-l}}; main_NW[]={{-l,-l},{0,-l},(-l,0}}; main_N[]={{-l,0},{-l,l},{-l,-l}}; main_NE[]={{-l,l},{0,l},{-l,0}}; main_E[]={{0,l},{l,l},{-l,l}};  /* orientation data array for further */ struct point struct point struct point struct point  further_SE[]={{2,2},{l,2},{2,l},{0,2},{2,0},{3,3},{2,3},{3,2},{l,3},{3,l}, {0,3},{3,0}}; further_S[]={{2,0},{2,l},{2,-l},{2,2},{2,-2},{l,2},{l,-2},{3,0},{3,l}, {3,-l},{3,2},{3,-2}}; further_SW[]={{2,-2},{2,-l},{l,-2},{2,0},{0,-2},{3,-3},{3,-2},{2,-3},{3,-l}, {l,-3},{3,0},{0,-3}}; further_N[]={{-2,0},{-2,l},{-2,-l},{-2,2},{-2,-2},{-l,2},{-l,-2},{0,2},{0,-2}, {-3,0},{-3,l},{-3,-l}};  Appendix 5 Source code for automated module struct point struct point struct point struct point static void static void static int static void static void static int  326  further_NE[]={{-2,2},{-l,2},{-2,l},{0,2},{-2,0},{-3,3},{-3,2},{-2,3},{-3,l}, {-l,3},{0,3},{-3,0}}; further_NW[]={{-2,-2},{-2,-l},{-l,-2},{-2,0},{0,-2},{-3,-3},{-2,-3},{-3,-2}, {-l,-3},{-3,-l},{0,-3},{-3,0}}; fiirther_Ea={{0,2},{l,2},{-l,2},{2,2},{-2,2},{2,l},{2,0},{0>3},{l,3},{-l,3}, {2,3},{-2,3}}; further_W[]={{0,-2},{l,-2},'{-l!-2},{2,-2},{-2,-2},{2,-l},{-2,-l},{2,0},{0,-3}, {-l,-3},{l,-3},{2,-3}}; trace_from(int*, int*, int); fiirther(int*, int*, int); any_direction(int*, int*); update_seg(int*, int*, int, int, int); round_up(int*, int*); convert(double);  6. traccc  * This Program is used to trace line segments from output image of Canny * Operator. */  #include "auto.h" #include "trace, h" void trace_segment(h, w) int h, w; { int i, j , k, orientation;  segment[0] = (struct point *) malloc(imageSize * sizeof(points)); buf = segment[0]; for(i= l;i<h;i++) for(j=l;j<w;j++){ if ((k = pr_get(new_image, i, j))) { segment[0]->x = i; segment[0]->y = j ; segment[0]->z = k; ++segment[0]; pr_put(new_image, i, j , 0); orientation = O; num_of_point[num_of_seg] = 0; trace_from(&i, &j, orientation);  Appendix 5 Source code for automated module  327  } } } /* start tracing from point (i, j) along orientation */ static void trace_from(i, j , orientation) int *i, *j, orientation; { register int k, m, n; xx = yy = 0.0; switch (orientation) { case O: n = sizeof main_0 / sizeof main_O[0]; for (m = 0; m < n; m++) if ((k = prj>et(new_image, *i + mainO.x, *j + main_0.y)) > 0) { update_seg(i, j , k, mainO.x, main_0.y); further(i, j , orientation); round_up(i,j); break; } break; case SE: n = sizeof main_SE / sizeof main_SE[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + main_SE.x, *j + main_SE.y)) > 0) { update_seg(i, j , k, mainSE.x, mainSE.y); break; } break; case S: n = sizeof main_S / sizeof main_S[0]; for (m = 0; m < n; m++) if ((k = pr^get(new_image, *i + mainS.x, *j + mainS.y)) > 0) { update_seg(i, j , k, mainS.x, main_S.y); break; } break; case SW: n = sizeof mainSW / sizeof main_SW[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + mainSW.x, *j + mainSW.y)) > 0) { update_seg(i, j , k, main_SW.x, mainSW.y);  Appendix 5 Source code for automated module  328  break; }  }  break; case W: n = sizeof main_W / sizeof main_W[0]; for (m = 0; m < n; m++) if ((k = prj5et(new_image, *i + mainW.x, *j + main_W.y)) > 0) { update_seg(i, j , k, main_W.x, mainW.y); break; } break; case NW: n = sizeof main_NW / sizeof main_NW[0]; for (m = 0; m < n; m++) if ((k = prjjetfaewjmage, *i + main_NW.x, *j + main_NW.y)) > 0) { update_seg(i, j , k, main_NW.x, main_NW.y); break; } break; case N: n = sizeof main_N / sizeof main_N[0]; for (m = 0; m < n; m++) if ((k = pr_get(newjm&ge, *i + main_N.x, *j + main_N.y)) > 0) { update_seg(i, j , k, main_N.x, main_N.y); break; } break; case NE: n = sizeof mainNE / sizeof main_NE[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + main_NE.x, *j + main_NE.y)) > 0) { update_seg(i, j , k, main_NE.x, main_NE.y); break; } break; case E: n = sizeof m a i n E / sizeof main_E[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + main_E.x, *j + main_E.y)) > 0) { update_seg(i, j , k, main_E.x, main_E.y); break; } } /* for switch */ /* for the function */  Appendix 5 Source code for automated module  329  /* find point 2-5 pixels away along the prefered direction */ static void further(i, j , orientation) int *i, *j, orientation; { register int k, m, n; /* fine tuned for each direction, don't try to generalize it */ switch (orientation) { case SE: n = sizeof furtherSE / sizeof further_SE[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + further_SE[m].x, *j + further_SE[m].y)) > 0) { update_seg(i, j , k, further_SE[m].x, further_SE[m].y); break; } break; case S: n = sizeof further_S / sizeof further_S[0]; for (m = 0; m < n; m++) if((k = prjjetOiewjmage, *i + further_S[m].x, *j + further_S[m].y)) > 0) { update_seg(i, j , k, further_S[m].x, further_S[m].y); break; } break; case SW: n = sizeof further_SW / sizeof further_SW[0]; for (m = 0; m < n; m++) if((k = prj»et(new_image, *i + further_SW[m].x, *j + further_SW[m].y)) > 0) { update_seg(i, j , k, further_SW[m].x, further_SW[m].y); break; } break; case N: n = sizeof furtherN / sizeof further_N[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + further_N[m].x, *j + further_N[m].y)) > 0){ update_seg(i, j , k, further_N[m].x, further_N[m].y); break; }  Appendix 5 Source code for automated module  330  break; case NE: n = sizeof further_NE / sizeof further_NE[0]; for (m = 0; m < n; m++) if ((k = pr_j>et(new_image, *i + further_NE[m].x, *j + further_NE[m].y)) > 0) { update_seg(i, j , k, further_NE[m].x, further_NE[m].y); break; } break; case NW: n = sizeof further_NW / sizeof further_NW[0]; for (m = 0; m < n; m++) if((k = prj*et(new_image, *i + further_NW[m].x, *j + further_NW[m].y)) > 0) { update_seg(i, j , k, further_NW[m].x, further_NW[m].y); break; } break; case E: n = sizeof further_E / sizeof further_E[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + further_E[m].x, *j + fiirther_E[m].y)) > update_seg(i, j , k, further_E[m].x, further_E[m].y); break; } break; case W: n = sizeof furtherW / sizeof further_W[0]; for (m = 0; m < n; m++) if ((k = pr_get(new_image, *i + further_W[m].x, *j + further_W[m].y)) > 0) { update_seg(i, j , k, further_W[m].x, further_W[m].y); break; } } /* for the switch */ /* for the function */  /*  * trace along all directions if the number of points in the current segment * is small */  Appendix 5 Source code for automated module  int  any_direction(i, j) int *i, *j; { int k, ii, jj; for(ii = - l ; i i < = l ; i i + + ) for(iJ = -l;jj<=l;jj-H-) if ((k = pr_get(new_image, *i + ii, *j + jj))) { update_seg(i, j , k, ii, jj); return 1; } /* succeed in finding a bridge */ return 0:  /* search along direction (ii, jj) */ static void update_seg(i, j , k, ii, jj) int *i, *j, k, ii, jj { double  sigma;  *i = *i + ii; *j = *j +jj; segment[0]->x = *i; segment [0]->y = *j; segment[0]->z = k; ++segment[0]; pr_put(new_image, *i, *j, 0); xx += ii; yy+=ij; sigma = atan2(yy, xx); orientation - convert(sigma); ++num_of_point[num_of_seg]; linetrace(i, j , orientation); return; } /* explore all directions and store selected path in a new segment */ static void round_up(i, j)  331  Appendix 5 Source code for automated module int  332  *i, *j;  register int  k;  k=l; while (k && num_ofj>oint[num_of_seg] < 5)  /* less than 5 pixels * away */  k = any_direction(i, j); segment[num_of_seg] = (struct point *) malloc(num_of_point[num_of_seg] * sizeof(points)); for (k = 0; k <= num_of_point[num_of_seg]; k++) { *segment[num_of_seg] = *(segment[0] - num_of_point[num_of_seg] - 1 + k); ++segment[num_of_seg]; } theta[num_of_seg] = atan(yy / xx); num_of_seg++; segment[0] = buf;  /* convert angle to orientation */ int convert(sigma) double { register int  sigma; orientation;  switch (nint((4 * sigma) / Pi)) { case 0: orientation = S; break; case 1: orientation = SE; break; case 2: orientation = E; break; case 3: orientation = NE; break; case 4: case -4: orientation = N; break;  Appendix 5 Source code for automated module case -1: orientation = SW; break, case -2: orientation = W; break; case -3: orientation = NW; break; } return orientation;  7. utility.c /*  * remove background noise based on the average and standard deviation of the * backgroud brightness intensity which are estimated from a three-pixel wide * margin of the image */  extern void removenoise(origimage) Pixrect *orig_image; { register int i, j , num; double sum, sum_sqr, mean, std; sum = sum_sqr = 0.0; for (i = 0; i < ncols; i++) { forG = 0 ; j < 3 ; j + + ) { sum += pr^get(orig_image, i, j); sum_sqr += sqr(pr_get(orig_image, i, j)); num++; } for (j = nrows - 3; j < nrows; j++) { sum += pr_get(orig_image, i, j); sum_sqr += sqr(pr_get(orig_image, i, j)); num++; } } for (j = 0; j < nrows; j++) { for(i = 0 ; i < 3 ; i++) { sum += pr_get(origjmage, i, j);  333  Appendix 5 Source code for automated module sum_sqr += sqr(prj*et(orig_image, i, j)); num-H-; } for (i = ncols - 3; i < ncols; i++) { sum += prj>et(orig_image, i, j); sum_sqr += sqr(pr_get(orig_image, i, j)); num++; } }  mean = sum / num; std = sumsqr - num * SQR(mean); std = sqrt(std / (num - 1.0)); /* if mean<128 (black background) and z < mean+std then z =0 */ if (mean < 128) { for (i = 0; i < ncols; i++) for (j = 0; j < nrows; j++) if (pr_get(orig_image, i, j) < mean + std) pr_set(orig_image, i, j , 0); } else { for (i = 0; i < ncols; i++) for (j = 0; j < nrows; j++) if (pr_jget(orig_image, i, j) > mean - std) pr_set(orig_image, i, j , 0); }  /* compute portion of overlap between segment zO-zl and z2-z3 */ float overlap(z0, zl, z2, z3) float zO, zl, z2, z3; {  int float  ij; ovlp, lap[2];  if(z0>zl){ lap[0] = zl; zl = zO; zO = lap[0]; } if(z2>z3){ lap[0] = z3;  334  Appendix 5 Source code for automated module  335  z3 = z2; z2 = lap[0]; } if (z3 > zl) lap[0] = zl - z2; else lap[0] = z3 - zO;  /* the length of the overlap */  lap[l] = (zl - zO < z3 - z2) ? zl - zO : z3 - z2;  /* the length of the * shortest segment */  if (tmp < 0) ovlp = 0.0; else if (!lap[l]) ovlp =1.0; else ovlp = lap[0]/lap[l]; return ovlp; } /*  * remove redundant segments based on complete overlap along x & y as well as * closeness of end-points */  static void removeredundantsegsO { register int i,j, k,jl,j2; float x[5], y[5];  >  for (i = 2; i < num_of_seg; i++) { x[l] = (newseg[seq[i]j - l)->x; yfl] = (newseg[seq[i]j - l)->y; x[2] = (newseg[seq[i]J - num_of_point[seq[i]] - l)->x; y[2] = (newseg[seq[i]] - num_of_point[seq[i]] - l)->y; for(j = i ; j < i ; j + + ) { x[3] = (newseg[seq(j]] - l)->x; y[3] = (newseg[seq[j]] - l)->y; x[4] = (newseg[seq(j]] - num_of_point[seq(j]] - l)->x; y[4] = (newseg[seq[j]] - num_of_point[seq[j]] - l)->y; if (overlap(x[l], x[2], x[3], x[4]) > 0.99 && overlap(y[l], y[2], y[3], y[4]) 0.99) { j l = j 2 = 0; for (il = 0; il <= num_of_point[seq[j]]; il++) {  Appendix 5 Source code for automated module x[0] = (newseg[seqOJ] - il - l)->x; y[0] = (newseg[seq[j]] - il - l)->y; if(D(x[l],y[l],x[0],y[0])<3.0) j i = i; if(D(x[2],y[2],x[0],y[0])<3.0) j2=l; if 01 &&J2) break; } if 01 &&J2) { num_of_point[seq[i]] = 0; break; } } } } return;  /* end ofj loop */ /* end of i loop */  } /* connect short segments based on distance and colinearity */ void connect() { register int double  i, j , k, x[5], y[5]; tmp, sigma;  /* allocate space for new segment array */ newseg[0] = (struct point *) malloc(imageSize * sizeof(points)); buf = newseg[0]; /* record where it starts */ k = 0; for (i = 1; i < num_of_seg; i++) if(num_of_point[i]) { k++; x[0] = (segment[i] - l)->x; y[0] = (segmentfij - l)->y; x[l] = (segment[i] - num_of_point[i] - l)->x; y[l] = (segment[i] - num_of_point[i] - l)->y; for (j = 0; j <= num_of_point[i]; j++) { *newseg[0] = *(segment[i] - num_of_point[i] - 1 + j); ++newseg[0]; }  336  Appendix 5 Source code for automated module  337 -  for (j = i + 1; j < num_of_seg; j++) if (num_of_point[j]) { tmp = fabs(theta[i] - theta[j]); sigma = HALFPI(tmp); x[2] = (segment[j] - l)->x; y[2] = (segmentrjj - l)->y; x[3] = (segment[j] - num_of_point[j] - l)->x; y[3] = (segment[j] - num_of_point[j] - l)->y; if(fabs(theta[i])<Pi/4.0) tmp = overlap(x[0], x[l], x[2], x[3]); else tmp = overlap(y[0], y[l], y[2], y[3]); /*  * if few overlap and segment ij are * colinear, or the two segments are * very short, connect the two */  if (num_of_point[j] > 2 && num_of_point[i] > 2 && sigma < Pi / 9.0 && tmp < 0.1 || num_of_point[i] < 3 || num_of_point[j] < 3) { /*  * check the four end points * of the two segments, * determine how to connect * them */  if (CLOSE(x[0], y[0], x[2], y[2])) { join_segment(j, 1); /* 1 - start from front */ } else if (CLOSE(x[0], y[0], x[3], y[3])) { join_segment(j, -1); /* 1 - start from back */ x[0] = x[2]; y[0] = y[2]; } else if (CLOSE(x[l], y[l], x[2], y[2])) { reverse_segment(i);  join_segment(j, 1); x[l]=x[0]; y[i] = y[0]; x[0]=x[3]; y[0] = y[3];  } else if (CLOSE(x[l], y[l], x[3], y[3])) { reverse_segment(i); join_segment(j, -1);  Appendix 5 Source code for automated module  338  x[l]=x[0]; y[i] = y[0]; x[0] = x[2]; y[0] = y[2];  }  theta[i] = ANGLE(x[0], y[0], x[l], y[l]); j = »; }  } newseg[k] = (struct point *) malloc(num_of_point[i] * sizeof(points)); for (j = 0; j <= num_of_point[i]; j++) { *newseg[k] = *(newseg[0] - num_of_point[i] - 1 + j); ++newseg[k]; } newseg[0] = buf; /* reset the memory location * for newseg[0] */ num_of_point[k] = num_of_point[i]; theta[k] = theta[i]; } num_of_seg = k + 1; } /* join segment j to newseg[0] from direction k */ static void join_segment(j, k) int j , k; { register int i; if(k>0) for (i = 0; i <= num_of_point[j]; i++) { *newseg[0] = *(segment[j] - i - 1); ++newseg[0]; }  else for (i = num_of_point[j]; i >= 0; i~) { *newseg[0] = *(segment[j] - i - 1); ++newseg[0]; } num_of_point[i] += num_of_point[j] + 1; num_of_point[j] = 0; } /* reverse the order of points in segment */  Appendix 5 Source code for automated module  static void reversesegment(i) int { register int  i; j;  for (j = 0; j < (num_of_point[i] + 1) / 2; j++) { *(newseg[0] - j) = *(newseg[0] - num_of_point[i] - 1 + j); *(newseg[0] - num_of_point[i] - 1 + j) = *(newseg[0] - j - 1); } for (j = 0; j < (num_of_point[i] + 1) / 2; j++) *(newseg[0] - (num_of_point[i] + l ) / 2 + j ) = *(newseg[0] - (num_of_point[i] + 1) / 2 + 1 + j); } /*  * order segments based on number of points in the segment, eliminate the one * with less than MINLEN points and save order information in seq[] */  static void order_segment() { register int  i, j , k;  for (i = 1; i < num_of_seg; i++) seq[i] = i; for (i = 1; i < n u m o f s e g ; i++) for (j = i + 1; j < num_of_seg; j++) if (num_of_point[seq[i]] < num_of_point[seq[j]]) { k = seq[i]; seq[i] = seqO]; seqjj] = k; } for (i = 1; i < num_of_seg; i++) if (num_of_point[seq[i]] < MINLEN) numofseg--; } /*  * locate coiling axis according to support from rib and coiling curve * candidates */  339  Appendix 5 Source code for automated module  340  static void locate_coiling_axis(ncols, nrows) int ncols, nrows; { register int i, j , k, x[5], y[5]; double sigma[2], contrib[2]; contrib[l] = 0; for (i = x[0] - ncols / 4; i < x[0] + ncols / 4; i += 5) /* 5 - scanning * resolution */ for (j = y[0] - nrows / 4; j < y[0] + nrows / 4; j += 5) if(i>0&&j>0){ contrib[0] = 0; for (k = 1; k < n u m o f s e g ; k++) { x[l] = (newseg[seq[k]] - num_of_point[seq[k]] / 2)->x - i; y[l] = (newseg[seq[k]] - num_of_point[seq[k]] / 2)->y - j ; if (x[l]) { sigma[0] = atan((double) y[l] / x[l]); sigma[l] = fabs(theta[seq[k]] - sigma[0]); sigma[0] = HALFPI(sigma[l]); } else { /* middle point vector * is in vertical * position */ sigma[0] = POSITIVE(theta[seq[k]]); } if (sigma[0] < Pi /12.0) /* a rib candidate */ contrib[0] += num_of_point[seq[k]]; else if (num_of_point[seq[k]] < imageSize / 6) { if (sigma[0] > 0.4 * Pi) /* short coiling curve * segment */ contrib[0] += num_of_point[seq[k]]; } else { /* get a short segment * of the long coiling * curve candidate */ x[l] = (newseg[seq[k]] - num_of_point[seq[k]] / 2 + imageSize / 20)->x - (newseg[seq[k]] num_of_point[seq[k]] / 2 - imageSize / 20)->x; y[l] = (newseg[seq[k]] - num_of_point[seq[k]] / 2 + imageSize / 20)->y - (newseg[seq[k]] num_of_point[seq[k]] / 2 - imageSize / 20)->y; if (x[l]) { sigma[l] = fabs(Pi / 2 - atan((double) y[l] / x[l])); sigma[0] = HALFPI(sigma[l]); } else sigma[0] = 0;  Appendix 5 Source code for automated module if(sigma[0] >0.4 * Pi) contrib[0] += num_of_point[seq[k]]; } } if (contrib[0] > contrib[l]) { /* the location geting * the largest support * is coiling axis */ contrib[l] = contrib[0]; xo = i;  yo=j; } } } int label_seg() { register int double  i, k, x[5], y[5]; sigma;  for (i = 1; i < n u m o f s e g ; i++) label[i] = 0; for (i = 1; i < num_of_seg; i++) { x[l] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->x - xo; y[l] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->y - yo; if (x[l]) { sigma = fabs(theta[seq[i]] - atan(y[l] / x[l])); sigma = HALFPI(sigma); } else sigma = TRUEDIF(Pi / 2, theta[seq[i]]); theta[seq[i]] = POSITIVE(atan2(y[l], x[l])); if(sigma<RIBANG) label[i] = RIB; else if (sigma > COILANG) label[i] = COILING; else labelp] = UNKNOWN; } k = 0; for (i = 1; i < num_of_seg; i++) if(label[i]=RIB) k++; if (k > 0.3 * num_of_seg) return RIB; /* ribbed form */ else  341  Appendix 5 Source code for automated module return COILING;  /* smooth shell */  }  bright_between(iO, jO, xO, yO, rO, rl) int iO, jO, xO, yO; float rO, rl; { register int i, j , il = 0, jl, x[5], y[5], f[400][100], count[400]; float s[5], n[5]; for (i = 0; i < 5; i++) n[i] = 0.0; for (i = 0; i <= num_of_point[seq[iO]]; i++) { x[l] = (newseg[seq[iO]] - i - l)->x; y[l] = (newseg[seq[iO]] - i - l)->y; s[l] = D(xO,yO,x[l],y[l]); if(s[l]>=rO&&s[l]<=rl){ for (j = 0; j <= num_of_point[seq[jO]]; j++) { x[2] = (newseg[seq[jO]] - j - l)->x; y[2] = (newseg[seq[j0]] - j - l)->y; s[2] = D(xO,yO,x[2],y[2]); if(fabs(s[2]-s[l])<1.0) break; } s[3] = atan2((double) y[l] - yO, (double) x[l] - xO); s[4] - atan2((double) y[2] - yO, (double) x[2] - xO); if(fabs(s[3]-s[4])<Pi/4.0){ if(s[3]>s[4]){ s[0] = s[3]; s[3] = s[4]; s[4] = s[0]; } } else { if(s[3]<0.0){ s[0] = s[4]; s[4] = 2 * Pi + s[3]; s[3] = s[4]; } else if(s[4]< 0.0) s[4] += 2 * Pi; }  il++; for (s[0] = s[3]; s[0] <= s[4]; s[0] 4= 0.5 / s[l]) { x[3]=x0 + s[l]*cos(s[0]); y[3] = y0 + s [l]*sin(s[0]);  342  Appendix 5 Source code for automated module  343  if (!(x[3] = x[4] && y[3] = y[4])) { x[4] = x[3]; y[4] = y[3]; f[il]Dl++] = prjget(x[3],y[3]); }  } count[il] = jl; }  } for(i= l ; i < = i l ; i + + ) { n[0] = count[i] / 2; nil] += f[i][(int) n[0]]; n[2] += SQR(f[i][(int) n[0]]); } if (il) { n[3] = n [ l ] / i l ; s[0] = n[2] + il * SQR(n[3]) - 2 * n[3] * n[l]; n[4] = 2 * sqrt(s[0] / il); n[l] = n[2] = n[0] = 0.0; for(i= l ; i < = i l ; i + + ) { jl=0; for 0 = 1; j <= countfi] / 2; j++) if (jl II m\j] < Ont) n[3] + n[4] && f[i][j] > (int) n[3] - n[4]) { ji = i; n[l] += f[i]D]; n[2] += SQR(f[i]D]); n[0]+=1.0; } } for(i= l;i<=il;i++) { jl=0; for (j = count[i] - 1; j > count[i] / 2; j--) if (jl II f[i][)] < Ont) n[3] + n[4] && f[i]D] > (int) n[3] - n[4]) { ji = i; n[i]+=f[i]D]; n[2] += SQR(f[i][j]); n[0]+=1.0; } } if(n[0]>4.0) n[3]=n[l]/n[0]; else return -2; s[0] = n[2] + n[0] * SQR(n[3]) - 2 * n[3] * n[l]; s[0] = sqrt(s[0]/n[0]); if(s[0]< threshold)  Appendix 5 Source code for automated module return (int) n[3]; else return-1; } else return -2; } bright_nearby(iO, jO, xO, yO, rO, i2) int iO, jO, i2, xO, yO; float rO; { register int i, j , il = 0, jl, x[5], y[5], f[400][100], count[400]; float s[5], n[5]; for (i = 0; i < 5; i++) n[i] = 0.0; s[2] = 0.0; for (i = 0; i <= num_of_point[seq[iO]]; i++) { x[l] = (newseg[seq[iO]] - i - l)->x; y[l] = (newseg[seq[iO]j - i - l)->y; s[l] = D(xO,yO,x[l],y[l]); if(fabs(s[l]-s[2])>0.5){ s[2] = s[l]; s[3] = atan2((double) y[l] - yO, (double) x[l] - xO); j i = i; il++; if (jO < 0) for (s[0] = s[3]; s[0] <= s[3] + rO; s[0] += 0.5 / s[l]) { x[3] = x0 + s[l] *cos(s[0]); y[3] = y0 + s[l] *sin(s[0]); if(!(x[3] = x[4]&&y[3] = y[4])){ x[4] = x[3]; y[4]=y[3]; f[il][jl++] = pr_get(orig_image, x[3], y[3]); }  } else for (s[0] = s[3]; s[0] >= s[3] - rO; s[0] -= 0.5 / s[l]) { x[3] = x0 + s[l]*cos(s[0]); y[3] = y0 + s[l]*sin(s[0]); if(!(x[3] = x[4]&&y[3] = y[4])){ x[4]=x[3]; y[4] = y[3]; f[il][jl++] = pr_get(orig_image, x[3], y[3]); }  } count[il] =jl;  344  Appendix 5 Source code for automated module  345  } } for(i=l;i<=il;i++) { n[0] = count[i] / 2; n[l]+=f[i][(int)n[0]]; n[2]+=SQR(f[i][(int)n[0]]); } if (il) { n[3] = n [ l ] / i l ; s[0] = n[2] + il * SQR(n[3]) - 2 * n[3] * n[l]; n[4] = 2*sqrt(s[0]/il); n[l] = n[2] = n[0] = 0; for(i= l ; i < = i l ; i + + ) { j l = 0; for 0 = 1; j <= countfi] / 2; j++) if (jl || f[i]D] < (int) n[3] + n[4] && f[i]D] > (int) n[3] - n[4]) { ji = i; n[i]+=f[i]D]; n[2] += SQR(fTi]D]); n[0] += 1.0; } } for(i= l ; i < = i l ; i + + ) { j l = 0; for (j = count[i] - 1 ; j >.count[i] / 2; j--) if 01 || mm < (mt) n[3] + n[4] && f[i]0] > (int) n[3] - n[4]) { ji = i; n[l]+=f[i][j]; n[2] += SQR(f[i]G]); n[0]+=1.0; } } if(n[0]>4.0) n[3] = n[l]/n[0]; else return -2; s[0] = n[2] + n[0] * SQR(n[3]) - 2 * n[3] * n[l]; s[0] = sqrt(s[0]/n[0]); if (i2 || s[0] < threshold) return (int) n[3]; else return -1; } else return -2:  Appendix 5 Source code for automated module  346  countpoints_between(iO, jO) int iO, jO; { register int i, j , j 1, n = 0, x[5], y[5]; if (theta[seq[iO]] > 0.25 * Pi && theta[seq[iO]] < 0.75 * Pi || theta[seq[iO]] > 1.25 * Pi &&theta[seq[iO]]<1.75*Pi) for (i = 0; i <= num_of_point[seq[iO]]; i++) { x[l] = (newseg[seq[iO]] - i - l)->x; y[l] = (newseg[seq[iO]] - i - l)->y; x[2] = 0; for (j = 0; j <= num_pf_point[seq[j0]]; j++) if (y[l] = (newseg[seq[j0]] - j - l)->y) { x[2] = (newseg[seq[j0]] - j - l)->x; break; } if (x[2]) { if(x[l]>x[2]){ x[3]=x[2]; x[2] = x[l]; x[l] = x[3]; } for (x[3] = x[l] + 3; x[3] < x[2] - 2; x[3]++) if(pr_j>et(x[3],y[l])){ j i = i; for (j = 0; j <= num_of_point[seq[i0]]; j++) if (x[3] = (newseg[seq[i0]] - j - l)->x && y[l] = (newseg[seq[i0]] - j - l)->y) { jl=0; break; }  if(jl) for (j = 0; j <= num_of_point[seq[j0]]; j++) if (x[3] = (newseg[seq[j0]] - j - l)->x && y[l] = (newseg[seq[j0]] - j i)->y) { jl=0; break; } ifOl) n++; } } } else for (i = 0; i <= num_of_point[seq[iO]]; i++) {  Appendix 5 Source code for automated module  347  x[l] = (newseg[seq[iO]] - i - l)->x; y[l] = (newseg[seq[iO]j - i - l)->y; y[2] = 0; for (j = 0; j <= num_of_point[seq[jO]]; j++) if (x[l] = (newseg[seq[jO]] - j - l)->x) { y[2] = (newseg[seq[J0]] - j - l)->y; break; } if <y[2]) { if(y[i]>y[2]){ y[3] = y[2]; y[2] = y[i]; y[i] = y[3]; } for (y[3] = y[l] + 3; y[3] < y[2] - 2; y[3]++) if (pr_j>et(x[l], y[3])) { j i = i; for (j = 0; j <= num_of_point[seq[iO]]; j++) if (x[l] = (newseg[seq[iO]] - j - l)->x && y[3] = (newseg[seq[iO]] - j - l)->y) { jl=0; break; }  ifOi) for (j = 0; j <= num_of_point[seq[jO]]; j++) if (x[l] = (newseg[seq[jO]] - j - l)->x && y[3] = (newsegfseqOO]] - j i)->y) { jl-O; break; } ifOi) n++; } } } return n; } getarg(desig, int char { int char  argc, argv) argc; *desig, *argv[]; argn; minus[2], lookfor[12];  Appendix 5 Source code for automated module  348  strcpy(minus, "-"); strcpy(lookfor, minus); strcat(lookfor, desig); for (argn = 1; argn < argc; argn++) if (!strcmp(argv[argn], lookfor)) return (argn); return (0); }  8. smoothform.c /* This program processes ammonites with few ribs. It was written several years ago and was in poor shape. It is a typical example of bad coding practice, difficult to read and maintain */ #include "auto.h" process_smooth_form() { register int i,j, k, x[110], y[110]; float tmp[6], x[l] = xx[l][pos[i2]]; int ORIENTATION; y[i] = yy[i][pos[i2]] ; x[2] = xx[l][pos[i2] + n[i2] - 1]; y[2]=yy[l][pos[i2]+n[i2]-l]; r[0]=D(xo,yo,x[l],y[l]); r[100]=D(xo,yo,x[2],y[2]); if(r[100]>r[0]) ORIENTATION = 0; else ORIENTATION = 1; n[201] = n[100]/20; if(n[i2]>n[201]){ x[2] = xx[l][pos[i2] + n[201]]; y[2] = yy[l][pos[i2] + n[201]]; r[100]=D(xo,yo,x[2],y[2]); } if(x[l]-xo) tmp[l] = atan2((float) (y[l] - yo), (float) (x[l] - xo)); else tmp[l] = (y[l] > yo) ? Pi / 2.0 : -Pi / 2.0; if(x[2]-xo) tmp[2] = atan2((float) (y[2] - yo), (float) (x[2] - xo));  Appendix 5 Source code for automated module else tmp[2] = (y[2] > yo) ? Pi / 2.0 : -Pi / 2.0; if(tmp[l]*tmp[2]>0.0) tmp[0] = fabs(tmp[2] - tmp[l]); else tmp[0] - LESSPI(fabs(tmp[2] - tmp[l])); tmp[3] = fabs(log(r[100] / r[0]) / tmp[0]); for (i = 1; i <= num_of_point[0]; i++) if(j&&len[i]>pos[i2]-2){ n[101]=i; j = 0; } else if (!j && len[i] > pos[i2] + n[i2] - 3) { n[102] = i; break; } for (i = 0; i <= 72; i++) ox[i] = oy[i] = -1.0; n[201] = num_of_point[0] / 20; ox[80]= 10.0; for(j = 0;j<n[201]/3;j++){ x[l] = (segment[0] - n[101] - 1 - j)->x; y[l] = (segmentfO] - nflOl] - 1 - j)->y; r[0]=D(xo,yo,x[l],y[l]); if(n[i2]>n[201]) n[202]=n[101] + n[201]-j; else n[202]=n[102]-j; x[2] = (segment[0] - n[202])->x; y[2] = (segmentfO] - n[202])->y; r[l]=D(xo,yo,x[2],y[2]); if(x[l]-xo) tmp[l] = atan2((float) (y[l] - yo), (float) (x[l] - xo)); else tmp[l] = (y[l] > yo) ? Pi / 2.0 : -Pi / 2.0; if(x[2]-xo) tmp[2] = atan2((float) (y[2] - yo), (float) (x[2] - xo)); else tmp[2] = (y[2] > yo) ? Pi / 2.0 : -Pi / 2.0; if(tmp[l] *tmp[2]>0.0) tmp[0] = fabs(tmp[2] - tmpfl]); else tmp[0] - LESSPI(fabs(tmp[2] - tmp[l])); if (ORIENTATION && r[l] < r[0]) { ox[0] = log(r[0]/r[l])/tmp[0]; if (fabs(ox[0] - tmp[3]) < ox[80]) {  349  Appendix 5 Source code for automated module ox[36] = ox[0];  oy[36] = -tmp[0]; ox[80] = fabs(ox[0] - tmp[3]); } } else if (!ORIENTATION && r[l] > r[0]) { ox[0] = log(r[l]/r[0])/tmp[0]; if (fabs(ox[0] - tmp[3]) < ox[80]) { ox[36] = ox[0]; oy[36] = tmp[0]; ox[80] = fabs(ox[0] - tmp[3]); } } } a[0] = r[0]; n[202]+=n[201]; i2 = 37; x[3]=x[2]; y[3] = y[2]; r[3]=r[l]; tmp[3] = tmp[2]; j0 = 0; for (i = n[202]; i < num_of_point[0]; i += n[201]) { ox[80] = ox[i2 - 1]; for(j = 0;j<n[201]/2;j-H-){ x[4] = (segment[0] - i + j)->x; y[4] = (segment[0] - i + j)->y; r[4] = D(xo,yo,x[4],y[4]); if (x[4] - xo) tmp[4] = atan2((float) (y[4] - yo), (float) (x[4] - xo)); else tmp[4] = (y[4] > yo) ? Pi / 2.0 : -Pi / 2.0; if (tmp[3] * tmp[4] > 0.0) tmp[0] = fabs(tmp[4] - tmp[3]); else tmp[0] = LESSPI(fabs(tmp[4] - tmp[3])); if (ORIENTATION && r[4] < r[3]) { ox[0] = log(r[3]/r[4])/tmp[0]; if (fabs(ox[0] - ox[i2 - 1]) < ox[80]) { ox[80] = fabs(ox[0] - ox[i2 - 1J); ox[i2] = ox[0]; oy[i2] = -tmp[0]; x[6]=x[4]; y[6] = y[4]; r[6] = r[4];  350  Appendix 5 Source code for automated module tmp[5]  =  tmp[4];  }  } else if (!ORIENTATION && r[4] > r[3]) { ox[O] = log(r[41 / r[3]) I tmp[0]; if(fabs(ox[0] ox[i2 1]) < ox[80]) { ox[801 = fabs(ox[0] ox[i2 1]); ox[i2] = ox[0]; oy[i2] = tmp[O]; x[6] = x[4]; y[6] = y[4]; r[61 = r{4j; tmp[5] = tmp[4]; -  -  -  } ) }  if(ox[80] <ox[i2 1]) { x[3] = x[6]; y[3] = y[6]; r[3] = r[6]; tmp[3] = tmp[5]; i2++; -  }  }  if(i2=37) { if(oy{36] > 0.0) { x[99] = x[2j; y[99j = y[2]; c[0j = tmp[2]; } else { x[98] = x[21; y[98j = y[2]; } else  {  } if(oy[36] > 0.0) { x[99] = x[3];  y[991 y[ 1; 3 =  c[0] =tmp[3];  } else { x[98] y[98j  }  x[3]; =  y[3j;  }  n[202] = n[101] +jl 35; x[3] = x[1];  y[3]=y[l];  -  n[201];  -  351  Appendix 5 Source code for automated module tmp[3] = tmp[l]; r[3] = r[0]; for (i = n[202]; i > 0; i -= n[201]) { ox[80] = ox[il + 1]; for(j = 0;j<n[201]/2;j++){ x[4] = (segment[0] - i - j)->x; y[4] = (segmentfoj - i - j)->y; r[4] = D(xo,yo,x[4],y[4]); cl = l; if(x[4]-xo) tmp[4] = atan2((float) (y[4] - yo), (float) (x[4] - xo)); else tmp[4] = (y[4] > yo) ? Pi / 2.0 : -Pi / 2.0; if (tmp[3] * tmp[4] > 0.0) tmp[0] = fabs(tmp[4] - tmp[3]); else tmp[0] = LESSPI(fabs(tmp[4] - tmp[3])); if (ORIENTATION && r[4] > r[3]) { ox[0] = log(r[4]/r[3])/tmp[0]; if (fabs(ox[0] - ox[il + 1]) < ox[80]) { ox[80] = fabs(ox[0] - ox[il + 1]); ox[il] = ox[0]; oy[il]=tmp[0]; x[6] = x[4]; y[6] = y[4]; r[6] = r[4]; tmp[5] = tmp[4]; } } else if (IORIENTATION && r[4] < r[3]) { ox[0] = log(r[3]/r[4])/tmp[0]; if (fabs(ox[0] - ox[il + 1]) < ox[80]) { ox[80] = fabs(ox[0] - ox[il + 1]); ox[il] = ox[0]; oy[il] = -tmp[0]; x[6] = x[4]; y[6]=y[4]; r[6] = r[4]; tmp[5] = tmp[4]; } } } if(ox[80]<ox[il + l]){ x[3] = x[6]; y[3] = y[6]; r[3] = r[6]; tmp[3] = tmp[5];  352  Appendix 5 Source code for automated module  } } if(il=35) { if (oy[36] < 0.0) { x[99] = x[l]; y[99]=y[l]; c[0]=tmp[l]; } else { x[98]=x[l]; y[98]=y[l]; } } else { if (oy[36] < 0.0) { x[99] = x[3]; y[99] = y[3]; c[0]=tmp[3]; } else { x[98] = x[3]; y[98] = y[3]; } } if (! ORIENTATION) ORIENTATION = -1; tmp[0] = 0.0; for (i = il + l;i<i2;i++) tmp[0] 4= fabs(oy[i]); r[0]=D(xo,yo,x[98],y[98]) ; r[100]=D(xo,yo,x[99],y[99]); tmp[l] = x[99] - xo; tmp[2] = y[99]-yo; tmp[3] = atan2(tmp[2], tmp[l]); angle = POSITIVE(tmp[3]); a[0] = fabs(log(r[100] / r[0]) / tmp[0]); b[0]=log(r[100])/a[0]; r[0] = r[100] / exp(a[0] * 2 * Pi); cl=0; i2=l; for(i=l;i<il;i++){ jl=0; x[21] = (newseg[seq[i]] - l)->x; y[21] = (newsegfseqfij] - l)->y; x[22] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->x; y[22] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->y; r[l] = D(xo,yo,x[21],y[21]);  353  Appendix 5 Source code for automated module  354  if(r[l]<r[0]){ r[200]=D(xo,yo,x[22],y[22]); tmp[l] = atan2((double) y[21] - yo, (double) x[21] - xo); tmp[l] = POSITIVE(tmp[l]); tmp[2] = atan2((double) y[22] - yo, (double) x[22] - xo); tmp[2] = POSITIVE(tmp[2]); tmp[3] = fabs(tmp[2] - tmp[l]); if (tmp[3] > Pi) { tmp[3] = 2 * Pi - tmp[3]; if (ORIENTATION > 0 && (tmp[l] > tmp[2] && r[200] > r[l] || tmp[l] < tmp[2] && r[200] < r[l])) j i = i; else if (ORIENTATION < 0 && (tmp[l] > tmp[2] && r[200] < r[l] || tmp[l] < tmp[2] && r[200] > r[l])) j i = i; } else { if (ORIENTATION > 0 && (tmp[l] > tmp[2] && r[200] < r[l] || tmp[l] < tmp[2] && r[200] > r[l])) j i = i; else if (ORIENTATION < 0 && (tmp[l] > tmp[2] && r[200] > r[l] || tmp[l] < tmp[2] && r[200] < r[l])) j i = i; } tmp[4] = fabs(log(r[200] / r[l])) / tmp[3]; if(jl&&tmp[4]<3*a[0]){ label[i] = -2; x[i2] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->x; y[i2] = (newseg[seq[i]J - num_of_point[seq[i]] / 2)->y; tmp[l] = x[i2] -xo; tmp[2] = y[i2]-yo; tmp[2] = atan2(tmp[2], tmp[l]); theta[seq[i]] = POSITIVE(tmp[2]); i2++; if(i2> 10) break; } } } for(i=l;i<il;i++) if (label[i] > 0) label[i] = 0; tmp[0] = 0.0; for(i=l;i<i2-l;i++) for(j=i+l;j<i2;j++){ r[200] = D(xo,yo,x[j] ) yO]); r[201]=D(xo,yo,x[i],y[i]);  Appendix 5 Source code for automated module  355  tmp[l] = atan2((double) y[j] - yo, (double) x[j] - xo); tmp[l] = POSITIVE(tmp[l]); tmp[2] = atan2((double) y[i] - yo, (double) x[i] - xo); tmp[2] = POSITIVE(tmp[2]); tmp[4] = 0.0; if (r[201] > r[200]) { for(j0 = 0;j0<5;j0++){ if (ORIENTATION > 0 && (tmp[0] = 2 * jO * Pi + tmp[2] tmp[l])>Pi/3) tmp[4] = log(r[201] / r[200]) / tmp[0]; else if (ORIENTATION < 0 && (tmp[0] = 2 * jO * Pi + tmp[l]-tmp[2])>Pi/3) tmp[4] = log(r[201] / r[200]) / tmp; if (tmp[4] > a[0] / 3 && tmp[4] < 1.5 * a[0]) { c[l] = tmp[4]; d[l] = log(r[201])/c[l]; tmp[4] = log(r[100]) / c[l] + Pi / 2.0; tmp[3] = tmp[2]; jl=0; for (iO = (tmp[4] - d[l]) / (2 * Pi) - 2; iO <= (tmp[4] - d [ l ] ) / ( 2 * P i ) + 2;iO++){ r[4] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION * (angle - tmp[3]))); if (r[4] < r[100] + (r[100] - r[0]) / 2 && r[4]>(r[100] + r [ 0 ] ) / 2 ) { j i = i; break; } } if 01) { tmp[l]=tmp[2] = 0.0; for(ji = l ; j l < i i ; j i + + ) if(label[jl] = - l ) { x[190] = (newseg[seq{jl]] - l)->x; y[190] = (newseg[seq[jl]] - l)->y; x[191] = (newseg[seq[jl]] num_of_point[seq[jl]] - l)->x; y[191] = (newseg[seq[jl]] num_of_point[seq[jl]] - l)->y; r[190] = D(xo, yo, x[190], y[190]); r[191] = D(xo, yo, x[191], y[191]); if(r[190]>r[191]){ r[192] = r[191]; r[191] = r[190]; r[190] = r[192]; }  Appendix 5 Source code for automated module  356  for (iO = -d[l] / (2 * Pi) - 1.0; iO <= (tmp[4] - d[l]) / (2 * Pi) + 1; i0++) { r[2] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION *(theta[seq[jl]] - tmp[3]))); if (r[2] < r[0] && r[2] > r[190] && r[2] < r[191]) { tmp[2] += num_of_point[seq[jl]]; break; } } }dseif(label01] = -2){ x[190] = (newseg[seq[jl]] num_of_point[seq(jl]] / 2)->x; y[ 190] = (newseg[seq[j 1 ]] num_of_point[seq[jl]] / 2)->y; r[190] = D(xo, yo, x[190], y[190]); for (iO = -d[ 1 ] / (2 * Pi) - 1; iO <= (tmp[4] d[l])/(2*Pi)+1.0;iO++){ r[2] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION * (theta[seq[jl]]-tmp[3]))); if (r[2] < r[0] && fabs(r[2] - r[190]) < 5.0) { tmp[l] += num_of_point[seq[jl]]; break; } } } if (tmp[l] / tmp[2] > tmp[0]) { tmp[0] = tmp[l] / tmp[2]; c[0] = c[l]; d[0] = d[l]; sigma = tmp[3]; } } } } } else { for(j0 = 0;j0<5;j0++){ if (ORIENTATION > 0 && (tmp[0] = 2 * jO * Pi + tmp[l] - tmp[2]) > Pi / 3) tmp[4] = log(r[200] / r[201]) / tmp[0]; else if (ORIENTATION < 0 && (tmp[0] = 2 * jO * Pi + tmp[2] - tmp[l]) > Pi 13) tmp[4] = log(r[200] / r[201]) / tmp[0]; if (tmp[4] > a[0] / 3 && tmp[4] < 1.5 * a[0]) { c[l] = tmp[4]; d[l] = log(r[200])/c[l];  Appendix 5 Source code for automated module  357  tmp[4] = log(r[100]) / c[l] + Pi / 2.0; tmp[3] = tmp[l]; for (iO = (tmp[4] - d[l]) / (2 * Pi) - 2; iO <= (tmp[4] - d[l]) / (2 * Pi) + 2; i0++) { r[4] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION * (angle - tmp[3]))); if (r[4] < r[100] + (r[100] - r[0]) / 2 && r[4] > (r[100] + r[0]) / 2) { j i = i; break; } }  if GO { tmp[l]=tmp[2] = 0.0; forOi = i ; j i < i i ; j i + + ) if(label[jl] = - l ) { x[190] = (newseg[seq[jl]] - l)->x; y[190] = (newseg[seq[jl]] - l)->y; x[191] = (newseg[seq[jl]] - num_of_point[seq[jl]] - l)->x; y[191] = (newseg[seq[jl]] - num_of_point[seq[jl]] - l)->y; r[190] = D(xo, yo, x[190], y[190]); r[191]=D(xo,yo,x[191],y[191]); if(r[190]>r[191]){ r[192] = r[191]; r[191] = r[190]; r[190] = r[192]; } for (iO = -d[l] / (2 * Pi) - 1.0; iO <= (tmp[4] - d[l]) / (2 * Pi)+1.0;i0++){ r[2] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION * (theta[seq[jl]] - tmp[3]))); if (r[2] < r[0] && r[2] > r[190] && r[2] < r[191]) { tmp[2] += num_of_point[seq[jl]]; break; } } } else if (label[jl] = -2) { x[190] = (newseg[seq[jl]] - num_of_point[seq[jl]] / 2)->x; y[190] = (newseg[seq[jl]] - num_of_point[seq[jl]] / 2)->y; r[190] = D(xo, yo, x[190], y[190]); for (iO = -d[l] / (2 * Pi) -1.0; iO <= (tmp[4] - d[l]) / (2 * Pi)+1.0;i0++){ r[2] = exp(c[l] * (d[l] + 2 * Pi * iO + ORIENTATION * (theta[seq[jl]] - tmp[3]))); if (r[2] < r[0] && fabs(r[2] - r[190]) < 5.0) { tmp[l] += num_of_point[seq[jl]]; break; }  Appendix 5 Source code for automated module } } if (tmp[l] / tmp[2] > tmp[0]) { tmp[0] = tmp[l] / tmp[2]; c[0] = c[l]; d[0] = d[l]; sigma = tmp[3]; } } } } } } tmp[4] = log(r[100]) / c[0] + Pi; tmp[0] = r[100]; for (tmp[0] = 0.0; tmp[0] < tmp[4]; tmp[0] += 0.5 / r[l]) { r[l] = exp(c[0]*tmp[0]); il = xo + r[l] * cos(sigma + ORIENTATION * (tmp[0] - d[0])); j l = yo + r[l] * sin(sigma + ORIENTATION * (tmp[0] - d[0])); pr_put(new_image, il, j 1, 1); } pr_dump(new_image, fpo, NULL, RT_STANDARD, 1); prclose(origimage); pr_close(new_image); pr_close(screen[0]); pr_close(screen[ 1 ]); system("stime"); } 9. ribbedform.c #include "auto.h" void process_ribbed_form() { register int  i, j , k;  /* coiling curves are nearly normal to radius vectors */ confirm_coiling_curve(); /* adjacent ribs should have large overlap along x or y direction */ confirmribbyoverlapQ;  358  Appendix 5 Source code for automated module /* divide into 12 sectors around coiling axis */ analysis_by_sector(); /* remove small ribs located within Pi/10 of big ribs */ remove_small_rib(); confine_coiling_curveO; simulate_morph(); } /* coiling curves are nearly normal to radius vectors (<75) */ static void confirm_coiling_curve(); { register int i, j , x[5], y[5]; double r[5], sigma[2], w; for (i = 1; i < num_of_seg; i++) if(label[i]!=RIB){ j = 0; x[l] = (newseg[seq[i]] - l)->x; y[l] = (newsegfseqfijj - l)->y; x[2] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->x; y[2] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->y; r[l]=D(xo,yo,x[l],y[l]); r[2]=D(xo,yo,x[2],y[2]); sigma[0] = atan2((doubIe) y[l] - yo, (double) x[l] - xo); sigma[0] = POSITIVE(sigma[0]); sigma[l] = atan2((double) y[2] - yo, (double) x[2] - xo); sigma[l] = POSITIVE(sigma[l]); sigma[0] = fabs(sigma[l] - sigma[0]); sigma[0] = LESSPI(sigma[0]); w = fabs(log(r[2] / r[l])) / sigma[0]; /* expansion rate */ if(w<l/tan(75*Pi/180)){ label[i] = COILING; x[2] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->x; y[2] = (newseg[seq[i]J - num_of_point[seq[i]] / 2)->y; sigma[0] = atan2((double) y[2] - yo, (double) x[2] - xo); theta[seq[i]] = POSITIVE(sigma[0]); } }  359  Appendix 5 Source code for automated module  360  /* adjacent ribs should have large overlap along x or y direction */ static void confirm_rib_by_overlap(); { register int i, j , x[5], y[5]; register int numlap;/* number of ribs that overlap with the * current rib */ double delta; double d[100];/* distance between ribs */ for (i = 1; i < num_of_seg; i++) if(label[i] = RIB){ x[l] = (newseg[seq[i]] - l)->x; y[l] = (newseg[seq[f|] - l)->y; x[2] = (newseg[seq[i]] - num_of_point[seq[i]] - l)->x; y[2] = (newseg[seq[i]] - num_of_point[seq[i]] - l)->y; num_lap= 1; /*  * the length of each rib should be consistent with * its neighboring ribs */  for (j = i + 1; j < num_of_seg; j++) if (num_of_point[seqO]] > 0.4 * num_of_point[seq[i]] && labelfj] = RTB){ delta = fabs(theta[seq[i]] - theta[seq[j]]); delta = LESSPI(delta); if (delta < P i / 10) { x[3] = (newseg[seq[j]] - l)->x; y[3] = (newseg[seq[flj - l)->y; x[4] = (newseg[seq[j]] - num_of_point[seq[j]] - l)->x; y[4] = (newseg[seq(j]] - num_of_point[seq[j]] - l)->y; if (abs(y[4] - y[3]) <= abs(x[4] - x[3]) / 10) d[num_lap] = y[l] - y[3]; /* distance between *the two ribs */ else d[num_lap] = (x[l] - x[3] - (x[4] - x[3]) * (y[l] y[3]) / (y[4] - y[3])) * (y[2] - y[l]) / D(x[l], y[l], x[2], y[2]); if (abs(d[num_lap]) < 2 * num_of_point[seq[j]]) { if (abs(y[2] - y[l]) > abs(x[2] - x[l]) && overlap(y[l], y[2], y[3], y[4]) > 0.4) num_lap-H-;  Appendix 5 Source code for automated module else if (abs(y[2] - y[l]) <= abs(x[2] - x[l]) && overlap(x[l], x[2], x[3], x[4]) > 0.4) num_lap++; } } } if (numlap < 4) /* doesn't get enough support */ label[i] = UNKNOWN; } } /* find the farthest and the second farthest ribs in each of the 12 sectors */ static void analysis_by_sector() { register int i, j , x[5], y[5]; double tmp[2]; for (i = 1; i < num_of_seg; i++) if (labelfi] = RIB || labelfi] = UNKNOWN) { x[0] = (newseg[seq[i]] - l)->x; y[0] = (newseg[seq[i]j - l)->y; x[l] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->x; y[l] = (newseg[seq[i]] - 1 - num_of_point[seq[i]])->y; tmp[0]=D(xo,yo,x[0],y[0]); tmp[l]=D(xo,yo,x[l],y[l]); if (tmp[0] > tmp[l]) { r[2*i]=tmp[0]; r [ 2 * i - l ] = tmp[l]; } else { r[2*i]=tmp[0]; r [ 2 * i - l ] = tmp[l]; } } for(i = 0 ; i < 100;i++){ repp] = 0; ox[i] = 0.0; } j = 0; for (i = 1; i < num_of_seg; i++) if(label[i] = -l || label[i] > 0) { tmp[0] += num_of_point[seq[i]]; tmp[l]+=r[2*i-l]; if(j>6)  361  Appendix 5 Source code for automated module  362  break; } tmp[0] /= j ; ribToaxis /= j ;  /* tha average length of the six longest rib * segments */ /* tha average distance of the six longest * rib segments from coiling axis */  j = tmp[0]/4; tmp[0] = Pi/6.0; for (i = 1; i < num_of_seg; i++) if «label[i] == RIB || label[i] = UNKNOWN) && num_ofjpoint[seq[i]] > j) { k = theta[seq[i]] / tmp[0] + 1; if (r[2 * i] > ox[k]) ox[k] = r[2 * i]; } for (i = 1; i < num_of_seg; i++) if ((label[i] = -1 || label[i] > 0) && num_of_point[seq[i]] > j) { k = theta[seq[i]] / tmp[0]; if (r[2 * i] > ox[20 + k] && r[2 * i] < ox[k]) { ox[20 + k] = r[2 * i]; rep[k] = i; } } } static void remove_small_rib() { register int double  i, j , k, big, rt, It; tmp[2];  for (i = 0; i < 12; i++) if (ox[20 + i] > 0.0) { k = (i + 1< 12) ? i + 1 : i + 1 - 12; if (ox[20 + big] > 0.0) { tmp[l] = fabs(theta[seq[rep[i]]] - theta[seq[rep[big]]]); if (tmp[l] < Pi / 10.0 || tmp[l] > 2 * Pi - Pi / 12.0) { if (ox[20 + i] < ox[20 + big]) ox[20 + i] = 0.0; else ox[20 + big] = 0.0; } } } tmp[l] = ox[20 + 0]; big = 0; for(i= l ; i < 12; i++)  Appendix 5 Source code for automated module  363  if(ox[20 + i]>tmp[l]){ tmp[l] = ox[20 + i]; big = i; } /* big is Big rib */ f o r ( i = l ; i < 12;i++){ rt = (big + i < 12) ? big + i: big + i - 12; if(rep[rt]) break; } /* Big rib's right neighbour */ for(i=l;i<12;i++){ It = (big - i < 0) ? 12 + big - i: big - i; if(rep[lt]) break; } /* Big rib's left neighbour */ /*  * if a rib candidate is closer to coiling axis then both its left * and right ribs, it should be removed */  for (i = 0; i < 12; i++) if(rep[i]&&i!=rt&&i!=lt){ for(j = l;j<12;j++){ k = ( i + j < 1 2 ) ? i + j : i + j - 12; if(rep[k]) break; } for(j = l;j<12;j++){ k = (i-j<0)?12 + i - j : i - j ; if(rep[k]) break; } if (ox[20 + i] < ox[20 + k] && ox[20 + i] < ox[20 + k]) ox[20 + i] = 0.0; } tmp[0]=tmp[l] = 0; for(i = 0 ; i < 12; i++) if (ox[20 + i] > 0.0 && i != big) for(j = l;j<12;j++){ rt = ( i + j < 1 2 ) ? i + j : i + j - 12; if(ox[20 + rt]>0.0){ delta = theta[seq[rep[rt]]] - theta[seq[rep[i]]]; delta = POSITIVE(delta); if (ox[20 + rt] < ox[20 + i] && ox[20 + rt] > ox[20 + i] / exp(0.4 * delta)) tmp[0] += ox[20 + i];  Appendix 5 Source code for automated module  364  else if (ox[20 + rt] > ox[20 + i] && ox[20 + rt] < ox[20 + i] * exp(0.4 * tmp[l])) tmp[l]+=ox[20 + i]; break; } } if(tmp[0]>tmp[l]){ ORIENTATION = 1;/* right-lateral */ forO = i ; j < i i ; j + + ) { rt = (big - j < 0) ? 12 + big - j : big - j ; if (ox[20 + rt] > 0.0) { delta = theta[seq[rep[big]]] - theta[seq[rep[rt]]]; delta = POSITIVE(delta); if (ox[20 + rt] > ribToaxis * exp(0.4 * delta)) ox[20 + rt] = 0.0; else break; } } for (i = 0; i < 12; i++) if (ox[20 + i] > 0.0 && i != rt) { for0 = l ; j < 1 2 ; j + + ) { lt = ( i + j < 1 2 ) ? i + j : i + j - 12; if (ox[20 + It] > 0.0) break; } delta = theta[seq[rep[lt]]] - theta[seq[rep[i]]]; delta = POSITIVE(delta); if(ox[20 + i]<ox[20 + lt]) ox[20 + i] = 0.0; else if (ox[20 + It] < ox[20 + i] / exp(0.4 * delta)) ox[20 + It] = 0.0; } } else { ORIENTATION = -1;/* left-lateral */ for(j = l ; j < l l ; j + + ) { rt = (big + j < 12) ? big + j : big + j -12; if (ox[20 + rt] > 0.0) { delta = theta[seq[rep[rt]]] - theta[seq[rep[big]]]; delta = POSITIVE(delta); if (r[2 * rep[rt]] > ribToaxis * exp(0.4 * delta)) ox[20 + rt] = 0.0; else break; }  Appendix 5 Source code for automated module  365  } for (i = 0; i < 12; i++) if (ox[20 + i] > 0.0 && i != it) { for(j=l;j<12;j++){ lt = ( i - j < 0 ) ? 1 2 + i - j : i - j ; if (ox[20 + It] > 0.0) break; } delta = theta[seq[rep[i]]] - theta[seq[rep[lt]]]; delta = POSITIVE(delta); if (ox[20 + i] < ox[20 + It]) ox[20 + i] = 0.0; else if (ox[20 + It] < ox[20 + i] / exp(0.4 * delta)) ox[20 + It] = 0.0; } } } static void confine_coiling_curve() { register int i, j , k, iO, x[l 10], y[l 10]; double tmp[5]; tmp[ 1 ] = Pi * imageSize / 100.0; for (iO = 0; iO < 12; i0++) if(ox[20 + i0]>0.0){ tmp[3] = tmp[4] = imageSize / 15; k = 0; x[19] = (newseg[seq[rep[iO]]] - l)->x; y[19] = (newseg[seq[rep[i0]]j - l)->y; x[20 + iO] = (newseg[seq[rep[iO]]] - num_of_point[seq[rep[iO]]] - l)->x; y[20 + iO] = (newseg[seq[rep[iO]]] - num_of_point[seq[rep[iO]]] - l)->y; if (D(xo, yo, x[19], y[19]) > D(xo, yo, x[20 + iO], y[20 + iO])) { x[20 + i0]=x[19]; y[20 + i0]=y[19]; } for (i = 1; i < num_of_seg; i++) if (label[i] = -2 && num_of_point[seq[i]] > tmp[l]) { x[100] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->x; y[100] = (newseg[seq[i]] - num_of_point[seq[i]] / 2)->y; ox[100] = D(xo, yo, x[100], y[100]); tmp[2] = fabs(theta[seq[rep[iO]]] - theta[seq[i]]); tmp[2] = LESSPI(tmp[2]); ox[101] = imageSize/ 15; if (ox[100] > ox[20 + iO] / 2.0 && tmp[2] < Pi / 4.0)  Appendix 5 Source code for automated module  366  for (jj = 0; j <= num_of_point[seq[i]]; j++) { x[100] = (newseg[seq[i]] - j - l)->x; y[100] = (newseg[seq[i]] - j - l)->y; ox[99] = D(xo, yo, x[100], y[100]); if(ox[99]>ox[20 + i0]){ ox[100] = D(x[20 + iO], y[20 + iO], x[100], y[100]); if(ox[100]<ox[101]){ ox[101] = ox[100]; x[101] = x[100]; y[101] = y[100]; } } } if(ox[101]<tmp[3]){ tmp[3] = ox[101]; x[102] = x[101]; y[102] = y[101]; rep[20 + iO] = i; }elseif(ox[101]<tmp[4]){ tmp[4] = ox[101]; x[103] = x[101]; y[103] = y[101]; k = i; } } if (k > 0) { if (tmp[4] * num_of_point[seq[rep[20 + iO]]] < tmp[3] * num_of_point[seq[k]]) { rep[20 + iO] = k; x[20 + iO] = x[103]; y[20 + i0]=y[103]; } else if (rep[20 + iO] > 0) { x[20 + i0] = x[102]; y[20 + i0] = y[102]; } } else if (rep[20 + iO] > 0) { x[20 + i0] = x[102]; y[20 + i0] = y[102]; } } } /*  * This program was written several years ago, typical spaghetti code, very * difficult to read. It may need a few weeks to clean it up  Appendix 5 Source code for automated module  367  */  static void simulate_morph() { int x[200], y[200], pos[1000], n[200]; int varl, var2; float sigma, angle, sclefact, xx[2][MAXNUM], yy[2][MAXNUM]; float a[200], b[200], c[200], d[200]; /* morph parameters */ float rfMAXNUM], ox[MAXNUM], oy[MAXNUM]; float tmp[6]; register i, j , il,jl, iOJO, i2; for (i = 0; i < 12; i++) if(ox[20 + i]>0.0){ ox[20 + i] = D(xo, yo, x[20 + i], y[20 + i]); oy[20 + i] = atan2((double) y[20 + i] - yo, (double) x[20 + i] - xo); oy[20 + i] = POSITIVE(oy[20 + i]); } ox[l] = tmp[2] = ox[20 + n[3]]; oy[l]=tmp[l] = oy[20 + n[3]]; x[l]=x[20 + n[3]]; y[l]=y[20 + n[3]]; i0=l; for (i = 1; i < 12; i++) { if(ORTENTATION>0) n[4] = (n[3] + i < 12) ? n[3] + i : n[3] + i - 12; else n[4] = (n[3] - i < 0) ? 12 + n[3] - i : n[3] - i; if (ox[20 + n[4]] > 0.0) { if(ORIENTATION>0) tmp[3] = oy[20 + n[4]] - tmp[l]; else tmp[3] = tmp[l] - oy[20 + n[4]]; tmp[3] = POSITIVE(tmp[3]); tmp[4] = log(tmp[2] / ox[20 + n[4]]); if (tmp[4] < 0.05 * tmp[3] || tmp[4] > 0.4 * tmp[3]) ox[20 + n[4]] = 0.0; else if (iO > 2 && (tmp[4] > 3.0 * tmp[3] * a[i0 - 1] || tmp[4] < tmp[3] * a[i0-l]/3.0)) ox[20 + n[4]] = 0.0; else { a[i0] = tmp[4] / tmp[3]; i0++; x[i0] = x[20 + n[4]]; y[i0] = y[20 + n[4]];  Appendix 5 Source code for automated module  368  tmp[2] = ox[iO] = ox[20 + n[4]]; tmp[l] = oy[i0] = oy[20 + n[4]]; } } } a[0] = tmp[4] = 0.0; b[100] = ox[l]; i0++; for (i = 2; i < iO; i++) { tmp[l] = log(ox[i])/a[i-l]; tmp[2]=log(ox[i-l])/a[i-l]; tmp[3] = oy[i - 1]; if(i = 2) c[100] = oy[0] = tmp[3]; a[99 + i] = a[i - 1]; b[99 + i] = ox[i]; c[99 + i] = oy[i]; tmp[4] += tmp[2] - tmp[l]; a[0]+=a[i-l]*(tmp[2]-tmp[l]); for (tmp[0] = tmp[l]; tmp[0] <= tmp[2]; tmp[0] += 0.5 / ox[i - 1]) { r[0] = exp(a[i - 1] * tmp[0]); i2 = xo + r[0] * cos(tmp[3] - ORIENTATION * (tmp[0] - tmp[2])); jO = yo + r[0] * sin(tmp[3] - ORIENTATION * (tmp[0] - tmp[2])); pr_put(new_image, i2, jO, 1); } printf("i=%d k=%f \n", i - 1, a[i - 1]); } a[0]/=tmp[4]; var2 = i 0 - 1; for (i = 1; i < num_of_seg - 1 ; i++) if (labelp] > 0 && labelp] != 2) { rep[100] = i; jl = 101; for (j = i + 1; j < num_of_seg; j++) if (labelfj] > 0) { tmp[3] = (r[2 * i] - r[2 * i - 1] > 120.0) ? (r[2 * i] - r[2 * i 1])/20.0: 6.0; tmp[4] = fabs(r[2 * j] - r[2 * i]); if(tmp[4]<tmp[3]){ tmp[3] = fabs(theta[seq[i]] - theta[seq[j]]); tmp[3] = LESSPI(tmp[3]); if(tmp[3]<Pi/10.0) rep01++]=j; } } if (jl > 102)  Appendix 5 Source code for automated module  369  for0 = 100;j<jl;j++) label[rep[j]] = 2; } for (i = 1; i < num_of_seg - 1; i++) if (label[i] > 0 && label[i] != 3) { rep[l 00] = i; j l = 101; for (j = i + 1; j < num_of_seg; j++) if (label[j] > 0) { tmp[3] = (r[2 * i] - r[2 * i - 1] > 120.0) ? (r[2 * i] - r[2 * i 1])/20.0: 6.0; tmp[4] = fabs(r[2 * j - 1] - r[2 * i - 1]); if(tmp[4]<tmp[3]){ tmp[3] = fabs(theta[seq[i]] - theta[seq[j]]); tmp[3] = LESSPI(tmp[3]); if(tmp[3]<Pi/10.0) rep[jl++]=j; } } if (jl > 102) { for(j=100;j<jl;j++) if (label[repG]] = 2) label[rep[j]] = 4; else label[rep0]] = 3; } } j = 0; for (i = 1; i < num_of_seg; i++) if (label[i] > 2) { ox[100+j] = r [ 2 * i - l ] ; if 0 > 6) break; } for (i = 100; i < 106; i++) for(j = i + l ; j < 1 0 7 ; j + + ) if (ox[i] < ox[j]) { ox[107] = ox[i]; ox[i] = ox[j]; oxjj] = ox[107];  } ox[107] = 0.0; for (i = 101; i < 106; i++) ox[107]+=ox[i]; ox[107] /= 5.0;  Appendix 5 Source code for automated module  370  tmp[0] = ox[107] + (ox[l] - ox[107]) / 15.0; n[4]=n[5] = 0; for (i = 1; i < num_of_seg; i++) if ((Iabelp] = 3 || label[i] == 4) && r[2 * i - 1] < ox[107]) { n[4]++; for (j = 1; j < num_of_seg; j++) if (labelfj] > 0 && r[2 * i - 1] > r[2 * j] && r[2 * i - 1] - r[2 * j] < r[2 * i] - r[2 * i - 1]) { tmp[0] = fabs(theta[seq[i]] - theta[seq[j]]); tmp[0] = (tmp[0] > 1.8 * Pi) ? 2 * Pi - tmp[0] : tmp[0]; if(tmp[0]<Pi/18.0) { n[5]++; break; } } } if (n[5] > 0.2 * n[4]) { tmp[0] = 0.0; tmpfl] = 2 * Pi * imageSize /100.0; for (i = 1; i < 500; i++) { rep[i] = 0; ox[i] = 1000.0; } i0=l; for (i = 1; i < num_of_seg; i++) if (label[i] = 2 || Iabelp] = 4) { tmp[2]=Pi/18; for (j = 1; j < num_of_seg; j++) if (labelO] > 0 && r[2 * j - 1] > r[2 * i] && r[2 * j - 1] r[2 * i] < r[2 * i] - r[2 * i - 1]) { tmp[0] = fabs(theta[seq[i]] - theta[seq[j]]); tmp[0] = (tmp[0] > 1.8 * Pi) ? 2 * Pi - tmp[0] : tmp[0]; if(tmp[0]<tmp[2]) { tmp[2] = tmp[0]; rep[2*i0]=j; ox[i0] = r[2 * j - l ] - r [ 2 * i ] ; } } i f ( o x [ i 0 ] < r [ 2 * i ] - r [ 2 * i - 1]) { rep[2 * i 0 - l] = i; i0++; } } for (i = 1; i < num_of_seg; i++) if(label[i]==3||label[i]==4) {  Appendix 5 Source code for automated module  371  tmp[2]=Pi/18; for (j = 1; j < num_of_seg; j++) if (label[j] > 0 && r[2 * i - 1] > r[2 * j] && r[2 * i - 1] r[2*j]<r[2*i]-r[2*i-l]){ tmp[0] = fabs(theta[seq[i]] - theta[seq[j]]); tmp[0] = (tmp[0] > 1.8 * Pi) ? 2 * Pi - tmp[0] : tmp[0]; if(tmp[0]<tmp[2]){ tmp[2] = tmp[0]; rep[2*i0]=j; ox[i0] = r [ 2 * i - l ] - r [ 2 * j ] ; } } if(ox[i0]<r[2*i]-r[2*i-l]){ r e p [ 2 * i 0 - l ] = i; iO-H-; }  } f o r ( i = l ; i < 2 * i 0 - l;i++) pos[i] = i; for(i= l ; i < i 0 - l;i++) forO' = i + l ; j < i O ; j + + ) if (ox[i] > ox[j]) { ox[0] = ox[i]; oxfi] = ox[j]; ox[j] = ox[0]; pos[0] = pos[i]; pos[i] = pos[j]; pos[j] = pos[0]; } /* remove false rib-between points */ for(i= l ; i < i 0 ; i + + ) { tmp[3] = theta[seq[rep[2 * pos[i]]]]; if (r[2 * rep[2 * posp]]] > r[2 * rep[2 * pos[i] - 1]]) tmp[4] = (r[2 * rep[2 * posp] - 1]] + r[2 * rep[2 * pos[i]] - 1]) / 2.0; else tmp[4] = (r[2 * rep[2 * pos[i]]] + r[2 * rep[2 * pos[i] - 1] - 1]) / 2.0; tmp[l] = tmp[2] = 0.0; for (jj = 1; j < num_of_seg; j++) if (labelQ] > 1) { tmp[0] = fabs(theta[seq[j]] - tmp[3]); tmp[0] = LESSPI(tmp[0]); if(tmp[0]<Pi/4.0){  Appendix 5 Source code for automated module  372  if (r[2 * j] > tmp[4] && r[2 * j - 1] < tmp[4] && tmp[4] r [ 2 * j - l ] > 0 . 1 0 * ( r [ 2 * j ] - r [ 2 * j - 1]) && tmp[4] - r[2 * j - 1] < 0.90 * (r[2 * j] - r[2 * j - 1])) tmp[2]+=r[2*j]-r[2*j-l]; else if (fabs(r[2 * j] - tmp[4]) < 0.1 * (r[2 * j] - r[2 * j - 1]) || fabs(r[2 * j - 1] - tmp[4]) < 0.1 * (r[2 * j] - r[2 * j -1])) tmp[l]+=r[2*j]-r[2*j-l]; } } if(tmp[2]>=tmp[l]/2.0) ox[i] = 1000.0; } i2=l; n P ] = 1; /* number of control points-xx-yy */ for(i= l;i<i0;i++) if (ox[i] < 1000.0) { j0 = 0; tmp[3] = yy[0][n[3]] = (theta[seq[rep[2 * pos[i]]]] + theta[seq[rep[2 * pos[i]-l]]])/2.0; if (r[2 * rep[2 * pos[i]]] > r[2 * rep[2 * pos[i] - 1]]) { xx[0][n[3]] = r[2 * rep[2 * pos[i] - 1]]; xx[l][n[3]] = r [ 2 * r e p [ 2 * p o s [ i ] ] - l ] ; } else { xx[0][n[3]] = r[2 * rep[2 * pos[i]]]; xx[l][n[3]] = r[2 * rep[2 * pos[i] - 1] - 1]; } tmp[4] = (xx[0][n[3]] + xx[l][n[3]]) / 2.0; n[3]++; tmp[0] = fabs(tmp[3] - oy[0]); tmp[0] = LESSPI(tmp[0]); if(tmp[0]<Pi/4.0) tmp[l]=tmp[0]; else { if (ORIENTATION > 0) { if(tmp[3]>oy[0]) tmp[l] = tmp[3]-oy[0]; else tmp[l] = 2 * Pi - oy[0] + tmp[3]; } else if (ORIENTATION < 0) { if(tmp[3]<oy[0]) tmp[l] = oy[0]-tmp[3]; else tmp[l] = 2 * Pi - tmp[3] + O y[0]; } tmp[0] = tmp[0] / exp(a[0] * tmp[l] / 2.0);  Appendix 5 Source code for automated module  373  } if (tmp[4] < tmp[0] && i2 = 1) JO-1; else if (tmp[4] < tmp[0]) { J0=1; for0=l;j<i2;j++){ tmp[0] = fabs(tmp[3] - oy[j]); tmp[0] = LESSPI(tmp[0]); if (tmp[0] < Pi / 6.0 && fabs(log(oy[100 + j] / tmp[4])) < exp(0.3)) { j0 = 0; break; } } } if GO) { n[100 + 2 * i2] = rep[2 * pos[i]]; n[100 + 2 * i2 -1] = rep[2 * pos[i] - 1]; x[i2] = xo + tmp[4] * cos(tmp[3]); y[i2] = yo + tmp[4] * sin(tmp[3]); oy[i2] = tmp[3]; ox[i2] = ox[i]; oy[i2 + 100] = tmp[4]; i2++; } if(i2>10) break; else if (i2 > 5 && ox[i] > imageSize / 20.0) break; } tmp[0] = 1000.0; for (i = 1; i < num_of_seg; i++) if (labelfi] > 2 && r[2 * i - 1] < tmp[0]) { tmp[0] = r[2 * i - 1 ] ; n[100 + 2 * i 2 - l ] = i; } x[100] = (newseg[seq[n[100 + 2 * i2 - 1]]] - l)->x; y[100] = (newseg[seq[n[100 + 2 * i2 - 1]]] - l)->y; x[101] = (newseg[seq[n[100 + 2 * i2 - 1]]] - num_of_point[seq[n[100 + 2 * i2 - 1]]] l)->x; y[101] = (newseg[seq[n[100 + 2 * i2 - 1]]] - num_of_point[seq[n[100 + 2 * i2 - 1]]] i)->y; oy[i2] = theta[seq[n[100 + 2 * i2 - 1]]]; ox[i2] = imageSize / 60; tmp[l] = D(xo, yo, x[100], y[100]); tmp[2] = D(xo, yo, x[101], y[101]);  Appendix 5 Source code for automated module  374  if(tmp[l]<tmp[2]){ x[i2] = x[100]; y[i2] = y[100]; oy[i2+100] = tmp[l]-3.0; } else { x[i2]=x[101]; y[i2] = y[101]; oy[i2+100] = tmp[2]-3.0; } for(i = l;i<=i2;i++) pos[i] = i; for(i=l;i<i2;i++) for(j = i + l ; j < = i 2 ; j + + ) if (ox[i] > ox[j]) { ox[0] = ox[i]; ox[i] = ox[j]; oxjj] = ox[0]; pos[0] = pos[i]; posji] = pos[j]; pos[j] = pos[0]; } d[62] = ox[i2 - 1]; f o r ( i = l ; i < i 2 - 1; i++) if (ox[i] < 100.0) for(j = i + l ; j < i 2 ; j + + ) if (ox[j] < 100.0) { tmp[l] = oy[100 + pos[i]]; tmp[2] = oy[100 + posjj]]; if(tmp[l]>tmp[2]){ tmp[0] = tmp[l]; tmp[l] = tmp[2]; tmp[2] = tmp; tmp[0] = oy[pos[i]]; tmp[5] = oy[pos[j]]; } else { tmp[0] = oy[pos[j]]; tmp[5] = oy[pos[i]]; d[60]=1.0; d[61] = 0.0; tmp[0] = 0.0; for (iO = -4; iO < 5; i0++) { d[50 + iO] = log(tmp[2] / tmp[l]) / (2 * Pi * iO ORIENTATION * (tmp[0] - tmp[5])); if (d[50 + iO] < 0.3 && d[50 + iO] > 0.05) { n[4] = n[5] = n [ 6 ] = l ; for(il = l ; i l <n[3];il++)  Appendix 5 Source code for automated module  375  if (!(xx[0][il] > tmp[2] || xx[l][il] < tmp[l])) { for(jl=0;jl<5;jl++){ tmp[3] = 2 * P i * j l ORIENTATION * (tmp[0] - yy[0][il]); tmp[4] = tmp[2] / exp(d[50 + iO] * tmp[3]); if (tmp[4] < tmp[2] && tmp[4] > tmpfl] && tmp[4] > xx[0][il] && tmp[4] < xx[l][il]) { n[4]++; break; } if(tmp[4]<tmp[l]) break; } } for (il = 1; il < n u m o f s e g ; il++) if (labelfil] > 0 && !(r[2 * il - 1] > tmp[2] && r[2 *il]<tmp[l])){ r[0] = (r[2 * il] - r[2 * il -1]) / 8.0; for(jl=0;jl<5;jl-H-){ tmp[3] = 2 * Pi * j l - ORIENTATION * (tmp[0] - theta[seq[il]]); tmp[4] = tmp[2] / exp(d[50 + iO] * tmp[3]); if (tmp[4] > tmp[l] && tmp[4] < tmp[2]) { tmp[3] = MIN(fabs(tmp[4] - r[2 * il]), fabs(tmp[4] - r[2 * il -1])); if (tmp[4] > r[2 * il - 1] + r[0] && tmp[4] < r[2 * il] r[0]){ n[5] += num_of_point[seq[il]]; break; }elseif(tmp[3]<d[62]) n[6] += num_of_point[seq[il]]; } if(tmp[4]<tmp[l]) break; } } tmp[3] = (float) n[6]/n[5]; if (tmp[3] > d[61] || tmp[3] = d[61] && fabs(d[50 + iO] - a[0]) < d[60]) { d[60] = fabs(d[50 + iO] - a[0]); tmp[0] = d[50 + iO]; d[61] = tmp[3]; } } } if (d[60] > 0.4 || tmp[0] > 0.3)  Appendix 5 Source code for automated module  376  ox[j] = 100.0; else { for (iO = j + 1; iO <= i2; i0++) if (oy[100 + pos[i0]] > tmp[l] && oy[100 + pos[i0]] < tmp[2]) { if (r[2 * n[100 + 2 * pos[i0]]] > r[2 * n[100 + 2 * pos[i0] - 1]]) { tmp[3] = r[2 * n[100 + 2 * pos[i0] - 1]]; tmp[5] = r[2 * n[100 + 2 * pos[i0]] - 1]; } else { tmp[3] = r[2 * n[100 + 2 * pos[i0]]]; tmp[5] = r[2 * n[100 + 2 * pos[i0] - 1] - 1]; } forOO = -4;jO<5;jO++){ tmp[0] = 2 * Pi * jO - ORIENTATION * (oy[pos[i]] oy[pos[i0]]); tmp[0] = oy[100 + pos[i]] * exp(tmp[0] * tmp); if (tmp[0] > tmp[3] && tmp[0] < tmp[5]) ox[i0] = 100.0; } } } } for (i = 101; i <= 100 + i2; i++) pos[i] = i - 100; for(i=l;i<=i2;i++) if (ox[i] = 100.0) pos[100 + pos[i]] = 0; for(i= l ; i < i 2 ; i + + ) if(pos[100 + i]>0) for0 = i + l ; j < = i 2 ; j + + ) if(pos[100+j]>0) if (oy[pos[100 + i] + 100] < oy[pos[100 + j] + 100]) { pos[100] = pos[100 + i]; pos[100 + i] = pos[100+j]; pos[100+j] = pos[100]; }  jo = i; for(i= 101;i<100 + i2;i++) if(pos[i]>0){ for (j = i + 1; j <= 100 + i2; j++) if(posD]>0){ i0=j; break; } tmp[3] = oy[100 + pos[i]]; tmp[4] = oy[100 + pos[i0]]; a[j0] = 0.0;  Appendix 5 Source code for automated module  377  d[61] = 0.0; d[60] = 1.0; for(j = 0;j<5;j++){ d[50 + j] = log(tmp[3] / tmp[4]) / (2 * Pi * j - ORIENTATION * (oy[pos[i]] - oy[pos[iO]])); if (d[50 + j] < 0.3 && d[50 + j] > 0.05) { n[4] = n[5]=n[6] = l; for(il = l;il<n[3];il-H-) if (!(xx[0][il] > tmp[3] || xx[L][il] < tmp[4])) { for01=0;jl<5;jl-f+){ tmp[l] = 2 * P i * j l ORIENTATION * (oy[pos[i]] yy[0][ii]); tmp[2] = tmp[3] / exp(d[50 + j] * tmp[l]); if (tmp[2] > tmp[4] && tmp[2] < tmp[3] && tmp[2] > xx[0][il] && tmp[2]<xx[l][il]){ n[4]-H-; break; } if(tmp[2]<tmp[4]) break; } } for (il = 1; il < num_of_seg; il++) if (label[il] > 0 && !(r[2 * il - 1] > tmp[3] && r[2 * il] < tmp[4])) { r[0] = (r[2 * il] - r[2 * il - 1]) / 8.0; for(jl=0;jl<5;jl++){ tmp[l] = 2 * Pi * j l - ORIENTATION * (oy[pos[i]] theta[seq[il]]); tmp[2] = tmp[3] / exp(d[50 + j] * tmp[l]); if (tmp[2] < tmp[3] && tmp[2] > tmp[4]) { tmp[l] = MIN(fabs(tmp[2] - r[2 * il]), fabs(tmp[2] - r[2 * il - 1])); n[6] += num_of_point[seq[il]]; if (tmp[2] > r[2 * il - 1] + r[0] && tmp[2] < r[2 * il] - r[0]) { n[5] += num_of_point[seq[il]]; break; }elseif(tmp[l]<d[62]) n[6] += num_of_point[seq[il]]; } else if (tmp[2] < tmp[4]) break; } } tmp[2] = (float) n[6] / n[5]; if (tmp[2] > d[61] || tmp[2] = d[61] && fabs(d[50 + iO] - a[0]) < d[60]) {  Appendix 5 Source code for automated module  378  d[61] = tmp[2]; d[60] = fabs(d[50+j]-a[0]); aD'0] = d[50+j]; } } } if(aOO]>0.05){ tmp[l] = log(tmp[4])/aOO]; tmp[2] = log(tmp[3])/a[j0]; >f 00 — 1) { b[0]=tmp[3]; c[0] = oy[pos[i]]; } bB0] = tmp[4]; c[j0] = oy[pos[i0]]; tmp[3] = oy[pos[i]]; for (tmp[0] = tmp[2]; tmp[0] >= tmp[l]; tmp[0] -= 0.5 / r[0]) { r[0] = exp(a[j0] * tmp[0]); il = xo + r[0] * cos(tmp[3] - ORIENTATION * (tmp[0] - tmp[2])); j l = yo + r[0] * sin(tmp[3] - ORIENTATION * (tmp[0] - tmp[2])); pr_put(new_image, i 1, j 1, 1); } J0++; }  } varl =j0; b[varl - 1] /= exp(a[varl -1] * 2 * Pi); } else { for (i = 1; i < 100; i++) repp] = 0; i0=l; cl = l; ox[0] = tmp[0]; tmp[0] = 0.0; while (cl) { ox[i0] = ox[0]; for (i = 1; i < numofseg; i++) if ((label[i] = 3 || label[i] = 4) && r[2 * i - 1] < ox[i0]) { if (iO = 1) J0=1; elseif(i0 = 2){ tmp[0] = fabs(theta[seq[i]] - theta[seq[rep[2 * (iO - 1) i]]]); tmp[0] = LESSPI(tmp[0]); tmp[4] = fabs(log(r[2 * i - 1] / ox[i0 - 1])); if (tmp[0] > Pi / 6.0 && tmp[4] > 0.05 * tmp[0])  Appendix 5 Source code for automated module  379  jo=i; else j0 = 0; } else if (iO > 2) { tmp[4] = fabs(log(r[2 * i - 1] / ox[iO - 1])); if (ORIENTATION < 0) { tmp[0] = LARGER(theta[seq[i]], theta[seq[rep[2 * (iO - 1) - i]]]); if (tmp[4] < 0.5 * tmp[0] && tmp[4] > 0.05 * tmp[0] && theta[seq[i]] > theta[seq[rep[2 * (iO - 1) -1]]] && tmp[0] > Pi / 6.0 && tmp[0] + tmp < 2 * Pi) J0=1; else if (tmp[4] < 0.5 * tmp[0] && tmp[4] > 0.05 * tmp[0] && theta[seq[i]] < theta[seq[rep[2 * (iO - 1 ) - 1]]] && theta[seq[rep[2 * (iO - 1) - 1]]] - theta[seq[i]] < 2 * Pi - Pi / 6.0 && theta[seq[rep[l]]] theta[seq[i]] > Pi / 6.0 && tmp[0] + tmp < 2 * Pi) J0=1; else JO = 0; } else { tmp[0] = LARGER(theta[seq[rep[2 * (iO - 1) - 1]]], theta[seq[i]]); if (tmp[4] < 0.5 * tmp[0] && tmp[4] > 0.05 * tmp[0] && theta[seq[i]] < theta[seq[rep[2 * (iO -1) - 1]]] && tmp[0] > Pi / 6.0 && tmp[0] + tmp < 2 * Pi) J0=1; else if (tmp[4] < 0.5 * tmp[0] && tmp[4] > 0.05 * tmp[0] && theta[seq[i]] > th