Thermoregulation in Neo-Tropical Tree

A thesis submitted to the University of Manchester for the degree of Master of Philosophy in the Faculty of Engineering and Physical Sciences

Submitted on 2015

Francisco Herrerías Azcué

School of Physics and Astronomy

1

2

List of Contents

List of Figures ...... 7 Abstract ...... 11 Publications and Presentations ...... 15 Acknowledgements ...... 17 1 Introduction ...... 19 2 Thermoregulation ...... 21 2.1 Absorbed radiation ...... 22 2.2 Emitted radiation ...... 22 2.3 Conduction ...... 23 2.4 Convection ...... 23 2.5 Evaporative water loss ...... 24 2.6 Metabolism ...... 24 3 Parameters ...... 25 3.1 Environmental ...... 25 3.1.1 Solar Irradiance ...... 26

3.1.2 Surrounding Temperature ...... 27

3.1.3 Wind ...... 27

3.1.4 Relative Humidity ...... 27

3.1.5 Global Position and Time ...... 28

3.2 -Dependant ...... 29 3.2.1 Shape ...... 29

3

3.2.2 Position / Projection ...... 30

3.2.3 Frog Spectra ...... 31

3.2.4 Convection Coefficients ...... 32

3.3 Constants ...... 34 4 Photogrammetry...... 35 4.1 Software ...... 35 4.2 Method ...... 36 4.2.1 Image Acquisition ...... 36

4.2.2 Model Reconstruction ...... 38

4.2.3 Mesh scaling and cleaning ...... 39

4.3 Measurements ...... 40 4.4 Precision ...... 40 4.4.1 Printed 3D Models ...... 40

4.4.1 Known Density Objects ...... 41

5 Frog Surface Areas ...... 43 5.1 Acquired Data ...... 44 5.2 Interpolation from weight ...... 44 5.3 Interpolation from snout-vent length ...... 45 5.4 Surface area comparison ...... 46 6 Measuring the Mass Transfer Coefficient ...... 49 6.1 Theoretical Background ...... 49 6.2 Experimental Method ...... 50 6.3 Models and Instrumentation ...... 51 6.3.1 Agar Models ...... 51

6.3.2 Agar Moulds for Plaster of Paris Models ...... 52

6.3.3 Plaster of Paris Models ...... 52

6.3.4 Instrumentation ...... 53

6.4 Results and Discussion ...... 53 6.5 Conclusion ...... 56 7 Frog Simulator GUI ...... 57 7.1 Solar Irradiance Model ...... 57

4

7.1.1 Air Mass Approach ...... 58

7.1.2 Solar Position Calculator ...... 58

7.1.3 SMARTS Approach ...... 59

7.2 GUI Inputs and Functionality ...... 60 7.2.1 Frog Characteristics ...... 60

7.2.2 Ambient Characteristics ...... 63

7.2.3 Location Characteristics ...... 64

7.3 Outputs ...... 64 7.4 Save and Load ...... 65 8 Simulation Results...... 67 8.1 Extreme Case Scenario ...... 67 8.2 Partially Occluded Frog ...... 69 9 Conclusions ...... 73 Appendix A, Frog Simulator Code ...... 76 Appendix B, Solar Position Code ...... 114 Appendix C, Solar Spectrum Code ...... 116 References ...... 137

Final word count: 33,458

5

6

List of Figures

Figure 1.1 Photographs of craspedopus (Top) and Cruziohyla calcarifer (Bottom), on which the surface area studies were focused...... 20 Figure 2.1 Diagram of the power exchange processes considered in the thermoregulation model. Absorption of solar radiation considers scattered, reflected direct and indirect sunlight, and it can only have a positive sign (going into the frog). Conduction and grey body radiation and convection can take either sign, and although evaporative water loss could too, it usually has a negative sign...... 22 Figure 3.1 Samples of the solar direct (red) and diffuse (blue) spectra at different zenith angles. Note how as the sun goes down (higher zenith angles) the blue end of the spectrum is significantly more attenuated than the infra-red, especially in the direct beam spectrum...... 26

Figure 3.2 Definition of the solar zenith and azimuth angles (휃푧 and 휃푎), used to calculate the solar irradiance and the frogs projected area receiving the direct solar beams...... 28

Figure 3.3 The shape of the frog is approximated as a disc of radius 푟푐, cross sectional areas

퐴푣, and thick-ness ℎ. This is only used for the solar projection and the conduction power exchanges...... 29

Figure 3.4 Definition of the frog’s zenith and azimuth angles (휃푧푓 and 휃푎푓) used to describe its position relative to the sun. The vectors 푛푔, 푛푣, and 푝푛푣 are the normal to the ground, the normal to the frog’s ventral area, and the projection of the latter on the cardinal plane, with north, east, south and west indicated by N, E, S and W respectively...... 30 Figure 3.5 Examples of spectra of frogs with and without the pterorhodin characteristic reflection peak at approximately 700 nm. The dotted and dashed black lines are extreme reference spectra built for a completely black frog, and a black frog that reflects all the near infra-red light...... 32 Figure 4.1 Aerotriangulation process. A sparse cloud of points helps to determine the position from which the photographs were taken...... 35

7

Figure 4.2 Turn-table used while testing different 3D reconstruction software and the possibility of using a rotating frame instead of a rotating camera...... 36 Figure 4.3 Deformities caused by highly reflective surfaces (Top, bicycle light), and objects with plain colours (Bottom, masking tape)...... 37 Figure 4.4 Turn-table used for frog photo sessions. Note that the base is made of wood, providing a textured background...... 37 Figure 4.5 Turn-table with walls, which only allows for the images to be taken from a single height...... 38 Figure 4.6 Top: original rendered model sent to 3D print. Bottom: rendered model of printed frog...... 40 Figure 4.7 Top: processed rendered cylinder. Centre: Deformities found in rendered metal objects before the cleaning process. Bottom: Example of deformities found on frog models due to head movement...... 42 Figure 5.1 Cruziohyla craspedopus in its water conserving posture. Note the flaps on its hind legs...... 43 Figure 5.2 Cruziohyla calcarifer. Note the absence of flaps and the steep angle at the edge in contact with the board...... 43 Figure 5.3 Volume and surface areas plotted against the snout-vent length (top) and weight (bottom). Note the clear overlap between species...... 44 Figure 5.4 Surface areas plotted against the weight of the frog with a power function fit. Note how closely overlapped the fitted lines are...... 45 Figure 5.5 Surface areas plotted against the snout-vent length squared, with a linear function fit. Note how the lines are clearly different...... 45 Figure 5.6 Snout-vent lengths plotted against weight...... 46 Figure 6.1 Top, a model inside the wind tunnel at a 90° position. Bottom, thermal image of a model while in the wind tunnel at a 0° position, showing the expected thermal gradient...... 51 Figure 6.2 Agar model making process...... 52 Figure 6.3 Agar mould making process ...... 52 Figure 6.4 Plaster of Paris model making process...... 52

Figure 6.5 Mass transfer coefficient (ℎ푑) plotted against the wind velocity with various fitted curves. Note how R2 is very similar in all of them...... 53

Figure 6.6 Mass transfer coefficient (ℎ푑) plotted against the wind velocity at which it was obtained. From the top left and clockwise, the plots are for the models for the adult C. calcarifer, then the juvenile C. calcarifer, then the bigger C. craspedopus and finally together

8 the smaller C. craspedopus and the Hemisphere. Note the clear increase in ℎ푑 with increasing wind speed...... 54 Figure 6.7 Mass transfer coefficient vs the square root of the wind speed. Note that all the intercepts with 푣 = 0 m/s are negative...... 55 Figure 6.8 Mass transfer coefficient plotted against the wind speed. Each line is for a different frog model. Note the variation in the intercept point...... 55 Figure 6.9 Mass transfer coefficient plotted against the wind speed to the power of 0.39. .... 56 Figure 7.1 Screen capture of the Frog Simulator. The Inputs section can be seen on top, and the Outputs section at the bottom...... 60 Figure 7.2 Top: Screen capture of the Confident Spectrum Clipping prompt...... 61 Figure 7.3 Screen capture of the Frog Characteristics section...... 61 Figure 7.4 Screen capture of the Ambient Characteristics section...... 63 Figure 7.5 Screen capture of the Location Characteristics section...... 64 Figure 7.6 Screen capture of the Outputs section. Note the two numerical outputs at the bottom...... 64 Figure 8.1 Ambient profile used in the simulations. The relative humidity was divided by a factor of 10 so that it could be shown next to the wind speed...... 67 Figure 8.2 Power contributions (left axis), and the resulting equilibrium frog temperature (right axis) plotted against time. At the top, the plot corresponds to Cruziohyla craspedopus (with pterorhodin) sitting flat and with no cover. At the bottom, the plot is for Hyla cinerea (without pterorhodin) in the same scenario. Note the different heights...... 68 Figure 8.3 Weight of the frog plotted against the time of day, assuming water evaporation is the only source of change...... 69 Figure 8.4 Power contributions (left axis), and the resulting equilibrium frog temperature (right axis) plotted against time. The plot corresponds to Cruziohyla calcarifer (with pterorhodin) sitting on a leaf with a 65% shade, zenith angle of 70°, and azimuth angle of 20°. Note the asymmetry of the solar radiation contribution...... 69 Figure 8.5 Temperature of all the simulated frogs in the partially occluded scenario. Note how the black and black IR reflecting frogs serve as an envelope for the other spectra. (The Gastrotheca and Hyla species do not present reflectivity in the near infra-red)...... 70 Figure 8.6 Weight of the frog minus the evaporated water so far at that moment of the day in the partially occluded scenario...... 70

9

10

The University of Manchester

Thermoregulation in Neo-Tropical Tree Frogs Francisco Herrerías Azcué Master of Philosophy 11 August 2015

Abstract

Pterorhodin, a darkening pigment that replaces melanin in some neo-tropical tree frogs, causes them to reflect light in the near infra-red. The evolutionary drive for this has been speculated to be either for enhancing the crypticity of such anurans, or to help them stay at cooler temperatures. The theoretical background is recapitulated, and the parameters associated with these processes are studied. A technique for measuring surface areas and volumes through 3D reconstruction is developed and used in the two species of the Cruziohyla genus, for which two area interpolation methods are suggested. Experimental measurements of the mass transfer coefficient are presented, and two extrapolation methods are proposed. A detailed simulation of the thermoregulatory processes in tree frogs programmed in MATLAB and made available to the public as a graphical user interface (GUI) is presented. The simulation includes all the proposed approximation values and a complete set of default values that enable the user to directly generate realistic simulations. The significance of the temperature differences between frogs with and without the infra-red reflectivity is discussed in two scenarios. The differences are concluded to be negligible in the most common scenario, but are shown to be significant when the frog is completely exposed to the solar radiation.

11

12

Declaration No portion of the work referred to in the thesis has been submitted in support of an application for another degree or qualification of this or any other university or other institute of learning.

Copyright © i. The author of this thesis (including any appendices and/or schedules to this thesis) owns certain copyright or related rights in it (the “Copyright”) and s/he has given The University of Manchester certain rights to use such Copyright, including for administrative purposes. ii. Copies of this thesis, either in full or in extracts and whether in hard or electronic copy, may be made only in accordance with the Copyright, Designs and Patents Act 1988 (as amended) and regulations issued under it or, where appropriate, in accordance with licensing agreements which the University has from time to time. This page must form part of any such copies made. iii. The ownership of certain Copyright, patents, designs, trademarks and other intellectual property (the “Intellectual Property”) and any reproductions of copyright works in the thesis, for example graphs and tables (“Reproductions”), which may be described in this thesis, may not be owned by the author and may be owned by third parties. Such Intellectual Property and Reproductions cannot and must not be made available for use without the prior written permission of the owner(s) of the relevant Intellectual Property and/or Reproductions. iv. Further information on the conditions under which disclosure, publication and commercialisation of this thesis, the Copyright and any Intellectual Property and/or Reproductions described in it may take place is available in the University IP Policy (see http://documents.manchester.ac.uk/DocuInfo.aspx?DocID=487), in any relevant Thesis restriction declarations deposited in the University Library, The University Library’s regulations (see http://www.manchester.ac.uk/library/aboutus/regulations) and in The University’s policy on Presentation of Theses

13

14

Publications and Presentations

Conference poster F. Herrerías-Azcué, M. Dickinson and A. Gray, “Thermoregulation Modelling, what colour makes the coolest frog?”, LiSci 2015, Tequisquiapan, Mexico, August 2015.

Journal Article F. Herrerías-Azcué, C. Blount, A. Gray and M. Dickinson, “Tree-frog Thermoregulation Modelling: the role of Reflection Spectra”, (in preparation).

15

16

Acknowledgements

Firstly I would like to thank my supervisor Dr. Mark Dickinson for all his help over the last year. Without his prompt guidance and support in all the problems that arose during the project, this research would not have been possible. I would also like to thank my co-supervisor, Dr. Andrew Gray, for all the insight and experience shared on a completely unexplored subject to me until the beginning of my degree, as well as Chris Blount and Adam Bland, who were always close and happy to help.

I’d like to thank the CONACyT program and the University of Manchester for the joint effort made to allow students from Mexico to do our postgraduate studies here, for the funding, the attention and the headaches, that in the end make this thesis possible. At the same time, I would like to thank the Institute Of Physics for the funding provided to attend the Li-Sci 2015 event at Tequisquiapan, Mexico.

I would like to thank Arturo Gonzales, mentor and friend, for all his support even at a distance, and all the people that have made this process a bit more pleasant by sharing themselves with me, like Alonso, Manuel, Itzel, Abraham and Mauricio.

Special thanks go to my wife, for her constant support and encouragement, for all the delicious lunch moments shared and all the wonderful experiences that we lived together during this period. Truly, without you, Ivonne, I would have fallen apart a long time ago. To my parents, brothers and sister, that I’ve missed but felt close and supportive the whole time, and also to Daniel, Chloe, Laura, Elizabeth, and Raul, who have made me feel welcome on this side of the Atlantic and somehow filled the gap created by the distance to my country and loved ones.

17

18

1 Introduction

In the decade of the 1970’s a “new” pigment was found in the skin of the Mexican leaf frog Pachymedusa Dachnicolor [1]. Its different morphology and the lack of previous reports led the researchers to name it “rhodomelanochrome”, although it was later confirmed that the pigment was in fact an already known pteridine dimer known as “pterorhodin” [2]. This darkening pigment replaces melanin in the skin of the frog and, as a result, the spectrum of the frog displays a distinct peak in the near infra-red [3]. Why this species has evolved to reflect the light in the infra-red has been the subject of speculation, and two theories have arisen. One proposes that it helps in the thermoregulation process, allowing the frog to stay cooler even when exposed to direct sunlight. The other proposes that, since the leaves the frogs sit on also reflect the light in the infra-red, it allows them to stay cryptic while they sleep, helping them to avoid predators [4]. There are no reports, however, that predators of leaf-sitting frogs are able to see in the near infra-red, and no serious studies are available regarding its aid in the thermoregulation process. Therefore, the question of its evolutionary trigger remains open.

In this thesis, a thorough study on the thermoregulatory process in tree-frogs is presented. In order to contest the possibility of pterorhodin (or changes in the spectrum of the frog, in general) being useful for the frog as a thermoregulatory aid, a comprehensive simulator will be presented and its outcomes discussed.

In Chapter 2, a review of the thermoregulation processes taking place is given, emphasising the importance of some that may have been disregarded in the past. In Chapter 3, a deeper insight on what parameters affect those processes is provided, emphasising the aspects that will be favoured in the simulation model developed here. The difference in spectra between frogs with and without pterorhodin is also explored in this section.

19

The surface areas of the frog being simulated can produce radical changes in the thermoregulatory processes, and that is why, in Chapter 4, a technique based on 3D model reconstruction is presented as a way to accurately measure surface areas and volume of the frogs. The accuracy achieved through this method offers possibilities for more careful studies on surface area changes through development or across species. The latter is approached in Chapter 5, using as an example the Cruziohyla genus, composed of only two species (See Figure 1.1). Also in this chapter, two methods for interpolating surface areas within a Figure 1.1 Photographs of Cruziohyla species are presented, that will be later used in the craspedopus (Top) and Cruziohyla calcarifer (Bottom), on which the surface area studies simulation model. were focused. The importance of water evaporation in anuran thermoregulation is stressed in Chapter 6, where the mass transfer coefficient is determined for agar and plaster of Paris frog models. The experiment conducted in this section also leads to a method for extrapolating the coefficient as a function of the wind speed, which is then applied in the simulation. Chapter 7 presents the simulator and explains the use and functionality of the graphical user interface, which is available for public use. A copy of the full source code, sample frog spectra, ambient profile and saved, importable simulation data files can be obtained by e-mailing [email protected] or [email protected]. For quick references, the full source code is presented in Appendices A through C. Finally, in Chapter 8 different simulation results are discussed, ranging from the absolute extreme situation of a frog sitting flat on the ground and fully exposed to the sun, to a frog in a more natural and realistic position, partially hidden and therefore shaded from the sun. The significance of the infra-red reflection is considered not only as a way to reduce the temperature of the frog but, perhaps more importantly, also as a way to help the specimen in conserving its water, reducing the need for rehydration. Chapter 9 draws some conclusions for the work presented in this thesis.

20

2 Thermoregulation

Every living organism survives in a limited range of temperatures, and only thrives in a further reduced range. The process through which they get to be in a certain temperature range is called thermoregulation. All possess different ways of modifying their temperature, whether it is consciously changing position, looking for a different habitat, moving, etc. or unconsciously shaking, metabolizing food, sweating, etc. Like reptiles and fish, anurans are ectotherms, which means they produce very little heat from metabolism and they depend solely on the environment to warm up. As such, the way in which they can modify their temperature goes down to a handful of factors, summarized since the 1970s, and mainly studied by two research groups lead by C. Tracy and W. Porter. The theoretical background in which they have studied thermoregulation is based on Porter and Gates 1969 paper [5], in which animals of any kind are modelled as concentric cylinders. Although the model so far was thorough, it did not include evaporative water loss (EWL). This is very significant in most frogs that, due to their permeable skin, evaporate water as a free water surface. EWL is first introduced by Richard Tracy [6], who summarizes most of his work related to thermoregulation modelling in [7]. Modelling has continued since, and the models have spawn into different animals, from [8]–[11] to reptiles [12]–[15]. Most of their recent research is aimed at using the models towards ecological or habitat restriction purposes of specific species [8], [9], [16], [17]. The theoretical model, however, has remained the same since the introduction of the EWL in 1976, and each of its factors contributes a certain amount of power to the frog, ultimately driving it to an equilibrium state. In a simplified model in which the frog has no water intake, the factors are shown in Figure 2.1 and are considered as follows.

21

Figure 2.1 Diagram of the power exchange processes considered in the thermoregulation model. Absorption of solar radiation considers scattered, reflected direct and indirect sunlight, and it can only have a positive sign (going into the frog). Conduction and grey body radiation and convection can take either sign, and although evaporative water loss could too, it usually has a negative sign.

2.1 Absorbed radiation

Solar radiation is the main income of energy for anurans, and that is why they are often found basking in the sun. Increasing their temperature allows them to quicken their metabolic rate, be able to move faster, and even help them fight diseases [18]. The incoming radiation can either be a direct beam, or it may be scattered or reflected light. It will depend greatly on the spectrum of both the incident radiation, the absorption characteristics of the frog itself, and also on the amount of surface exposed to such radiation.

In general, the power absorbed (푃푎푏푠), can be expressed as

푃푎푏푠 = 훼 푅𝑖 퐴𝑖 , (2.1) where 훼 is the absorptivity of the frog, 푅 the incoming radiation, and 퐴 the exposed surface. The subscript 𝑖 represents the existence of several sources of radiation, each with a particular surface linked to it. However, since the main components come from the solar energy, they can be expressed as a sum of the diffuse or reflected light, and the direct solar beam. The diffuse light gets to the frog from any point to the dorsal area (퐴푑), and the direct beam casts a projection of the dorsal area depending on the solar position relative to the frog. In this way, the solar power contribution is expressed as

푃푠표푙 = 푃푑𝑖푓푓 + 푃푑𝑖푟 = 훼 푅푑𝑖푓푓 퐴푑 + 훼 푅푑𝑖푟 푝 퐴푑 , (2.2) where the subscripts 푠표푙, 푑𝑖푓푓 and 푑𝑖푟 identify the total solar power, its diffuse and direct components respectively; 푝 is a projection factor that changes with the solar position.

2.2 Emitted radiation

Like every other object, frogs emit a certain amount of power just by existing at a certain temperature. They also absorb thermal radiation coming from their surroundings, and so the radiation output (푃푟푎푑) can be treated as that of a grey body at temperature 푇푓 in a room at temperature 푇푒푛푣

22

4 4 푃푟푎푑 = 휀퐴푑휎(푇푓 − 푇푒푛푣) , (2.3) where 휎 is the Stephan-Boltzmann constant, and 휀 is the frog’s emissivity, in anurans usually around 0.96 [7]. The area through which this exchange is happening is set to be the dorsal area, for their ventral area is in direct contact with a substrate, whether that is water, dirt, rock, wood or a leaf. When the air and the substrate are not in equilibrium, 푇푒푛푣 has to be calculated as a point in between the two, trying to account for the amount of “sky” and closer surroundings to the frog.

2.3 Conduction

Direct heat transfer from or to the frog, especially from the substrate on which it is standing, can be a determining factor. For big animals, the time that heat takes to be conducted from the core to the integument and vice versa has to be taken into account [5], [6], because it adds a thermal inertia to the system. In small specimens, however, the core and outer shell can be treated as one, because their small mass reflects on negligible inertia [14]. Conduction to the substrate (at temperature 푇푠) takes place only through the ventral surface (퐴푣) of the frog, and although in general a specific “shape factor” (퐺) should be calculated, neo tropical frogs can be accurately simulated as flat slabs. As such, their shape factor is defined as the cross sectional area of the slab (namely the frog’s ventral area) divided by its thickness (ℎ), and therefore the power of conduction (푃푐표푛푑) is described by

퐴푣 푃푐표푛푑 = 퐺 푘푡 (푇푠 − 푇푓) = 푘푡 (푇푠 − 푇푓) , ℎ (2.4) where 푘푡 is the thermal conductivity. Usually, the limiting conductivity is set by the frog, but in some cases the substrate may have lower thermal conductivities than the frog.

2.4 Convection

The air surrounding the frog will also take some heat away, especially if there are air currents. The relevance of heat convection will be determined by the temperature difference between the frog and the air, the frog’s exposed surface, and a heat transfer coefficient (ℎ푐), that in turn depends on wind speed and the size of the frog. The power exchange through convection

(푃푐표푛푣) is given by

푃푐표푛푣 = ℎ푐퐴푑(푇푓 − 푇푎) . (2.5) The heat transfer coefficient has been approximated in the past as a function of wind speed [5], [19], but because it is also shape dependant, how accurate that may be is still something that has to be considered.

23

2.5 Evaporative water loss

Also a power exchange with the air surrounding the frog, evaporation is one of the main elements controlling the cooling process in most anurans. It is usually due to water evaporating from the frog, but sometimes it can add heat when water condensates on the dorsal area (퐴푑). Either way, the power exchange will vary with the frog’s area, the water vapour density at the skin layer (휌푠) and further away from it (휌푎). The water exchange rate will also vary greatly from one species to another, and this change is usually assigned to a factor referred to as the “mass transfer” coefficient (ℎ퐷). The latter is very circumstantial, and in general it depends on wind speed, relative humidity and on the frog’s shape and orientation with respect to the wind direction. Although there are some frogs that exhibit some resistance to evaporative water loss [20], [21], this is not the case for most anurans, and in general they can therefore be simulated as a free water surface [6]. As such, the water vapour density of a frog with no resistance to EWL can be directly imputed from tables [22], and for the air further away, it will be the product of the saturation value and the relative humidity of the air.

The power exchanged through EWL (푃퐸푊퐿) is given by:

푃퐸푊퐿 = 퐿ℎ퐷퐴푑(휌푠 − 휌푎) , (2.6) where 퐿 is the evaporation or condensation latent heat of water.

2.6 Metabolism

As mentioned before, the metabolism of anurans produces very little heat, and even when it is joined to the activity that the frog has, and all the work it does, it is generally a very small amount and of opposite sign to the power lost through respiratory water evaporation, and it is therefore usually neglected [6]. Most frogs are in a constant water regulation process, and this directly links to thermoregulation. It is not surprising then that simulations are sometimes run simultaneously. Accounting for water intake can be very complicated, because it is usually behaviourally driven. Having said that, the simulation proposed here does not run in parallel with a water balance model, and water intake is not taken into account. Most leaf frogs are nocturnal, and only rehydrate during the night, but it is important to note that the model proposed in this work will not be correct if the specimen under study is gaining or losing mass (and therefore energy) through water intake.

24

3 Parameters

Even in the relatively simplified model hereby presented, there are many variables that affect the final result in thermal equilibrium. Some of these, such as the frog conductivity, rarely differ and can therefore be treated as constants. Others do vary significantly, like the air temperature or relative humidity, but they can in no way be manipulated or modified by the frog, and will be categorized in this work as environmental. Finally, there are many others that can and do change from one species to another (or even in the same specimen), and they can be adapted to actively thermoregulate. Some of these are, for example, the shape of the frog, its position towards the sun, its absorption spectrum, etc. All these parameters work in synchrony and result in a relatively precise temperature and water balance, that enables the frog to digest, move, keep hydrated, fight diseases and ultimately reproduce successfully. The following classification is not absolute or even very rigid, but it tries to show the way in which such parameters can be manipulated by a frog or how easily they can change. At the same time, the classification reveals how they are treated in the model proposed in this work.

3.1 Environmental

Although the frogs actively search for an environment with an adequate temperature for their needs [23], [24], once they find a place to stay they can sleep relatively motionless on a leaf throughout the whole day. Therefore, there are some variables that contribute to their temperature change that are simply not under their control, like the solar irradiance changing throughout the day, or the changes in the relative humidity of the air. These do vary significantly, and they are very important in the process of power exchange. Although they can be relatively easier to predict than, for example, the position of a frog, they are not constant, and are hence included in this separate category.

25

3.1.1 Solar Irradiance As the main source of heat, this parameter has to be taken very seriously. All the energy that the frog can capture from the sun is in the form of radiation, but it can be either from direct solar exposure, scattered, or reflected light. The direct solar radiation (푅푑𝑖푟) is only absorbed through the projected surface discussed in Section 3.2.2. The other two are absorbed through the whole dorsal surface, and can therefore be combined into a single irradiance source, usually called diffuse radiation (푅푑𝑖푓푓). The solar radiation varies through the day, not only in intensity, but also in spectrum (See Figure 3.1). It is common to dim the solar intensity using a coefficient called “Air Mass” [25], which is a relative optical path for the sun through the atmosphere. This solution satisfies most engineering Figure 3.1 Samples of the solar direct (red) and diffuse (blue) spectra at different zenith angles. Note how as the sun goes down (higher zenith angles) the blue end of applications, but since the spectrum is significantly more attenuated than the infra-red, especially in the direct beam spectrum. absorption of solar radiation depends on the spectrum and the frogs under study reflect a different and specific wavelength range, the air mass coefficient approach is not accurate enough for this research. Gueymard [26] presents a “Simple Model of the Atmospheric Radiative Transfer of Sunshine” (SMARTS), which simulates the solar irradiance at the earth’s surface starting from a solar spectrum in space, and then taking into account the different absorption processes as the light goes through the atmosphere. As is to be expected, this simulator requires several inputs regarding the location, gas concentration and so on. To simplify this process, and given that the simulator proposed in this work is aimed at neo-tropical tree frogs, a simplified version of SMARTS was compiled. This simplification was made by fixings some inputs to specific conditions close to the tropical forests. This, of course, decreases the range of situations that can be efficiently simulated, but allows for a rapid and accurate reproduction of the solar spectrum throughout the day. The parameters fixed in the SMARTS program forced a rural aerosol model, surrounding albedo of green rye grass and the use of Gueymard’s proposed synthetic solar spectrum and standard turbidity value. Also, radiometer simulation, smoothing, illuminance and special UV

26 calculations were bypassed. With all of these parameters fixed, the most important input left is the zenith angle, which is calculated separately as described in Section 3.1.5. The resulting program was translated into Matlab, which allowed for it to be directly called from the frog simulator, and also for its vectorization, which made it calculate more efficiently. It yields the solar irradiance values for both the direct and diffuse light at wavelength gaps of 0.5 nm from 280 nm to 400 nm, 1 nm from 400 nm to 1700 nm, and 5 nm from 1700 nm to 4000 nm.

3.1.2 Surrounding Temperature The second and only other significant way in which the frog may gain energy is by conduction, which is directly related with the substrate temperature (푇푠) on which it is sitting. Minor power exchanges occur due to convection, directly related to the surrounding air temperature

(푇푎). Because the frog will be modelled as a grey body in a room at a temperature different from zero, a combination of these two will also affect the way in which the frog radiates energy. Usually, however, both are very similar, and there is no discernible difference in how they are averaged. The temperature of the air (in conjunction with the relative humidity) will also determine the saturation vapour pressure of the air, fundamental in the evaporative water loss calculation.

3.1.3 Wind The wind speed (푣) of the air surrounding the frog will strongly influence the amount of water evaporating from it, as well as the amount of heat it losses through convection. Meteorological reports usually address only the velocities above the forests’ canopies, and although the wind there can be very strong, it is only a small fraction of it that is usually experienced closer to the ground, where frogs tend to bask or sleep. Studies in tropical forests in the Amazon have reported that the wind at those levels is usually from 1 to 5% of the wind at the canopy [27]. Therefore, when wind profiles were approximated for simulations, 2.5% of the wind speed at the canopies was used.

3.1.4 Relative Humidity The amount of suspended water in the air will determine how prone water is to evaporate from the frog or condense on its dorsal surface. It will also reflect on the amount of solar radiation absorbed in the air before it reaches the frog. As evaporative water loss is one of the most important power loss mechanisms, relative humidity (푅퐻) plays a very significant role in both thermal equilibrium and water balance.

27

Relative humidity (in conjunction with the temperature of the air) will also determine the saturation vapour pressure of the air, fundamental in the evaporative water loss calculation.

3.1.5 Global Position and Time The location in which the lives will determine many of the other variables already included explicitly in this category, it will greatly constrict the ranges of the relative humidity, the surrounding temperature, the amount of gasses in the atmosphere that absorb solar radiation and so on. However, it is of most importance to explicitly describe the position of the sun relative to the area. This will depend on the latitude, longitude and altitude of the location, and also on the time of the day. All these variables can then be combined to output a couple of angles that describe the vertical and horizontal direction of the sun with respect to the ground.

The vertical information is included in the zenith angle (휃푧), which is the angle between the normal to the ground and the sun beam, which means that it will be closest to 0 ° at noon, it will vary from 0 ° to 180 °, and the sunrise and sunset will happen at 90° (See Figure 3.2). It is responsible for the changes in the spectrum of the sun throughout the day, for it determines the Figure 3.2 Definition of the solar zenith and azimuth thickness of the atmosphere through which the angles (휃푧 and 휃푎), used to calculate the solar irradiance and the frogs projected area receiving the direct solar beams. light passes.

The horizontal information is encompassed in the azimuth angle (휃푎), measured from the north towards the east (i.e. 푛표푟푡ℎ = 0°, 푒푎푠푡 = 90°, 푠표푢푡ℎ = 180°, 푤푒푠푡 = 270°), goes from 0 ° to 360 ° (See Figure 3.2). It is unimportant in the determination of the solar spectra, but it is very important to use it in combination with the zenith angle and the position of the frog to determine whether the direct solar beams reach the frog or not (see Section 3.2.2). To compute these angles, the PSA algorithm proposed by Blanco-Muriel et al [28] was adopted, for it remains stable and functional in both hemispheres, as opposed to the commonly used Michalsky’s algorithm [29], even after the corrections proposed by Spencer [30]. Furthermore, it allows for date input in the common dd/mm/yyyy format (instead of using the Julian date), and it predicts the zenith at local noon, whereas the other algorithm changes due to the Julian date corrections. The PSA algorithm is only recommended for the period 1999-2015, to insure a precision of 0.5 minutes of arc, which is far more than needed in the frog simulator. Therefore, the same code can be used to simulate the solar position for dates far into the future.

28

3.2 Frog-Dependant

In this category, the parameters that change from one species to another or that can be manipulated by the frog itself are listed. Therefore, this is where most of the active thermoregulation variables are included, like the specimen’s position relative to the sun and its shape. Other (more passive) variables are included, but they are traits that have evolved differently in each frog’s species, and hence are the result of evolutionary characteristics that may aid in the thermoregulation process, like their general shape, their spectrum, the efficiency with which they lose heat through evaporation and convection.

3.2.1 Shape Undoubtedly one of the most important and more widely influential parameters is the animal’s shape itself. It affects how much energy it collects from the sun, how much it radiates, how much water evaporates, how quickly conduction can take place, etc. Due to this, a whole separate chapter is dedicated to the description of a technique developed to measure, interpolate and predict volume and surface areas of frogs (see Chapter 4). In general though, a frog in a water conserving posture conceals a softer more permeable section of its skin and shields itself with a sturdier and commonly cryptic surface. The relatively flat surface in contact with the substrate (in leaf sitting frogs, as the name suggests, generally a leaf), is referred to as the ventral area (퐴푣). The exposed surface, usually only in direct contact with air is called the dorsal area (퐴 ) and is through which most 푑 Figure 3.3 The shape of the frog is power exchange takes place, and also of particular interest in approximated as a disc of radius 푟푐, cross sectional areas 퐴푣, and thick- ness ℎ. This is only used for the this study, for it is where pterorhodin can be found in some solar projection and the conduction species [2], giving their spectra a characteristic peak of power exchanges. reflectance in the near infra-red. Also useful in the description of the frog’s profile is a characteristic length of the frog, defined as the distance from the tip of its nose, or snout, and the vestige of its tail, or vent, hence called the snout-vent length (퐿푠푣). This measurement characterizes a frog species, and is used widely to refer to the size of a frog [31], [32]. The size of frogs varies hugely, with extreme cases covering from 7.7 mm to 300 mm.

However, most species have 퐿푠푣 of between 20 mm and 100 mm [33], which makes the

Cruziohyla species used in Chapter 5 (퐿푠푣 of 5 to 7 cm) examples of typical sizes.

29

Their thickness is not as simple a measurement and it varies at every point, especially in the direction perpendicular to the snout-vent length (the frog’s width). Furthermore, the frog itself can, to some extent, choose to increase or decrease its thickness. However, it is important for simulating the conduction and for estimating the portion of the dorsal surface receiving direct solar radiation. Therefore, throughout this work it will be thought of as a single measure for the whole frog, and approximated through its volume, or calculated through its weight and a generalized density (see Section 3.3). The thickness (ℎ) will be then constructed as the height of a cylinder of equal volume to the frog, and cross sectional areas equal to the ventral area (See Figure 3.3). Also, this cylinder radius will be defined as 푟푐 = √퐴푣/휋 for its use in the frog’s projection.

3.2.2 Position / Projection Although not thoroughly explored in the model here presented, frogs adjust their position relative to the sun and wind to adjust the radiation they receive and the water they evaporate [7]. The importance of the orientation of the frog in water evaporation has been debated [6], [10], so it is neglected in this model. The effect that the position of the frog has on the absorbed radiation is directly linked to the shadow it casts, and it is the only way in which it will be accounted for. Only the projection of the dorsal area of the frog will receive direct and normal solar radiation and, even with a static frog, it will vary throughout the day as the sun rises, culminates and sets. The solar position can be described by two angles, one for its vertical position

(zenith, 휃푧) and the other (azimuth, 휃푎) for its cardinal direction (see Section 3.1.5). Similarly, the position of the frog will be described with two angles. Its vertical

Figure 3.4 Definition of the frog’s zenith and orientation will be measured from the normal to the azimuth angles (휃 and 휃 ) used to describe its 푧푓 푎푓 ground (푛⃗⃗⃗⃗ ) towards the normal to the frog’s ventral position relative to the sun. The vectors 푛⃗⃗⃗⃗푔 , 푛⃗⃗⃗⃗푣 , 푔 and 푝⃗⃗⃗⃗푛⃗⃗푣 are the normal to the ground, the normal to the frog’s ventral area, and the projection of the area (푛⃗⃗⃗⃗v ), as shown in Figure 3.4. This angle will be latter on the cardinal plane, with north, east, south and west indicated by N, E, S and W respectively. referred to as the frog’s zenith angle (휃푎푓), and it can vary from 0° (with the frog sitting parallel to the ground) to 180° (with the frog upside-down). The other angle will describe its cardinal orientation, and it will be measured from the north, going east, to the projection (푝⃗⃗⃗푛⃗⃗⃗v ) of the normal to the frog’s ventral area onto the cardinal plane, also shown in Figure 3.4. It will take values from 0° to 360°, and will be referred to as the frog’s azimuth angle (휃푎푓).

30

Note that, to describe a generalized position of the frog, a third angle would be necessary, but since our model frog is cylindrical, its axial symmetry reduces the description to two angles. This, however, ignores the effect of the sun hitting the head, the side or the back of the frog, which varies slightly the projected shadow. This “disc simplification” means that the projection can be calculated as a function of four angles, two for the sun, and two for the frog.

For a frog sitting flat on the ground (i.e. 휃푧푓 = 0°) the axial symmetry results in lack of importance for both azimuth angles (휃푎푓 and 휃푎), and the projection is simply a function of the solar zenith angle (휃푧). In such circumstances, the cylinder should cast a shadow equal to 2푟푐ℎ when 휃푧 = 90°, and equal to 퐴푣 when 휃푧 = 0°, which can be easily reproduced using

퐴푝 푓푙푎푡 = (2푟푐ℎ) sin(휃푧) + (퐴푣) cos(휃푧) , (3.1) where 푟푐, ℎ are the radius and thickness of the cylindrical frog (see Section 3.2.1). Introducing the possibility for a tilted frog makes both azimuth angles relevant, and so instead of introducing just another angle, it introduces 3 more. However, we are only interested in the angle between the solar beam and the normal to the frog’s ventral area, which can be obtained directly from the law of cosines in spherical coordinates, given by

cos(훾) = sin(휑1) sin(휑2) cos(훽1 − 훽2) + cos(휑1) cos(휑2) , (3.2) where 훾 is the angle between two vectors (푟𝑖, 훽𝑖, 휑𝑖) in spherical coordinates. Here, 휑𝑖 are measured just as the zenith angles, and because only the difference 훽1 − 훽2 is used, it is unimportant that they are measured from the 푥 axis and counter clockwise, instead of from the north and clockwise, as the azimuth angles.

Taking this into account, the projection zenith angle (휃푧푝) can be obtained as

휃푧푝 = acos(푠𝑖푛(휃푧) 푠𝑖푛(휃푧푓) 푐표푠(휃푎 − 휃푎푓) + 푐표푠(휃푧) 푐표푠(휃푧푓)) , (3.3) and it can have values between 0° and 180°. When it is greater than 90°, the sun would be reaching the frog from underneath, therefore reducing the projected area to zero. For other values, the projected area of the frog can be calculated using Eq. (3.1) and replacing 휃푧 with the projection zenith angle 휃푧푝

퐴푝 = (2푟푐ℎ) sin(휃푧푝) + (퐴푣) cos(휃푧푝) , (3.4) where now the projected area 퐴푝 allows for any position for both the sun and the frog. Note that when 휃푧푓 is set to 0 in Eq. (3.3), Eq. (3.4) results in Eq. (3.1), as would be expected.

3.2.3 Frog Spectra This parameter has largely been ignored in the literature, and it is one of the main motivations for this research. Although most leaf frogs converge in the visible spectra to a cryptic green colour, their spectra outside of the visible range can be significantly different [3]. Even more

31 so when the darkening pigment melanin is replaced by pterorhodin, as is often the case [34]. This change in the melanophores results in light in the near infra-red being reflected, which is readily visible in their spectra (see Figure 3.5). Its evolutionary drive is yet to be explained. It is trivial to see that this peak in reflectivity would affect the amount of radiation absorbed by the anuran, and it would therefore affect its temperature. However, insufficient research has been made in the matter. The only report available is that of Emerson et al [4], where they only mention as a quick note that the IR reflectance would account for less than a 2 °C temperature change. The spectra used in this research include frogs with and without this characteristic peak, so as to be able to compare the effects in the spectra changes. Additionally, two spectra were built as reference of the extreme cases: A completely black frog that absorbs all the incoming radiation (labelled as Figure 3.5 Examples of spectra of frogs with and without the pterorhodin characteristic reflection peak at approximately 700 nm. The dotted and “Black” in Figure 3.5) and a frog dashed black lines are extreme reference spectra built for a completely black frog, and a black frog that reflects all the near infra-red light. that absorbs all the incoming radiation except the light in the near infra-red (labelled as “Black IRR” in Figure 3.5). The other spectra shown in the plot are from Cruziohyla calcarifer, Criziohyla craspedopus, Pycomeosa savagii, Gastrotheca riobambae and Hyla cinerea. As a group, they will be referred to as the “real” frog spectra throughout the text. The spectra shown in Figure 3.5 are the ones used in the simulation and therefore they have already gone through the process of spectrum import described in Section 7.2.1.1, which adds an exponential fall off at the edges of the spectrum being imported.

3.2.4 Convection Coefficients The efficiency with which energy is exchanged through convection or evaporative water loss is described by two quantities known as the mass transfer coefficient (ℎ푑), and the heat transfer coefficient (ℎ푐). Although they seem to play a very important role in thermoregulation, there are very little reported measurements of these values in anurans, and when it is reported, it is shown as a correlation between the Nusselt-Reynolds numbers, or the Sherwood-Reynolds numbers [6].

32

The nature of the mass transfer coefficient makes it very situation dependent, and so it will vary with each particular scenario in which it is measured, whether due to the air’s humidity, wind speed, air’s temperature or the frog’s temperature. This makes the computational simulation very difficult, and experimental measurements have to be made. The experiment itself is fairly simple, but since the results are dependent on so many factors, the error associated with the obtained value is anything but negligible. In Chapter 6, the experimental method and results are described and discussed in depth. For now, it will only be stated that for the models used, the mass transfer coefficient yielded is of the order of 10−2 m/s. Cussler mentions that there is commonly a relationship between the mass transfer coefficient and the wind velocity [35], where ℎ푑 is usually a function of the square root of the wind velocity. Although the data acquired in the experiment here conducted does fit such a relationship, it also fits different relationships with the wind speed, and therefore it neither supports nor disproves Cussler’s theory.

Measuring ℎ푐 experimentally, on the other hand, can be more complicated, but more efforts have been made to simulate it. Porter and Gates [5] propose a model in which any animal is represented as a cylinder, with a heat transfer coefficient given by 푣1/3 ℎ = 푘 , (3.5) 푐 ℎ 푑2/3 where 푣 is the wind speed, 푑 is the diameter of the cylinder and 푘ℎ is a constant reported by J themselves as 3.629 for a smooth cylinder with an axis perpendicular to the m5/3 s2/3 °K direction of the wind. A slight complication of using this approximation is to determine the cylinder diameter to use, which is not an issue in the model proposed by Mitchell [19]. He chooses to represent animals as spheres of a radius equal to the cubic root of their volume. He shows that the relationship between the Nusselt (푁푢) and Reynolds (푅푒) numbers for a sphere is 푁푢 = 0.34푅푒0.6 , which if combined with the definitions of these numbers in terms of a characteristic length equal to the radius of the sphere (퐿 = 푉1/3), yields ℎ 퐿 푣퐿 푁푢 = 푐 푅푒 = , 푘푎𝑖푟 푘휈 where 푘푎𝑖푟 is the thermal conductivity of air and 푘휈 is its kinematic viscosity, the heat transfer coefficient can be calculated as 푣 0.6 1 0.4/3 ℎ푐 = 0.34 푘푎𝑖푟 ( ) ( ) . (3.6) 푘휈 푉

33

Since the volume is also used to approximate the thickness, using it does not introduce new parameters, and both 푘푎𝑖푟 and 푘휈 are relatively constant, so this approximation is preferred. However, both methods are available as options in the model presented here.

3.3 Constants

Most of the following parameters are not strictly constant, but they either have a minimal variation, or those variations reflect on insignificant changes in the power balance. However, it is important to consider them as reference and, since no direct measurements were made, the simulator allows for direct input of most of them. The values reported here are simply the default values.

The frog’s thermal conductivity (푘푓) is usually what limits the speed of thermal conduction to W and from the substrate. Its value was set to 푘 = 48.8 °K, which is the conductivity 푓 m2 reported by Tracy et al [6] in SI units.

The air’s thermal conductivity (푘푎), which only affects the heat transferred through convection −2 currents, was fixed at 푘푎 = 2.624 × 10 W/m°K. Its kinematic viscosity (푘휈) affects the −5 2 same phenomenon, and it was set to 푘휈 = 1.568 × 10 m /s. Both values were taken from dry air property tables [36]. The frog’s emissivity (휀) will govern the radiation process, and as Tracy [7] mentions, it is usually approximately the same, with a value 휀 = 0.96. The frog’s density does not directly affect the thermoregulation process, but it can be used to determine the volume from weight and vice versa. Since these are relevant in the simulation, it is important to mention that density was taken to be always around the density of water, i.e. 1 g/cm3. Other values used were the latent heat of evaporating water 퐿 = 2260 kJ/kg for evaporative water loss, the Stephan-Boltzmann’s constant 휎 = 5.670373 × 10−8 W/m2 °K4 for grey body J radiation, and the smooth cylinder convection constant 푘 = 3.6289 mentioned in ℎ m5/3 s2/3 °K Section 3.2.4 for convective heat loss.

34

4 Photogrammetry

In the search for a technique for accurately measuring the surface areas of a frog, the literature directly related to anurans was found to be lacking of non-invasive methods. Some studies killed and skinned the frog [37], [38], or, in the best case scenario, the specimen was sedated to create a cast from which then measurements were obtained through an electrolytic bath technique [6]. Technology has improved greatly since those studies were made, and image processing seemed to be a good way of obtaining precise data. Photographs taken from directly above or below the frog would yield accurate measurements of the ventral area when analysed computationally. However, an equivalent could not be done to obtain the dorsal area. We can see an object and think of its 3D shape by having two different perspectives of the same object and assuming similarities to previously seen objects. We only reconstruct accurately a 3D object when it is presented to us from every angle. This should be equivalent for computer software, and, indeed, there are various different options available online.

4.1 Software

However different the software may be, the workflow is always very similar. First, a series of images from all around the object have to be acquired (and how carefully and methodically this is done severely affects the resulting model). Then the spatial position of the camera is approximated in a process known as “aerotriangulation” by using a sparse cloud of “tie points”, generated from high contrast common features in different photos (See Figure 4.1 Aerotriangulation process. A sparse cloud of points helps to determine the position Figure 4.1). Once the photos are fixed in space, a dense from which the photographs were taken.

35 point cloud is obtained, gathering much more detail from the photos. These points are then converted into a mesh, which can be cleaned, modified and measured. After testing the ease of use, consistency of the results, accuracy of the resulting 3D models, and the speed of the rendering process, a joint process of Smart3DCapture 3.1.1 [39] and Blender 2.73 [40] was chosen. The former is the free version of a more complex 3D reconstruction program developed by Acute3D. It receives the photographs as inputs, reconstructs the scene and outputs a textured mesh (i.e. a coloured 3D model). The latter is an open licence, robust and powerful software for 3D modelling and animation. It can be used to edit the 3D model mesh, both as a whole and for individual points. Using a toolkit called NeuroMorph [41], it can yield surface, volume and length measurements of parts or totality of the model.

4.2 Method

4.2.1 Image Acquisition The number of photographs, the position from which they are taken, the lighting conditions in which the images are acquired and their resolution all affect not only the accuracy of the resulting 3D model, but also the time needed to render it and, ultimately, the required time to get accurate measurements. In theory, more photographs with as many different perspectives as possible will yield models with better resolution. However, it also increases the processing time. Several tests were conducted and when the image overlap was over 60% and the pictures were no more than 15° apart, the time taken to find the tie points reduced significantly and better quality models were obtained. Changes in lighting trick the process of allocating tie points, and hence result in poor model reconstruction. The whole photo series of any object should be acquired with the same configuration for exposure and aperture to prevent changes in contrast and luminosity. Smart3DCapture uses the “internal position” of the Figure 4.2 Turn-table used while testing different 3D photographs (i.e. the sensor maximum size and focal reconstruction software and the possibility of using a rotating frame instead of a rotating camera. length of the camera) to aid in the aerotriangulation process, and such information is usually stored in the metadata of each image. If images are extracted from a video their metadata is lost and, therefore, the quality of the resulting model

36 and the processing speed improves when photographs are used, even when the number of images that can be extracted from video frames is much higher. A higher image resolution, in theory, provides more dots from which to gather tie points and ultimately yields a more precise result. Nevertheless, the tests conducted with stuffed animals showed that there is actually not a significant difference in the resulting model between images of 4608x3456 and the same images resized to 1024x768 pixels using Brice Lambson’s image resizer [42], which keeps the metadata of the images. The processing time, however, dropped drastically from 78 min with high resolution images, to 4 min with the medium resolution images. Furthermore, the free version of Smart3DCapture sets a limit to the amount of megapixels that can be processed, and using smaller files allows the use of more images. Most information available online advises users to rotate the Figure 4.3 Deformities caused by camera and not rotate the object for a very simple reason: highly reflective surfaces (Top, bicycle light), and objects with plain colours The whole image is used when reconstructing the model, (Bottom, masking tape). including the background, and rotating the object will mislead the software to reconstruct the background instead of the rotating object. However, if the whole frame included in the photo and the main light sources are rotated, that is no longer a problem. This enormously facilitates the attainment of more systematic and better quality photographs, because the camera can be set using a tripod, and the objects rotated on a turntable (see Figure 4.2). Nonetheless, doing this comes with a price. When taking photographs of stuffed animals, it presents no problems, but when turning a live frog, it can make the frog move when it senses the rotation. Adding higher walls to the turn-table provided a still background (on the rotating frame) for the frog to set its eyes, and proved to make them move less, but they still felt some motion and occasionally moved their head. Minor deformities in the resulting model are caused by these movements, and it is important to take them Figure 4.4 Turn-table used for frog photo sessions. Note that the base is made of into account when determining the accuracy of this wood, providing a textured background. technique. Higher walls (~40 cm) also means that the photographs can only be taken from a single height, and this can also introduce errors to the reconstructed image.

37

As can be seen in Figure 4.3, shiny, translucent and highly reflective objects can result in holes in the resulting model, so they should be avoided where possible. Also, surfaces with plain colour offer no high contrast points, and it is then difficult to generate tie points. When a sturdier version of the turn-table was made this was taken into account, and a wooden base was used (see Figure 4.4). This resulted in a smooth flat reconstruction of the base, as opposed to the curve observed in the rightmost wall of the masking tape at Figure 4.3.

The reconstructed objects are generally not to scale, and it is therefore important to have a reference object to scale them. For the reconstruction of the frog models, a ruler with a scale down to 0.5 mm was used. For over 40 sessions, two frog species were subjected to the whole process while they were sleeping, so as to record their water conserving posture. One of the species (C. craspedopus) tends to sit even stiller when turned, as their natural reaction to danger is to trust in their camouflage. The other species (C. calcarifer), contrarily, opened its eyes and looked for the cause of the movement, moving its head as the background rotated. This forced the use of walls on the turntable, which meant that the images acqcuired for the second

Figure 4.5 Turn-table with walls, species had to be taken from a single height (~ 40 cm) above the which only allows for the images to be taken from a single height. wall (see Figure 4.5), wheras the photos for the first species could be taken from two different heights (~ 20 and 40 cm).

4.2.2 Model Reconstruction The default settings of Smart3DCapture were used throughout the whole project. These result in a good quality reconstruction and a low processing time cost. Once the images are loaded into the program, the process starts with submitting an aerotriangulation, which locates each photograph origin in a three dimensional frame. In some cases, the lamp used as a light source occluded the object of reconstruction, causing incomplete aerotriangulation. This was usually not a problem with the amount of images fed for frog renders (100-150), but when it did happen, simply re-submitting the aerotriangulation (which runs another pass but using the previously allocated images as guides) solved the problem. Next, a new reconstruction is submitted, followed by a new production. The latter generates the dense point cloud using the fixed images and using the sparse cloud of tie points as guides.

38

It constructs a reference 3D model to which coloured pixels are linked. This reference 3D model can then be exported from the reconstruction to a more general format, which can be then imported from Blender. To be able to use the coloured pixels as guides in the scaling and mesh cleaning process, the model and texture were always exported, which generates both a “.obj” file with the mesh, and a “.jpg” file with the texture information.

4.2.3 Mesh scaling and cleaning After importing the “.obj” file into Blender, the textured 3D model can be explored. Because the texture is also shown, the scale in the ruler can be used as a reference for scaling the object, and the flat board surface can be used to rotate and locate the model. The procedure followed for cleaning the rendered frogs was the following. 1. The rendered frog was roughly pre-oriented at the centre of the plane and its location and rotation were applied. 2. A multi-segment measurement of the ruler was made using intervals of no less than 5 cm. This measurement was then compared to the nominal length shown in the ruler, and the scaling factor was applied to the 3D model. 3. Every vertex but the ones describing the wooden base and the frog were deleted, leaving a flat surface to use as a reference. 4. The model was finely rotated and located horizontally at the 푥-푦 plane using the gridlines as a reference, barely surfacing above the reconstructed wooden base. The location and rotation were then applied. 5. In an orthographic frontal view, the knife tool (with the “cut through” option activated) was used to create a cut directly on top of the 푥 axis, which generates a loop around the frog. 6. A “triangulate” modifier was then applied to fix uneven faces generated in the previous cut. 7. The “Loop Inner-Region” was selected and then reduced, resulting in everything but the frog and the edge generated in the cut being selected. 8. The selected vertices were deleted, and minor, final cleaning was conducted. 9. The edge of the resulting model was then selected, and a ventral surface created, resulting in a closed model of the frog, ready to be measured. This method yielded models with great morphological accuracy, and although it sometimes appears to be taking portions of the wooden base as part of the frog this is only due to the way

39 in which the mesh was textured, and in reality only the mesh above the base plain is kept (i.e. the frog).

4.3 Measurements

Four types of measurements can be made using the NeuroMorph tools in Blender: Volume, surface, multi-segment, and shortest path. The last two are one dimensional measurements, the former going straight from one specified vertex to the next one, and the latter following already existing edges on the mesh. The surface can be measured for either the whole mesh or only a section. The volume needs to be measured for a closed surface, and hence the importance of having cleaned up the model. The frogs are generally characterized by their volume, their snout to vent length, their ventral surface, and their dorsal surface. These are all measurements that can be made directly from the cleaned 3D model with very high precision. The method in which the mesh was cleaned generated a single surface that represents the ventral surface, and it is then very easy to select and measure. The total surface and volume can be measured simultaneously selecting the whole mesh, and the dorsal area can be obtained from there. The snout-vent length was obtained as a multi-segment distance between two arbitrarily selected vertices.

4.4 Precision

It is not trivial to calculate the precision of the measurements obtained in this technique, because many “obscure” processes are taking place, and no direct measurement can be made in the living frogs with enough precision to compare it to that reported by the NeuroMorph tools. The frogs move, shrink and turn, making a direct and accurate snout-vent length impossible. However, two different precision tests were conducted in order to estimate the accuracy with which the 3D models were being obtained.

4.4.1 Printed 3D Models A set of four models were chosen to represent the different frogs that had been rendered. These models were then 3D printed. The resulting blue plastic frogs were then submitted to the same

Figure 4.6 Top: original rendered process with which they had been obtained, and the same model sent to 3D print. Bottom: rendered model of printed frog. measurements were obtained from the resulting rendered 3D blue

40 frogs (see Figure 4.6). In this way, an irregular object of accurately known volume and similar shape to the original frogs were measured, and a direct comparison of the process error could be obtained. Because two different image acquisition sets were used with the frogs (one with walls, forcing a single height, and one without, allowing for two heights), two reconstructions were made for each plastic frog (one for each set), providing information on the accuracy of each configuration. Table 4.1 shows the absolute average errors for each measurement, as well as an overall average. The error was calculated as the difference between the “measured” value (obtained from the blue model) and the “real” value (obtained from the model sent to print), and then divided by the “real” value (푒푟푟% = (푚푒푎푠푢푟푒푑 − 푟푒푎푙)/푟푒푎푙)

Table 4.1 Absolute Snout Vent Ventral Area Surface Area Volume Average average error for each measurement on the 3D Two Heights 0.79% 0.94% 0.48% 1.01% 0.81% reconstruction technique. Walls 0.45% 1.63% 0.36% 1.55% 1.00%

As would be expected, the error related to the “two heights” configuration resulted in a smaller error. It is important to note that a snout-vent error of 0.79 % is at most a 0.48 mm difference from the original value, an accuracy which would hardly be achievable with a direct measurement of the live frog. Similarly, a maximum error of 0.34 cm2 in surface area and 0.25 cm3 in volume is hardly deterministic when the frog can move a leg slightly or flatten itself willingly to some extent.

4.4.1 Known Density Objects A total of six metal cylindrical or cuboid objects of either brass or aluminium were reconstructed using the same method. The density of aluminium and the brass used were well known, so their volume was readily available when the object’s weight was measured. Since they were all regularly shaped, their surface areas were also easily calculated, and so the technique could be set to a test. However, all of these objects were highly reflective, symmetric, and plainly textured, all characteristics counter indicated in Section 4.2.1, and their common errors shown in Figure 4.3. These being so, it is considered that the error associated with these renders should only be used as a reference maximum error, and not as a frequently occurring error when acquiring the frog models. Surface Volume Average In a similar way to the error Processed Models Two Heights 0.91% 2.54% 1.73% obtained for the 3D printed frogs, Walls 2.38% 5.70% 4.04% Table 4.2 shows the absolute Table 4.2 Absolute average error on processed 3D models. average errors for surface and volume measurements, as well as an overall average. The error

41

was calculated as with the previous precision test, where in this case the “real” value is the value obtained from direct measurements, and the “measured” value is that obtained

digitally. Again, the error related to the models rendered from single height images is significantly higher, and the error in volume measurement is greater than the error in surface calculation. It is clear that the error increased dramatically for both sets, but it is still worth mentioning that a 2.54 % or even 5.7 % change in volume in a frog is minimal compared with what they can change willingly, either moving, or urinating. Figure 4.7 Top: processed rendered cylinder. Centre: Deformities found The same models were also measured before the cleaning in rendered metal objects before the cleaning process. Bottom: Example of deformities found on frog models process (see Figure 4.7) described in Section 4.2.3 to try and due to head movement. quantify the extent in which human error is involved. It is important to note that the deformities caused by the properties of these models were much more pronounced than those caused by the frogs moving their heads while the photos were being taken, as can be seen in Figure 4.7. Perhaps surprisingly, the fixed deformities did not account for a major improvement in accuracy, as can be appreciated in Table 4.3, which shows the same error data obtained from the raw models. This led us to believe that the error introduced by the deformities caused by the head movement in live frogs would not contribute greatly to the error of the 3D rendering technique, at most increasing its value by a half.

Raw Models Surface Volume Average With this taken into account, the Two Heights 1.17% 3.99% 2.58% normally occurring error in the Walls 2.25% 6.80% 4.52%

Table 4.3 Absolute average error in render models prior to any processing. measurements obtained from frog 3D models will be treated as one and a half times the error obtained from the 3D printed models, which is less than 1.2 % in snout vent measurements and 2.5 % in surface and volume measurements.

42

5 Frog Surface Areas

The technique developed in the previous chapter offers enough accuracy to conduct research on the differences in surface area between closely related species. In the case of the Cruziohyla genus, this can be particularly interesting. The genus only comprises 2 species, and one of them (C. craspedopus) has evolved flanges that seem to intentionally enlarge its surface area, making its edge leaf-shaped, and the transition from the frog’s dorsal area to the leaf it is sitting on very smooth (see Figure 5.1). The other member of the genus (C. calacarifer) the almost stealthy transition between leaf and frog is not present, and a much more common over-all shape Figure 5.1 Cruziohyla craspedopus in its water can be observed (see Figure 5.2). conserving posture. Note the flaps on its hind legs. Although the simulator developed in this research has no particular interest in the differences between these species, the thermoregulation process does change significantly if the surface areas change. A way of being able to interpolate surface areas in frogs can then prove to be very Figure 5.2 Cruziohyla calcarifer. Note the absence of flaps and the steep angle at the edge in contact useful for the model. with the board.

In this chapter, a quick study on the surface area differences between the two Cruziohyla species is presented with the underlying motive for obtaining surface area interpolation methods. Two ways for interpolating the surface area of the frogs are discussed and the coefficients for these species are determined.

43

5.1 Acquired Data

In collaboration with the Vivarium at the Manchester Museum, a total of 23 C. craspeopus and 20 C. calcarifer of different sizes and at different stages of development were photographed. Their 3D models were rendered and their surface areas and volume were measured using the technique described in Chapter 4. The C. craspedopus specimens ranged from 3.1 cm snout-vent and 2 g, to 5.8 cm snout-vent and 15 g. This covers sizes from frogs a few weeks after hatching to nearly fully grown adults. The C. calcarifer specimens ranged from 3.3 cm snout-vent and 3 g, to 6.4 cm snout-vent and 23 g, which also covers from very young froglets, up to fully developed male adults, which are usually a bit smaller than adult females. As can be seen in Figure 5.3, there is a large overlap in frog sizes between the species. It is

Figure 5.3 Volume and surface areas plotted against the snout-vent length also clear that a relationship (top) and weight (bottom). Note the clear overlap between species. could be established for either “size” parameter (snout-vent or weight), and how the difference in surface areas is much more clear in one than in the other.

5.2 Interpolation from weight

In previous studies [6], [37], [38], the surface areas of anurans in either standard sitting position or water conserving posture are usually approximated as a power function of the frog’s weight:

푏 푑 퐴푑 = 푎(푤 ) 퐴푣 = 푐(푤 ) , (5.1)

44 where 퐴푑 and 퐴푣 are the dorsal and ventral areas, respectively, 푎, 푏, 푐 and 푑 are experimentally determined constants that vary between species, and 푤 is the frog’s weight. It is somewhat unexpected, nonetheless, that such an arbitrary relationship is allowed and even with no theoretical background and with its lack of consistency regarding the units, it is widely used. A dimensional analysis would yield that the weight, directly related to the frog’s volume through density, could be expected to have a relationship with surface areas like the one proposed in Equation (5.1) as long as values for 푏 and 푑 were at least very close to 0.66. However, values are reported [38] so remote as 0.226 for the Bufo boreas toad, and 0.273 for the Hyla cinerea frog. Despite this, the fit was tried for the measurements acquired for both species (see Figure 5.4), and the coefficients were found to have much more intuitive Figure 5.4 Surface areas plotted against the weight of the frog with a power values. For C. calcarifer, the function fit. Note how closely overlapped the fitted lines are. coefficients were found to be 푎 = 4.80, 푏 = 0.65, 푐 = 3.08 and 푑 = 0.66. For C. craspedopus, the coefficients were found to be 푎 = 5.04, 푏 = 0.63, 푐 = 2.92 and 푑 = 0.70.

5.3 Interpolation from snout-vent length

It is also natural to expect a relationship between the snout-vent length and the surface areas, and since it is a measurement reported for almost any report of a frog, it is very convenient to approximate the surface areas from it. As can be seen in Figure 5.5, there is a clear link between the snout-vent length squared and the surface areas, for which the Figure 5.5 Surface areas plotted against the snout-vent length squared, with interpolation is simply proposed a linear function fit. Note how the lines are clearly different. as a linear fit with the intercept forced to zero:

2 2 퐴푑 = (푑표푟푠푎푙)(퐿푠푣) 퐴푣 = (푣푒푛푡푟푎푙)(퐿푠푣) , (5.2)

45 where 푣푒푛푡푟푎푙 and 푑표푟푠푎푙 are the only coefficients that need to be experimentally determined, and 퐿푠푣 is the snout vent length. The coefficients for C. calcarifer were found to be 푑표푟푠푎푙 = 0.81 and 푣푒푛푡푟푎푙 = 0.53 whereas for C. craspedopus, they were found to be 푑표푟푠푎푙 = 0.85 and 푣푒푛푡푟푎푙 = 0.58. It is not strictly necessary to force the intercept to zero and, although they would be found to be negative in some cases (for the dorsal area of C. calcarifer, for example, the intercept is at negative 1.4 cm2), the range at which the equation would yield negative values is at very small snout-vent lengths, even smaller than the size of the tadpoles. However, forcing the intercept at zero makes comparing the frogs and surfaces much simpler.

5.4 Surface area comparison

It is already evident from Figure 5.4 and Figure 5.5 that there are two apparently contrasting results. On one hand, when the weight is used as a reference for the size of the frog, both species seem to have very similar surface areas. On the other hand, when the snout-vent is used as a reference, both ventral and dorsal areas seem to be distinct. In frogs from 3 g to 23 g, the average difference in dorsal areas between frogs of the same weight is 0.95 %, which is comfortably inside the error in our measurements reported in Chapter 4 at 2.5 % and is therefore insignificant. Conversely, two frogs of the same snout- vent length have a dorsal area difference of 4.8 %, which is clearly significant, even after the error is taken into account. Both interpolation models agree that the ventral area of C. craspedopus is greater than that of C. calcarifer, but they disagree in the magnitude of the difference. The average difference in ventral areas between frogs of the same weight is 4.5 % whereas if the snout-vent length is used as reference, the difference is 9 %. With this said, it is important to note that the weight of a frog can change significantly. Frogs have been reported to loose around 20 % of their body weight when their bladders are emptied [43]. The contents of the bladder were not rigorously monitored in the photographed frogs, for which the results may be compromised. However, due to the amount of data acquired and the fact that the relationship between weight and snout- vent length (see Figure 5.6) of the measured frogs is so direct, leads us to believe that the Figure 5.6 Snout-vent lengths plotted against weight.

46 data is still valid.

Although it is easy to agree that C. craspedopus has a larger ventral area, it is unclear how much larger it is. It is tempting to say that the dorsal area is also larger, but it all comes down to how the two frogs are compared. The issue then remains: the difference in surface areas depends on whether two frogs of the same snout-vent length or of the same weight are compared.

47

48

6 Measuring the Mass Transfer Coefficient

Water evaporation is one of the main cooling mechanisms for anurans, and the rate at which it takes place is very situation dependant. Changes in the surrounding air’s temperature, its relative humidity, the wind velocities present and the temperature of the frog itself will vary the rate at which water is being evaporated from (or condensed on) the specimen’s surface.

Another quantity, referred to as the mass transfer coefficient (ℎ푑), will also take a very important role in determining the power exchange taking place, but since so many factors affect the process, pin-pointing what it is that defines this coefficient is not trivial. It would seem, as Cussler [35] mentions, that there should be a relationship between ℎ푑 and the wind speed, and it is also intuitive to say that the shape and orientation of the frog relevant to the wind should have an effect on it, although [6] disputes that it affects it very slightly and only at high wind speeds.

Simulations are not commonly used, and values for ℎ푑 are not easy to find in the literature, which only leaves a single option. Experimental measurements have to be made.

6.1 Theoretical Background

As described in Chapter 2, the power exchange due to water evaporation is described by the energy required to evaporate or condense a certain amount of water

푃퐸푊퐿 = 퐿푚̇ , (6.1) where 퐿 is the evaporation or condensation latent heat of water, and 푚̇ is the rate at which water evaporates/condenses. Now, as expressed in Equation (2.6), the power exchanged through evaporative water loss (푃퐸푊퐿) is given by

푃퐸푊퐿 = 퐿ℎ퐷퐴푑(휌푠 − 휌푎) , (6.2)

49 where ℎ퐷 is the mass transfer coefficient, 퐴푑 is the frog’s dorsal area, 휌푠 is the water vapour density at the skin layer (considered as a completely saturated surface) and 휌푎 is that of the air further away from the frog, which has a value dependant on the ambient relative humidity. Therefore, the mass transfer rate is described as

푚̇ = ℎ푑퐴푑(휌푠 − 휌푎) . (6.3)

Since both 휌푠 and 휌푎 can be obtained from tables or from an exponential fit to those tables [22] as long as the relative humidity is known, the dorsal area can be measured using the technique described in Chapter 4 and the rate at which water evaporates is simply a mass change over a period of time, calculating ℎ푑 from experimental measurements seems trivial. The mass transfer can be obtained from Equation (6.3) as

푚̇ (6.4) ℎ푑 = , 퐴푑(휌푠 − 휌푎) and since 푚̇ is simply a mass change, it can be measured as (푚2 − 푚1)/푡 .

The fit described in [22] to obtain the saturation water vapour densities (휌푠푎푡) is given by 7235 (77.3450 + 0.0057 푇 − ) 0.0022 푒 푇 (6.5) 휌 = , 푠푎푡 푇9.2 3 where 휌푠푎푡 is given in kg/m , and 푇 is the temperature in °K. If the frog skin is approximated as a saturated surface, 휌푎 is equal to 휌푠푎푡 (using the frog’s temperature). For the air further away from the frog, 휌푎 is simply 휌푠푎푡 (using the air temperature) multiplied by the relative humidity [6]

휌 = 휌 휌 = 푅퐻 ∗ 휌 . (6.6) 푠 푠푎푡 (푇푓) 푎 푠푎푡 (푇푎)

Using Equation (6.4) in conjunction with (6.5) and (6.6) allows for calculating ℎ푑 from parameters that are easily measured experimentally.

6.2 Experimental Method

An adaptation was made from the experiment described by Tracy in [6]. Because a wind dependant result is expected [35], the experiment has to be conducted under regulated wind velocities, and repeated at different speeds. Therefore, a wind tunnel is ideal. Also as suggested in that paper, models of both agar and plaster of Paris were used for the tests. A total of 7 parameters have to be measured: mass, time, dorsal area, wind speed, temperature of the frog, air temperature and relative humidity. Although the orientation and shape of the frog have been presumed to be negligible at low wind speeds [6], they will also be considered in the experiment, which introduces two other parameters, at least qualitatively.

50

For each experiment the wind tunnel was set at a speed and left to stabilize. Then, a model or group of models were introduced to the wind tunnel and set at an angle of either 0° or 90° relative to the wind direction (see Figure 6.1) and left there for a few minutes until they reached thermal equilibrium. Once thermal equilibrium was reached, the model’s mass and temperature, as well as the air’s temperature and relative humidity, were monitored at regular intervals for a set period of time. The frog models had to be momentarily removed from the wind tunnel to be weighed each time. All models were left soaking overnight before being used in the experiment, to ensure that they started the experiment at the same room temperature and that the plaster models were completely saturated. As would be expected, the areas more exposed to the wind Figure 6.1 Top, a model inside the cooled further than the rest, generating a thermal gradient on wind tunnel at a 90° position. Bottom, thermal image of a model while in the the model (see Figure 6.1). An area of intermediate wind tunnel at a 0° position, showing the expected thermal gradient. temperature was always used when acquiring the temperature of the model. Five different model shapes, at two different orientations relative to the wind speed (either head on or perpendicular to it) and at 5 different wind velocities were used.

6.3 Models and Instrumentation

In order to produce accurate models with a known dorsal area, the 3D models produced using the technique described in Chapter 4 were sent to print, and moulds were made out of them. Both a positive plastic frog and a negative frog mould were printed so that models of both agar and plaster of Paris could be made, testing what Tracy claims in [6] about them both evaporating water similarly. The procedure followed for this was the following.

6.3.1 Agar Models A solution of 1.5 g of agar powder in 100 g of water was heated to boiling point using a hot plate with the magnetic stirrer always on.

51

As soon as the boiling started, the hot plate was turned off, leaving the solution to cool down with the stirrer still on. When the solution reached approximately 60 °C, it was a clear, bubble-free liquid, which was then poured into the plastic moulds (Figure 6.2 top). The plastic negatives were filled to the brim, and cooled at room temperature. Then, gentle pressure was applied on the agar from the edges and towards the centre, causing it to slowly be released from the mould (Figure 6.2 Figure 6.2 Agar model making process bottom).

6.3.2 Agar Moulds for Plaster of Paris Models A base of packing tape was prepared with the sticky side up. A plastic model was fixed on it, and the top of a plastic cup was set around the model. Agar mixture was prepared following the same process described for the agar models, and then poured in the bottomless cup until it covered the plastic model and 0.5 cm above it (Figure 6.3 top). Once cooled to room temperature, the plastic model was removed by

Figure 6.3 Agar mould gently flexing the agar mould (Figure 6.3 bottom). making process On a plastic cup of the same size, the same procedure was followed but without the plastic model inside it, creating a “lid” for the agar mould.

6.3.3 Plaster of Paris Models A mixture of 10 g of plaster of Paris and 7 g of water was thoroughly mixed, until no lumps or big bubbles could be seen in the mixture. It was then poured into the agar mould, until it completely filled it (Figure 6.4 top left). The mould’s lid was then put over it, and gently tapped in the centre, removing any surplus (Figure 6.4 top right). Once solidified, the plaster models were removed from

Figure 6.4 Plaster of Paris model making the agar moulds by gently flexing it (Figure 6.4 bottom process. left) and cleaned with running water. While still wet, the base was smoothed using wet & dry sandpaper. With the wet sandpaper on the table, the plaster frogs were gently rubbed until the burrs fell off (Figure 6.4 bottom right).

52

Models for one adult and one juvenile C. calcarifer, two juvenile C. craspedopus of different sizes, and one hemisphere were produced for the experiment in both agar and plaster.

6.3.4 Instrumentation The experiments took place in the facilities of the School of Mechanical, Aerospace and Civil Engineering at the University of Manchester, where the “Armfield Tunnel” was chosen for its capacity to produce steady low wind speeds (1 m/s to 5 m/s) needed for this experiment. The speed was measured with a precision of 0.1 m/s. The frog models were weighed using a Kern EMB500-1 precision scale with an accuracy of 0.1 g. The surface area of the models was the same as the moulds printed for them, for which accuracy similar to that of the 3D rendering technique is expected, i.e. an error of 2.5 %. The temperature of the frog was measured with an 8889 IR thermometer with an accuracy of 0.5 °C. The air temperature and relative humidity, were monitored with an HTD-625 hygrometer- thermometer with an accuracy of 0.5 °C and 2 % respectively. Measurements were taken every 5 minutes for wind speeds around 5 m/s, every 7.5 minutes for velocities around 3 and 4 m/s, and every 10 minutes for speeds around 1 and 2 m/s. The orientation of the models was only measured qualitatively.

6.4 Results and Discussion

A total of 80 complete measurements were acquired. Half of those were for agar models, set at approximately 1, 2, 3, 4 and 5 m/s wind speeds. All five differently shaped models were

0.08

tested at a 0° orientation (with Linear (All Models) the head pointing towards the 0.07 Power (All Models) 0.06 Expon. (All Models) wind). At 90° (perpendicular to Poly. (All Models) 0.05 the wind), only the models if the 0.04 two C. calcarifer and the bigger 0.03 y = 0.014e0.29x C. craspedopus were tested. 0.02 R² = 0.81 y = 0.0005x2 + 0.0068x + 0.01 0.01 R² = 0.79

The remaining 40 measurements y = 0.015x0.79 y = 0.0099x + 0.0059 Mass Transfer Coefficient ] m/s Coefficient [ TransferMass R² = 0.82 R² = 0.78 had the same experimental 0.00 0.00 1.00 2.00 3.00 4.00 5.00 6.00 configuration but used plaster of Wind Speed [m/s]

Figure 6.5 Mass transfer coefficient (ℎ푑) plotted against the wind velocity with Paris models. various fitted curves. Note how R2 is very similar in all of them.

53

0.08 0.08 CalcAdAgar - 0° CalcJuvAgar - 0° 0.07 0.07 CalcAdPlaster - 0° CalcJuvPlaster - 0°

0.06 0.06

CalcAdAgar - 90° CalcJuvAgar - 90° 0.05 0.05 CalcAdPlaster - 90° CalcJuvPlaster - 90°

[m/s] 0.04 0.04

[m/s]

d d d d

h 0.03 0.03 h 0.02 0.02 0.01 0.01 0.00 0.00 0.00 1.00 2.00 3.00 4.00 5.00 0.00 1.00 2.00 3.00 4.00 5.00 Wind Speed [m/s] Wind Speed [m/s] 0.08 0.08 CraspBAgar - 0° CraspSAgar - 0° 0.07 0.07 CraspBPlaster - 0° CraspSPlaster - 0°

0.06 0.06

CraspBAgar - 90° HemiAgar - 0° 0.05 CraspBPlaster - 90° 0.05 HemiPlaster - 0°

0.04 0.04

[m/s]

[m/s]

d d

d d 0.03 0.03

h h 0.02 0.02 0.01 0.01 0.00 0.00 0.00 1.00 2.00 3.00 4.00 5.00 0.00 1.00 2.00 3.00 4.00 5.00 Wind Speed [m/s] Wind Speed [m/s]

Figure 6.6 Mass transfer coefficient (ℎ푑) plotted against the wind velocity at which it was obtained. From the top left and clockwise, the plots are for the models for the adult C. calcarifer, then the juvenile C. calcarifer, then the bigger C. craspedopus and finally together the smaller C. craspedopus and the Hemisphere. Note the clear increase in ℎ푑 with increasing wind speed.

The acquired data had a large spread and was not easy to interpret, but it does shine light on the order of magnitude that ℎ푑 has. Regardless of the material model or orientation, the coefficient has values around 0.021 ± 0.003 m/s at wind speeds of 1.46 m/s, 0.027 ± 0.004 m/s at wind speeds of 2.12 m/s, and 0.033 ± 0.004 m/s at wind speeds of 2.82 m/s. At higher speeds, the standard deviation increases and the spread is clearer between models and orientations (see Figure 6.6 and Figure 6.5), just as [6] suggests. The coefficient averaged at 0.043 ± 0.008 m/s with wind speeds of 3.80 m/s, and 0.053 ± 0.009 m/s at wind speeds of 4.63 m/s. It is trivial to see that there is a relationship between the mass transfer coefficient and the wind speed when seen plotted against each other. However, as can be seen in Figure 6.5 the data is sufficiently spread out that it would fit almost any function. Therefore, our data neither 1/2 refutes nor proves the relationship ℎ푑 ~ 푣 proposed by Cussler in [35]. It is to be expected, however, that even when there is no wind (i. e. 푣 = 0 m/s) if the water vapour densities of the frog’s skin is greater than that of the air around it (휌푠 > 휌푎), there is some water evaporating from the frog, however small it may be. When 휌푠 < 휌푎 there should be at least a tiny amount of water condensing on the frog’s skin.

54

Therefore, from Equation (6.3), the mass transfer coefficient must have a non-zero intersection, and it should be positive:

푚̇ = ℎ푑퐴푑(휌푠 − 휌푎) → 𝑖푓 (휌푠 − 휌푎) ≠ 0 , ℎ푑 > 0 ∀ 푣 . (6.7) Now, when the obtained mass transfer coefficients are plotted against the square root of the wind speed, even if the models

Linear (C. calcarifer Juvenile) are taken independently and a 0.06 Linear (C. craspedupus Big) Linear (C. craspedupus Big) trend line is calculated for each Linear (C. craspedupus Small) 0.04 Linear (Hemisphere) Linear (All models) of them, they all show a 0.02 negative intercept (see Figure 6.7). Different powers of 푣 0.00 0.0 0.7 1.4 2.1 were tried, exponent values -0.02

from 0.3 to 0.8 were tested, but ] m/s Coefficient [ TransferMass -0.04 they all had the same problem. (Wind Speed)1/2 [(m/s)1/2]

It was not until ℎ푑 is compared Figure 6.7 Mass transfer coefficient vs the square root of the wind speed. Note to 푣0.9 that all the intersections that all the intercepts with 푣 = 0 m/s are negative. start to have a positive value. The values for 푅2 were compared to those of the linear relationship, ℎ푑~푣, and the latter resulted better, although there is a negligible difference. In a simple dimensional analysis, that there should be a linear relationship between the mass transfer coefficient and the wind speed is sensible. A linear relationship between the wind speed and the mass transfer coefficient can be seen plotted in Figure 6.8. As can be 0.08

C. calcarifer Adult seen, all intercepts are positive, 0.07 C. calcarifer Juvenile C. craspedupus Big 0.06 but they vary widely between C. craspedupus Small 0.05 Hemisphere frog models. At zero wind Linear (All Models) 0.04 y = 0.0099x + 0.0059 speed, however, it would be 0.03 R² = 0.78 expected that the only source of 0.02 y = 0.0093x + 0.0028 y = 0.0088x + 0.0084 R² = 0.87 R² = 0.86 variation between models was 0.01 y = 0.0097x + 0.0061 y = 0.01x + 0.0094 y = 0.014x + 0.0029

Mass Transfer Coefficient ] m/s Coefficient [ TransferMass R² = 0.88 R² = 0.93 R² = 0.94 the surface area, which is not 0.00 0.0 1.0 2.0 3.0 4.0 5.0 intrinsic to ℎ푑. Furthermore, Wind Speed [m/s] Figure 6.8 Mass transfer coefficient plotted against the wind speed. Each line apart from the hemispherical is for a different frog model. Note the variation in the intercept point. model, all the slopes have very close values, which would suggest that there is not a high increase in the spread of the mass transfer coefficient at higher wind speeds across different shapes or orientations.

55

With this in mind, a different relationship was sought. The best fit was found for an exponential function of a power function of the wind speed of the form

푘 푣푝 ℎ푑 = 퐴 푒 , (6.8) where 푣 is the wind speed in m/s and 퐴 , 푘 , and 푝 are experimentally determined constants. The value of 푝 was determined by maximizing 푅2 in a fit for all models (see Figure 6.9), which yielded 푝 = 0.39. It was then set to be constant between frog models. The other two parameters were allowed to change between models, and they average to 퐴 = 0.0041 m/s and 푘 = 1.40 (s/m)푝. The positive and non-zero intercept in all curves is immediately apparent. Moreover, it can be

0.08 C. calcarifer Adult y = 0.0029e1.52x noted how all the values for 퐴 0.07 C. calcarifer Juvenile R² = 0.93 y = 0.0048e1.29x converge at approximately C. craspedupus Big R² = 0.91 0.06 C. craspedupus Small y = 0.0041e1.39x 0.0041 m/s, which addresses Hemisphere R² = 0.90 0.05 1.25x Expon. (All Models) y = 0.0058e R² = 0.94 the concern noted for the linear 0.04 y = 0.0041e1.40x y = 0.0041e1.54x R² = 0.82 R² = 0.96 fit. Also, it is clear that the 0.03

0.02 curves start diverging at higher

0.01 wind velocities, which is in

Mass Transfer Coefficient ] m/s Coefficient [ TransferMass 0.00 concordance to what Tracy et al 0 0.5 1 1.5 2 (Wind Speed)p [(m/s)p] found [6]. Figure 6.9 Mass transfer coefficient plotted against the wind speed to the power of 0.39. It is imperative to stress, however, that this relationship is only proposed to fit the data with an emphasis on the intercept point, and there is no theoretical basis for it.

6.5 Conclusion

The acquired data shows that there is a clear link between the mass transfer coefficient and −2 the wind speed, and that ℎ푑 is of the order of 10 m/s at wind speeds between 1 and 5 m/s.

We did not find the functionality found in literature ℎ푑 ~ √푣 , particularly for low speeds. A linear relationship seems to address that issue, but the unexpected variation at the zero wind speed intercept makes its practicality at low wind speeds ambiguous.

푘 푣푝 A fit of the form ℎ푑 = 퐴 푒 was proposed to approximate values of the mass transfer coefficient, particularly at low wind speeds and the average values of 퐴, 푘 and 푝 were suggested.

56

7 Frog Simulator GUI

In order to test the hypothesis of pterorhodin (or the spectrum of the frog in general) affecting the thermoregulatory process, a comprehensive simulator was programmed using MATLAB and presented for the user as a graphical user interface (GUI). The theoretical framework has already been established and discussed in previous sections (see Chapters 2, 3, 4, 5 and 6), for which only its implementation is discussed in this chapter. The aim of this simulator is to be able to accurately calculate the equilibrium temperature at any moment in time for a frog of known reflection spectrum with relatively fixed ambient parameters. If a non-negligible temperature change is driven by the infra-red reflectance, it should be readily visible when the results of the simulation are compared for two different introduced spectra. The significance of such a hypothetical temperature difference should be determined by how it may help the frog in maintaining its humidity [11], [21], [24], how it may allow it to fight diseases [18], [23], or increase its metabolic rate [44]. In an attempt to minimize the necessary field measurements, it will be shown that most parameters can be approximated in at least one way, but to allow further precision, all of the parameters can be directly fed into the graphical user interface. Every approximation and input that is not explained in its own label was also given a tooltip, briefly describing its function.

7.1 Solar Irradiance Model

The energy that a frog absorbs from solar radiation is by far the main contributor to its temperature increase. Therefore, in order to accurately predict its temperature, the solar spectra and intensity has to be equally accurate.

57

7.1.1 Air Mass Approach Most engineering applications are satisfied by taking a standard solar irradiance spectra and dimming it through a factor called “Air Mass” (퐴푀), which is a relative optical path for the sun through the atmosphere. The 퐴푀 is equal to 1 for the sun directly on the zenith and at sea level, it increases as the solar elevation decreases (it is around 38 at sunrise/sunset), and increases at higher altitudes. Although always tabular values are used, Kasten and Young [25] propose an approximation equation for the air mass at sea level as a function of the solar elevation angle (훾, the complementary angle to the zenith angle (훾 = 90° − 휃푧)) in degrees:

−푐 −1 퐴푀(훾) = (푠𝑖푛(훾) + 푎 ∙ (훾 + 푏) ) (7.1) where 푎, 푏, and 푐 are constants. As the altitude increases, the air mass should decrease and therefore an altitude over sea level correction is sometimes introduced [45] based on Laue’s comments [46]. However, Laue also concludes that much greater changes occur due to gas concentration, pollution and humidity than due to changes in elevation. A study on UV radiation concludes that the altitude effect accounts for an increase of up to 24 % for each km change in elevation [47]. Nonetheless, such an increase is measured at 300 nm, and it drastically decreases to 11 % at 320 nm, and then slowly goes down to 9 % at 370 nm. Different approximations are found for different tables [45], but they were found to be inaccurate in different ways. Higher altitudes affect the UV part of the spectrum more and therefore attenuating the whole irradiance by a constant coefficient is too inaccurate for the calculations needed here. It will be noted, however, that the simulator offers an option to bypass the calculated solar spectrum, and if that is the user’s choice, using an appropriate 퐴푀 can be beneficial.

7.1.2 Solar Position Calculator Including the solar position change at different places on the planet and at different times of the year is an absolute necessity. Simple algorithms can be found to be more than accurate to what this research needs, such as Michalsky’s algorithm [29], available in Fortran, or Blanco- Muriel et al. PSA algorithm [28], available in C++. The former was noted to be malfunctioning at the southern hemisphere, for which Spencer proposed a modification [30]. Both codes were translated to MATLAB and tested. The Michalsky algorithm indeed fails at the southern hemisphere. Even after Spencer’s modification, the solar noon is shifted throughout the year, and through the whole day, which means that in August solar noon is at 4:00 am, which is clearly incorrect. On the other hand, the PSA algorithm predicts the solar azimuth and zenith angles at the locality specified with the

58 solar noon at the correct time (GMT, not including the daylight saving hour changes). Furthermore, Michalsky’s presents errors when used near the equator or the poles, whereas the PSA remains stable. The PSA algorithm is only recommended for the period 1999-2015, to insure a precision of 0.5 minutes of arc. This is far more than needed in the frog simulator and, therefore, the same code can be used to simulate the solar position for dates further into the future. A transcription of the translated code is available both at Appendix B and online, as the function named SolPos.m.

7.1.3 SMARTS Approach The National Renewable Energy Laboratory webpage allows users to download a program called “The Simple Model of the Atmospheric Radiative Transfer of Sunshine” (SMARTS) [26], which computes clear sky direct and diffuse spectral irradiances taking into account elevation changes, gas absorption and many other variables. It is important to note that the complexity of such a model makes it extremely precise, but also vastly complicated. Its source code in Fortran is also available to download, and therefore an attempt was made to translate a simplified version into MATLAB, which would serve the purpose of the frog simulator without overcomplicating it, nor compromising too much on the accuracy of the irradiance model. The outcome is equivalent to running the SMARTS program with many of its inputs fixed at values that are closer to what is needed in tropical forests. It requires only 7-8 inputs: latitude, altitude, air temperature, relative humidity, average day temperature, season, zenith angle and pressure (which if set at 0 will be automatically approximated), as opposed to dozens offered in the original code. The cost paid to reduce the amount of input data, was fixing the selection of a “Rural Aerosol Model”, the “Synthetic Solar Spectrum”, a “Standard Turbidity”, and the albedo of “Green Rye Grass”. Also, the options for “Radiometer”, “Smoothing”, “Illuminance” and “Special UV Calculations” were bypassed. To improve the efficiency of the translated code, it was then vectorised, avoiding unnecessary loops and duplication of data. To change from a loop to vector code language, some of the input absorptivity and albedo files were slightly modified, not from their real values but in shape and order, so that they could be directly read in the way that Matlab indexes elements in matrices. Abs_O3IR and Abs_O3UV were merged into a single matrix, Abs_SO2IR and Abs_SO2UV were merged, all absorptivities were filled with zeros in the wavelength gaps, albedo was completed as the original program interpolated it and some columns in the SO2 were multiplied for a factor, for which they are later divided in the code.

59

The whole translation process yielded a much more compact code of 700 lines (as opposed to 6000 of the original code). This is reflected in the processing time, which was reduced to about one tenth of the time. More importantly, it makes the solar spectrum generator natively compatible with the frog simulator. It is important to highlight that although many simplifications were made in the process, the resulting irradiance spectra are the same as Gueymard’s model yields with the indicated configuration. The translated and simplified SMARTS is used in combination with the translated PSA algorithm, which yields an accurate irradiance spectrum at any location and any time. A transcription of the translated code is available both at Appendix C and online, under the names GenSpec.m, which also calls Abs_Alb_Spec.mat, Ozon.m and Intp.m.

7.2 GUI Inputs and Functionality

The graphical user interface is divided into two main sections, the “Inputs” section on top, and the “Outputs” section at the bottom, as can be seen in Figure 4.2. The Input section is further subdivided into three sections: “Frog characteristics” shown in Figure 7.3, “Ambient Characteristics”

Figure 7.1 Screen capture of the Frog Simulator. The Inputs section can be shown in Figure 7.4, and “Location seen on top, and the Outputs section at the bottom. Characteristics” in Figure 7.5. It also includes the possibility to save the simulation data for further analysis, load previous simulation data, or save the plot as an image file. Most functions, inputs and approximation modes are described in tooltips that are shown when the mouse pointer hovers over them.

7.2.1 Frog Characteristics In this section, all the information that may change due to the frog specimen is found. Every aspect, from the spectrum of the frog to its thermal conductivity can be either set or approximated through customizable modes in this section.

60

7.2.1.1 Frog Spectrum First and foremost is the spectrum of the frog, which can be either loaded from an excel spreadsheet, or chosen from available spectra (which have been previously loaded). The file from which a spectrum may be loaded should be a two column spreadsheet with wavelengths in nm in the first column, and reflectivities on the second column. When a compatible file is loaded, an option is prompted for clipping the spectrum at wavelengths where the measurement is known to be accurate, referred to as the “confident Spectrum” (see Figure 7.2, top). When the spectrum is clipped, exponentially increasing/decreasing values are added to the edges, creating a spectrum that goes Figure 7.2 Top: Screen capture of the from 280 nm to 4000 nm (see Figure 7.2, bottom). The Confident Spectrum Clipping prompt. Bottom: Example of clipped spectra. Note 푒−5 the exponentially increasing/decreasing values go down to times the reflectivity value at the extrapolated values. edge of the spectrum. Also at that point, a normalization factor may be given. That is, reflectivities should have values between 0 and 1, so a factor to scale all reflectivities may be set at that point. If the given value is not greater or equal to the maximum reflectivity in the spectra, the latter will be used as a normalization value, overriding the introduced value. Once a spectrum has been imported, it will be saved for later use in the “Spectra” folder, and it will be automatically listed as an option in future runs.

7.2.1.2 Frog Size The density, weight, snout-vent length, dorsal area, ventral area and thickness of the frog may be set in this section. Strictly speaking, the first three inputs are only used if approximation modes are selected either for ventral and dorsal areas, thickness, or heat transfer coefficient. However, it is also useful to have them as a Figure 7.3 Screen capture of the Frog Characteristics section. reference to the frog’s shape and size that is being simulated. Three modes are offered to approximate areas (see Figure 7.3).

61

The first mode simply assumes a hemispherical frog, with ventral area equal to the cross sectional circle and the dorsal area equal to the surface area of half a sphere of the given diameter, hence

푑 2 푑 2 퐴푑 = 2 휋 ( ⁄2) and 퐴푣 = 휋 ( ⁄2) , (7.2) where 퐴푑 and 퐴푣 are the dorsal and ventral areas, and 푑 is the diameter of the hemisphere. As discussed in Chapter 5, two different fits were found to interpolate surface areas of frogs. One of them is through their weight, and it is covered in the second approximation mode as

푏 푑 퐴푑 = 푎 (푤푒𝑖푔ℎ푡) and 퐴푣 = 푐 (푤푒𝑖푔ℎ푡) , (7.3) where 푎, 푏, 푐, and 푑 are input parameters. The other fit to the area approximation is from the frog’s snout-vent length, and it is offered in the third approximation mode as

2 2 퐴푑 = (푑표푟푠푎푙) ∗ (푠푛표푢푡 − 푣푒푛푡) and (푣푒푛푡푟푎푙) ∗ (푠푛표푢푡 − 푣푒푛푡) , (7.4) where 푑표푟푠푎푙, and 푣푒푛푡푟푎푙 are input parameters. The thickness of the frog only offers one mode of approximation, and it does so as a disc of equal cross sectional area to the frog’s ventral area. The volume of the disc is calculated from the weight and density of the frog, so thickness of the disc is the frog’s volume divided by its ventral area

푡ℎ𝑖푐푘푛푒푠푠 = (푤푒𝑖푔ℎ푡/푑푒푛푠𝑖푡푦) / 푣푒푛푡푟푎푙 푎푟푒푎 , (7.5) as described in Chapter 3.

7.2.1.3 Thermal Properties The heat transfer coefficient, mass transfer coefficient, emissivity and thermal conductivity of the frog may be set in this section. There are two approximation modes for each convection coefficient.

The first heat transfer coefficient (ℎ푐) approximation mode first calculates the radius of a sphere based on the density and weight of the frog, as

3 퐿 = √푣표푙푢푚푒 = (푤푒𝑖푔ℎ푡/푑푒푛푠𝑖푡푦)1/3 , (7.6) where 퐿 is the radius of the sphere. Then, it uses that radius to calculate ℎ푐 through the method proposed by Mitchel in [19], described in Equation (3.6).

The second mode uses the method described by Porter and Gates in [5], described in Equation (3.5), with the inputted cylinder diameter.

62

The first mass transfer coefficient (ℎ푑) approximation mode uses the power function of wind speed fit described in Chapter 6 and given by

푓 ℎ푑 = 휖(푣 ) + 푔, (7.7) where 휖, 푓 and 푔 are inputs, and 푣 is the wind speed, an input at the ambient characteristics section.

The second mode uses the exponential fit, also described in that chapter, and given by

푘 푣푝 ℎ푑 = 퐴 푒 , (7.8) where 퐴, 푘 and 푝 are inputs, 푣 is the wind speed and 푒 is Euler’s number.

7.2.2 Ambient Characteristics In this section, all the information that may change due to changes in the environment around the frog is found. The temperature, relative humidity, kinematic viscosity and thermal conductivity of the air, as well as the wind speed and atmospheric pressure are found here. The latter is defaulted to “auto”, which automatically calculates the pressure through the SMARTS code, as described in Section 7.1.3. Also, the substrate’s temperature and thermal conductivity can be set.

Furthermore, a section on specifics about the frog’s orientation Figure 7.4 Screen capture of the Ambient Characteristics section. (described in Chapter 3) and shade percentage are found. The “Bypass direct beam projection” checkbox sets the surface through which the solar radiation is absorbed to a percentage of the dorsal area (determined by the user). As its name suggests, it bypasses the projection method described in Section 3.2.2. Additionally, there is an option to load an “Ambient Profile”, which includes information that changes through the day. If this option is selected, an excel spreadsheet with 5 columns should be provided, containing the time, air temperature, wind speed, relative humidity and substrate temperature in each column and in the given order. This, of course, makes longer period simulation much more realistic. Because these 5 inputs are going to be taken from the file, their direct input is disabled when the ambient profile is in use. The value displayed in them has no significance.

63

7.2.3 Location Characteristics As described in Section 7.1, the solar irradiance will vary with the location of the frog. Therefore, in order to calculate an accurate solar spectrum, the global position, date and time are necessary, all of which can be set here. The period for which the equilibrium temperature of the frog is simulated can also be set here, as well as the time steps taken through the simulation. There is an option to request the simulation in local time or in the Figure 7.5 Screen capture Greenwich Meridian Time (GMT), which simply shifts programmatically of the Location Characte- ristics section. the simulation start and end hours. Finally, there is an option to bypass the solar spectrum calculated as described in Section 7.1. This can be the case, for example, when a lamp is the radiation source, or when a direct reading was made. If this option is selected, an excel spreadsheet with wavelengths and irradiance values must be provided.

7.3 Outputs

As can be seen in Figure 7.6, most of the simulation results are presented in a plot, from which different power contributions can be turned on or off, as well as being able to show or hide the plot legend. Yet, two other results are shown at the bottom.

Figure 7.6 Screen capture of the Outputs section. Note the two numerical outputs at the bottom.

The first numerical output labelled “Total Water Lost” is the amount of water that would evaporate from a frog that undergoes the simulation parameters through the whole period in order to reach the equilibrium temperature shown in the plot. This number does not have any constrains, for which it can even be greater than the frog’s mass. It should be used as an indicative of whether a frog is capable of withstanding that scenario and for how long, before it needs to rehydrate.

64

The second numerical output labelled “Temperature Range” simply finds the maximum and minimum equilibrium temperatures of the frog in the simulation period. This can be especially helpful when two frogs are being compared. An additional output is discussed in Section 7.4, because it is only available from the file where the data is saved.

7.4 Save and Load

After a simulation has been completed, all the information used to run it, as well as all the outputs, can be saved to an excel file. The file will always be composed of three spreadsheets, one for the simulation inputs and outputs, one for the interpolated ambient profile, and one for the bypassing solar spectrum. The latter two will only contain data if their corresponding options were selected when the simulation was run. Since all the inputs and options are saved in the file, they can also be loaded back into the simulator for whatever purpose it may be. When loading a file, the simulator will try to find the appropriate frog spectrum in the “Spectra” folder, the used ambient profile and the bypassing solar spectrum (if any) in the specified directory. If the spectrum of the frog is not found, the inputs will not be loaded. If the ambient profile or bypassing solar spectrum are not found, all the rest of the data (including the results) will be loaded, but a warning message will be displayed prompting to relocate the missing files. The plot can also be saved directly into a “png” file, but since it is a bit image, it cannot be manipulated further. The outputs in the excel file, on the other hand, are arranged in a way that allows for very straightforward plotting. There is also an output in the spreadsheet that is not available in the simulator. It is located in the “Outputs” section, and it is the last column with results, under the title “Frog Weight”. The contents of this column represent the weight of the frog at every time, assuming that the weight loss is equivalent to the cumulative water evaporation. This is also particularly useful when comparing two frogs, but again, it is only to be used as indicative of how long a frog is capable of withstanding that scenario before rehydration is needed.

65

66

8 Simulation Results

Some of the experimental results have already been discussed in Chapters 5 and 6, but these were obtained with the purpose of being able to run a complete simulation of the thermoregulatory processes in tree frogs. As presented in Chapter 3, there are many parameters affecting the amount of power being absorbed or expelled from the frog, and therefore two scenarios are evaluated, both of them using all the different spectra mentioned in Section 3.2.3. First, the extreme case scenario is explored, where a frog is totally exposed to solar radiation on a clear day. This should yield the maximum difference in frogs with differing spectra. The second scenario is a more “natural” case, in which the frog is hanging from a leaf and therefore partially occluded. This should yield more realistic and frequently occurring results. In both cases, the ambient profile shown in Figure 8.1 was used for the simulation. It was obtained from interpolated meteorological reports from Amazonian forests [48], combined with the wind speed Figure 8.1 Ambient profile used in the simulations. The relative humidity was divided by a factor of 10 so that it could approximation described in Section 3.1.3. be shown next to the wind speed.

8.1 Extreme Case Scenario

The way in which a frog can receive the highest radiative power is if it sits flat on a completely exposed area, which means that there is nothing casting a shade nor dimming the radiating intensity throughout the simulation period. Although this is a very rare scenario (to say the

67 least), it is where the advantages of being able to reflect the light in the infra-red would be most apparent. The fact that the frog is sitting flat makes the absorbed solar radiation profile almost symmetric (see Figure 8.2), and the equilibrium temperature asymmetry through the day is only the result of the ambient profile used in the simulation.

Figure 8.2 Power contributions (left axis), and the resulting equilibrium frog temperature (right axis) plotted against time. At the top, the plot corresponds to Cruziohyla craspedopus (with pterorhodin) sitting flat and with no cover. At the bottom, the plot is for Hyla cinerea (without pterorhodin) in the same scenario. Note the different heights. The power contribution and equilibrium temperature profiles of a frog that reflects the light in the infra-red are of very similar shapes as those for a frog that does not (see Figure 8.2 Top and Bottom). However, there is a change in scale, making a slight cooling effect of the IR reflection evident. In this scenario, the black frog reached a maximum of 30.5 °C as opposed to the black IR reflecting frog, which only reached 27.7 °C. As for the real frog spectra, the difference between the highest and lowest maximum temperatures was 1.7 °C. The significance of this temperature difference is reflected in the ability of the frog to conserve its water. This process can be more easily appreciated in the plot in Figure 8.3, where the subtraction of the initial weight of the frog and the evaporated water is plotted against the time of the day. As highlighted in the simulator description (see Chapter 7), one must be careful when looking at these numbers. It was mentioned in Section 5.4 that frogs can hold up to 20 % of their weight in their bladder, and that should therefore indicate the limit at which this plot may be valid. A frog like the one used in this simulation, with an initial weight of 5.4 g, would be severely dehydrated at 4.8 g, and it would very likely try to rehydrate at that point.

68

Therefore, what Figure 8.3 shows is that, in this scenario, a completely black frog would need to rehydrate after about 3.7 hrs of sun exposure, wheras the black IR reflecting frog would only need rehydration after 4.3 hrs. As for the real frog spectra, the time difference between the maximum exposure time before Figure 8.3 Weight of the frog plotted against the time of day, rehydration was 0.4 hrs. assuming water evaporation is the only source of change. These differences in temperature (at most 9.5 %) and in maximum exposure time (at most 16.7 %) before rehydration show that the changes in the spectrum can contribute significantly in a completely exposed scenario, however infrequent it may be.

8.2 Partially Occluded Frog

The frogs to which the simulator is aimed are leaf-sitting frogs, which are usually nocturnal and sleep through the day. This means that, in order to avoid predators, they usually sit on leafs that are not completely exposed and therefore block part of the incoming solar radiation. Furthermore, as they are tilted, the projected area of the frog changes throughout the day, and the absorbed power varies accordingly. This is clearly reflected in the solar absorption profile (see Figure 8.4), which in turn acts on the equilibrium temperature profile.

Figure 8.4 Power contributions (left axis), and the resulting equilibrium frog temperature (right axis) plotted against time. The plot corresponds to Cruziohyla calcarifer (with pterorhodin) sitting on a leaf with a 65% shade, zenith angle of 70°, and azimuth angle of 20°. Note the asymmetry of the solar radiation contribution. The axis scales of Figure 8.4 compared to the ones in Figure 8.2 quickly show how drastic the change is between a realistic scenario and the completely exposed case. Evidently, this is reflected in the fact that the maximum temperature reached by the black frog was 25.5 °C, and the black IR reflecting frog peaks at 24.7 °C. As for the real frog spectra, the difference between the highest and lowest maximum temperatures was 0.5 °C.

69

In Figure 8.5, a closer inspection of the equilibrium temperature of all the spectra evaluated in these simulations is shown. As would be expected, the temperature of the completely absorbing spectrum (Black) and the one built to absorb all but the near infra- red light (Black IRR) serve as an envelope to

Figure 8.5 Temperature of all the simulated frogs in the the temperatures of the real frog spectra. partially occluded scenario. Note how the black and black IR reflecting frogs serve as an envelope for the other spectra. This indicates that it is then safe to assume (The Gastrotheca and Hyla species do not present reflectivity in the near infra-red). that these spectra reflect the limiting values. Again, the significance of the temperature difference must be evaluated through the ability of the frog to conserve its water. Following the same procedure as in the completely exposed scenario, what the plot in Figure 8.3 shows is that a completely black frog would need to rehydrate after about 4.6 hrs, and the black IR reflecting frog would need rehydration after 5.3 hrs. In the case of the real frog spectra, the time difference between the maximum exposure time before rehydration is Figure 8.6 Weight of the frog minus the evaporated water so far at that moment of the day in the partially occluded scenario. necessary was 0.4 hrs.

Interestingly, although the temperature difference between frogs with the infra-red reflection and without it reduces drastically in the realistic scenario, the difference in the time that they can be exposed before rehydration does not reduce as much. In this more realistic scenario, the difference in temperature by itself only accounts for a maximum 3.0 % temperature difference between a black frog that reflects the near infra-red and a black frog that doesn’t. On the other hand, this is reflected as a 13.6 % prolongation of the time they can be exposed, which seems to be a very significant increase in their water holding efficiency. In the spectra from real frogs, these percentages reduce to a maximum 1.9 % temperature difference, and a 8.5 % prolongation of the time they can be exposed, which may still be a relevant factor to avoid movement during the day.

70

71

72

9 Conclusions

A thorough exploration has been made on the thermoregulatory processes of tree frogs. The different components and the affecting parameters have been discussed and their relevance evaluated. A technique for accurately measuring surface areas and volumes through 3D rendering has been developed and used on two frog species, which have led us to propose two surface area interpolation methods within a species. The technique has been used to evaluate differences in surface areas between two species, and a question of how to compare the different frogs is presented. The mass transfer coefficient of frog models has also been experimentally determined, and its relationship with the wind speed exposed, yielding two extrapolation methods. A thorough simulation model has been built, and made available to the user as a graphical user interface. In it, all the results and approximation methods are included, and default parameters set to allow realistic simulations on its execution. Two scenarios have been simulated and presented in Chapter 8, showing that the infra-red reflection does seem to generate changes in the thermoregulatory processes, and these discrete changes can directly affect the water balance of the frogs. Although the resulting temperature difference seems negligible (up to 3 % in a realistic scenario), it reflects in a larger difference between rehydration periods (up to 13.6 % in the same circumstances). Whether this provides enough motivation for the evolution of pterorhodin or not is still an open question, but, contrary to what the literature suggests, the infra-red reflectivity does seem to have a significant impact on the thermal and water balance regulation processes.

It is worth mentioning that the validation of the model is still pending. Field trips were planned to acquire measurements to compare with the simulated results but, due to weather conditions, the data was not gathered. Also, the tests conducted on the simulator only included the spectra for 5 different frogs, for which further tests can be made before a

73 definitive conclusion can be drawn. On the other hand, the simulator is complete and ready to run any of the proposed tests, it yields data that is readily available to be compared with field data, and the generated Black and Black IRR spectra clearly show limits to what the thermoregulatory advantage of reflecting the infra-red could yield. If thermoregulation is discarded, crypticity seems to be the obvious choice to explain the presence of pterorhodin in anurans. Given the similar infra-red reflection peak on leaves, the pigment should act as a camouflage and avoid detection while sitting on them. However, no predators have been found that can see in this part of the spectrum. Another possibility could be thermal crypticity. Although the temperature regulation itself may not be of particular use, half a degree difference in temperature could provide just enough to allow the frogs to blend in with the environment, avoiding predation by snakes. Further studies on the use of this infra-red reflection for crypticity are needed before a reliable evolutionary trigger can be selected.

74

75

76

Appendix A, Frog Simulator Code

This appendix contains the code that corresponds to the graphical user interface and all of the sub-functions that were written from the beginning. See Chapter 7 for details on the inputs and functionality of the simulator. It is divided into 8 sections. First, the main function “FrogSimulator.m”, and then 7 sub functions, two of which are for the immediate operation of the GUI, and the remaining 5 that calculate the different power contributions to the thermoregulation.

FrogSimulator.m

%======Initialization Code===DO NOT EDIT======function varargout = FrogSimulator(varargin) %FROGSIMULATOR M-file for FrogSimulator.fig % FROGSIMULATOR, by itself, creates a new FROGSIMULATOR or raises the % existing singleton*. % % POWFUNCE = FROGSIMULATOR returns the handle to a new FROGSIMULATOR % or the handle to the existing singleton*. % % FROGSIMULATOR('Property','Value',...) creates a new FROGSIMULATOR % using the given property value pairs. Unrecognized properties are % passed via varargin to FrogSimulator_OpeningFcn. This calling % syntax produces a warning when there is an existing singleton*. % % FROGSIMULATOR('CALLBACK') and FROGSIMULATOR('CALLBACK',hObject,...) % call the local function named CALLBACK in FROGSIMULATOR.M with the % given input arguments. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help FrogSimulator

% Last Modified by GUIDE v2.5 10-Jul-2015 12:14:26

% Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @FrogSimulator_OpeningFcn, ... 'gui_OutputFcn', @FrogSimulator_OutputFcn, ... 'gui_LayoutFcn', [], ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end %======End of Initialization Code======

%======Executes just before FrogSimulator is made visible ======%======Executes just before FrogSimulator is made visible ======function FrogSimulator_OpeningFcn(hObject, ~, handles, varargin) %Loads the spectra in folder "Spectra" and shows them in pop up list allinSpectra=dir('Spectra'); %Lists all available contents in folder Spectra m=1; %Initializes position counter for n=1:length(allinSpectra) if strcmp(allinSpectra(n,1).name,'.')||... %Skips empty elements strcmp(allinSpectra(n,1).name,'..') else spectrainspectra{m,1}=allinSpectra(n,1).name; %Writes current element to temporary array m=m+1; %Increases position counter end end if m==1 spectrainspectra{m,1}=' '; %Creates empty name if no elements were found end set(handles.listspectra,'String',spectrainspectra); %Sets the drop down menu elements

%Creates 2 overlapped axes and labels them %Axis for power set(get(handles.axpow, 'Parent'), 'HandleVisibility', 'on'); %set handle visibility to on xlabel(handles.axpow,'Hour of the day'); %X label ylabel(handles.axpow,'Contributed Power [W]'); %Y label 77

78

%Axis for temperature handles.axtemp = axes('Units', 'character','Parent',handles.Outputs); %create a new axes in outputs and set units to be character set(handles.axtemp,'Position',get(handles.axpow,'Position'),... %position the new axis on the earlier existing axis 'YAxisLocation','right',... %Y axis to the right 'Color','none',... %Background transparent 'YColor','k'); %Y axis black ylabel(handles.axtemp,'Temperature [°C]'); %Y label handles.Legend={}; %initializes a legend array

%Sets tooltips for selected inputs and outputs set(handles.listspectra,'TooltipString',... %Frog Spectra List sprintf(['Select an already available frog''s spectrum or load a \n'... 'new one using the import button'])); set(handles.import,'TooltipString',... %Import Frog Spectrum sprintf(['Import a spectrum from an excel spreadsheet with only \n'... 'two columns, the first one for the wavelengths [nm] and \n'... 'the second for reflectivities. It should contain only \n'... 'values (no headings). Also, it will require you to input\n'... 'a wavelength range and a normalization factor. Only the\n'... 'data inside of that range will be kept, and the reflec-\n'... 'tivities will be divided by the normalization factor.'])); set(handles.hemisphere,'TooltipString',... %Approx Area, Hemisphere sprintf(['Calculates the dorsal area of the frog as half a sphere\n'... 'of the given diameter and its ventral area as a circle\n'... 'of the same diameter.'])); set(handles.weight,'TooltipString',... %Approx Area, Weight sprintf(['Calculate both dorsal and ventral area from a given\n'... 'weight of a frog, using the relationships:\n'... ' DorsalArea=a*Weight^b VentralArea=c*Weight^d '])); set(handles.snout,'TooltipString',... %Approx Area, Snout-Vent sprintf(['Calculate both dorsal and ventral area as a function of\n'... 'the snout-vent length of the frog squared, i.e.: \n'... 'VentralArea=ventral*SntVt^2 DorsalArea=dorsal*SntVt^2'])); set(handles.approxthick,'TooltipString',... %Approx Thickness sprintf(['Calculates the thickness of the frog as if it was a flat\n'... 'slab of cross sectional area equal to the ventral area \n'... 'and volume equal to the volume of the frog, which is in \n'... 'turn calculated from its weight and density: \n'... ' Thickness=Volume/Ventral Area'])); set(handles.sphere,'TooltipString',... %Approx Heat Transfer, Weight Calculated Sphere sprintf(['Calculates the heat transfer coefficient for the frog as\n'... 'if it was a sphere with a diameter calculated from the \n'... 'cubic root of its volume, which is in turn calculated \n'... 'from its weight and density.'])); set(handles.cylinder,'TooltipString',... %Approx Heat Transfer, Cylinder sprintf(['Calculates the heat transfer coefficient for the frog \n'... 'as if it was a smooth cylinder with a specified diameter.'])); set(handles.powfunc,'TooltipString',... %Mass Transfer Approx, Power Function sprintf(['Calculate the mass transfer coefficient of the frog as \n'... 'if it was a power function of the wind speed of the form\n'... ' hd = e*(windspeed^f)+g'])); set(handles.expfunc,'TooltipString',... %Mass Transfer Approx, Exponential Function sprintf(['Calculate the mass transfer coefficient of the frog as \n'... 'if it was an exponential function of the wind speed of \n'... 'the form: hd = A*exp(k*(windspeed^p))'])); set(handles.shade,'TooltipString',... %Shade Percentage sprintf(['Percentage of the dorsal area shaded by something over\n'... 'over the frog, such as leaves, trees, clouds, etc. The\n'... 'direct solar absorption will be scaled using this factor.'])); set(handles.frogzen,'TooltipString',... %Frog Zenith Angle sprintf(['Angle measured from the normal to the ground towards the\n'... 'normal to the frog''s ventral area. It can take values \n'... 'from 0° (for a horizontal frog), through 90° (for a \n'... 'tical frog) and up to 180° (for an upside down frog).'])); set(handles.frogazim,'TooltipString',... %Frog Azimuth Angle sprintf(['Angle measured from the North, clockwise, towards the \n'... 'normal to the frog''s ventral area. It can take values \n'... 'from 0° to 360°. An angle of 0° means that the frog has \n'... 'its dorsal area exposed to the North, 90° to the East,\n'... '180° South, and 270° West.'])); set(handles.bypproj,'TooltipString',... %Bypass Projection Factor sprintf(['Bypasses the projection factor that would be calculated \n'... 'with the frog''s zenith and azimuth angles, and uses a \n'... 'fixed value inputed below. The default value is obtained\n'... 'as 1.1*ventral/dorsal, which is usually slightly above \n'... 'the maximum percentage of exposed dorsal area.'])); set(handles.project,'TooltipString',... %Bypass Projection Factor sprintf(['Percentage of dorsal area exposed to direct and normal\n'... 'solar radiation. The default value is usually slightly\n'... 'above the maximum percentage of exposed dorsal area, and\n'... 'it is calculated as 1.1*ventral/dorsal.'])); set(handles.bypsol,'TooltipString',... %Bypass Solar Spectrum sprintf(['Bypasses the solar spectrum calculation and uses the \n'... 'given spectrum throughout the whole simulation period.\n'... 'The spectrum should be a two column excel spreadsheet \n'... 'with wavelengths [nm] on the first column, and direct \n'... 'irradiances [W/(m2 nm)] on the second. Diffuse lighting \n'... 'is defaulted to 10% of the direct lighting.'])); set(handles.profile,'TooltipString',... %Ambient Profile sprintf([' \n'... 'Allows for an ambient profile to be inported. It should \n'... 'be presented as a 5 column .xlsx file with the varying \n'... 'ambient parameters for the simulation period, including \n'... 'Time, Air Temperature, Wind Speed, Relative Humidity and\n'... 'Substrate Temperature (in that order). \n'... 'Note that if the convection coefficients are being \n'... 'approximated, they will vary through the simulation.'])); set(handles.load,'TooltipString',... %Load Simulation Data 79

80

sprintf(['Loads the data with which a previous simulation was made\n'... 'and automatically runs the simulation again. \n'... 'The spectra used have to be available.'])); set(handles.save,'TooltipString',... %Save Simulation Data sprintf(['Saves all the imput data, approximation choices, spectra\n'... 'names and results to an excel spreadsheet in the chosen\n'... 'file path.'])); set(handles.saveplot,'TooltipString',... %Save Plot sprintf(['Saves the plot being displayed at the moment as a .png \n'... 'file in the chosen path.'])); set(handles.txttotwatlost,'TooltipString',... %Total Water Lost sprintf(['Water lost through evaporative cooling in the whole \n'... 'simulated period.'])); set(handles.txttemprange,'TooltipString',... %Temperature Range sprintf(['Minimum and maximum equilibrium temperatures reached by \n'... 'the frog in the whole simulation period.']));

handles.output = hObject; % Choose default command line output for DayLongInterface guidata(hObject, handles); % Update handles structure

movegui(hObject,'center'); %Centres gui in the screen %======%======

%==== Outputs from this function are returned to the command line. ======function varargout = FrogSimulator_OutputFcn(~, ~, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure varargout{1} = handles.output; %======

%======%======

%------IMPORT BUTTON ------%------IMPORT BUTTON ------function import_Callback(~, ~, handles)

[filename,filefolder,~]=uigetfile('*.xlsx'); %Prompts for spectrum file path selection

if filename~=0 %Only continues if a file was chosen (if "Cancel" wasn't selected) inputsneeded={sprintf(['The data is going to be clipped with the',... %Sets a message for clipping the data in the given wavelength 'following limits:\nLower wavelength:']),... range and normalization factor. 'Upper wavelength:','Normalization factor:'}; defaultanswers={'450','950','100'}; %Sets default answers to 450 nm to 950 nm, and normalize to 100. answerrows=[1,50;1,50;1,50]; %Sets the size of the answer boxes clippingdata=inputdlg(inputsneeded,'Confident Spectrum Clipping',... %Prompts with the message and default answers. answerrows,defaultanswers);

if ~isempty(clippingdata) %Only continues if there is a valid answer (if "Cancel" wasn't selected) load('Abs_Alb_Spec','SynthSolarSpectrumGueymard'); %Loads the chosen file Spectrum=SpectrumImport(fullfile(filefolder,filename),... %Calls SpectrumImport, which clips the data and normalizes str2double(clippingdata(1)),str2double(clippingdata(2)),... reflectivities. str2double(clippingdata(3)),SynthSolarSpectrumGueymard(:,1)/10); %Locally saves the spectrum matrix with the original file name newname=strtok(filename,'.'); %Copies the file name without the file type eval([newname '=Spectrum;']); %Copies the matrix to a variable named like the file save(['Spectra\' newname],eval('newname')); %Saves the spectrum with its original name to the "Spectra" folder %Adds and selects the imported spectrum in the spectra list elements=get(handles.listspectra,'String'); %Gets the current elements in the list newspecposition=size(elements,1)+1; %Calculates the position for the spectrum being imported elements{newspecposition}=[newname '.mat']; %Adds the element to the list set(handles.listspectra,'String',elements); %Updates the elements in the list set(handles.listspectra,'Value',newspecposition); %Selects the imported spectrum end end %------%------

%------INPUT DENSITY ------%------INPUT DENSITY ------function dens_Callback(~, ~, handles) if get(handles.approxhc,'Value')&&get(handles.sphere,'Value') %If the heat transfer coefficient is being approximated as a sphere approxhc_Callback(handles.approxhc,[],handles) %Recalculates hc through a fake callback end if get(handles.approxthick,'Value') %If the thickness is being approximated approxthick_Callback(handles.approxthick, [], handles) %Recalculates thickness through a fake callback end %------%------

%------INPUT WEIGHT ------%------INPUT WEIGHT ------function w_Callback(~, ~, handles) if get(handles.approxhc,'Value')&&get(handles.sphere,'Value') %If the heat transfer coefficient is being approximated as a sphere approxhc_Callback(handles.approxhc,[],handles) %Recalculates hc through a fake callback end if get(handles.approxareas,'Value')&&get(handles.weight,'Value') %If areas are being approximated from weight approxareas_Callback(handles.approxareas, [],handles) %Recalculates areas through a fake callback end if get(handles.approxthick,'Value') %If the thickness is being approximated approxthick_Callback(handles.approxthick, [], handles) %Recalculates thickness through a fake callback end %------%------

%------INPUT SNOUT-VENT ------%------INPUT SNOUT-VENT ------function snoutvent_Callback(~, ~, handles) 81

82

if get(handles.approxareas,'Value')&&get(handles.snout,'Value') %If areas are being approximated from snout vent approxareas_Callback(handles.approxareas,[], handles) %Recalculates areas through a fake callback end %------%------

%------INPUT VENTRAL-AREA ------%------INPUT VENTRAL-AREA ------function va_Callback(~, ~, handles) if get(handles.approxthick,'Value') %If the thickness is being approximated approxthick_Callback(handles.approxthick, [], handles) %Recalculates thickness through a fake callback end %------%------

%------APPROXIMATE AREAS ------%------APPROXIMATE AREAS ------function approxareas_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked set(handles.da,'Enable','off'); %Disables dorsal area input set(handles.va,'Enable','off'); %Disables ventral area input set(handles.areas,'Visible','on'); %Shows aproximation options EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.areas,'SelectedObject')); areas_SelectionChangeFcn(handles.areas, EvDat, handles) %Recalculates areas through a fake callback else %If unticked set(handles.areas,'Visible','off'); %Hides aproximation options set(handles.da,'Enable','on'); %Enables dorsal area input set(handles.va,'Enable','on'); %Enables ventral area input end %------%------

%------APPROXIMATE THICKNESS ------%------APPROXIMATE THICKNESS ------function approxthick_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked set(handles.thick,'Enable','off'); %Disables thickness input %Calculates thickness as a column weight=(str2double(get(handles.w,'String'))); %Reads weight density=str2double(get(handles.dens,'String')); %Reads density ventarea=str2double(get(handles.va,'String')); %Reads ventral area vol=weight/density; %Calculates volume as weight/density thickness=(vol/ventarea); %Calculates thickness as volume/ventral area set(handles.thick,'String',thickness); %Displays calculated thickness else %If unticked set(handles.thick,'Enable','on'); %Enables thickness input end %------%------

%------AREA APPROXIMATION CHOICE ------%------AREA APPROXIMATION CHOICE ------function areas_SelectionChangeFcn(~, eventdata, handles) switch get(eventdata.NewValue,'Tag') %Gets the tag of the selected area approximation choice case 'hemisphere' %If approximated as hemisphere set(handles.diam,'Enable','on'); %Enables the diameter section set(handles.a,'Enable','off'); %Disables weight section set(handles.b,'Enable','off'); % set(handles.c,'Enable','off'); % set(handles.d,'Enable','off'); % set(handles.svent,'Enable','off'); %Disables the snout-vent section set(handles.sdors,'Enable','off'); % %Computes areas as hemispheres and displays them rad=(str2double(get(handles.diam,'String')))/2; %Reads hemisphere radius (diameter/2) in cm dorsa=2*pi()*((rad)^2); %Calculates dorsal area as half the surface of a sphere venta=pi()*((rad)^2); %Calculates ventral area as a circle set(handles.da,'String',dorsa); %Displays calculated dorsal area in cm2 set(handles.va,'String',venta); %Displays calculated ventral area in cm2

case 'weight' %If approximated from weight set(handles.diam,'Enable','off'); %Disables the diameter section set(handles.a,'Enable','on'); %Enables weight section set(handles.b,'Enable','on'); % set(handles.c,'Enable','on'); % set(handles.d,'Enable','on'); % set(handles.svent,'Enable','off'); %Disables the snout-vent section set(handles.sdors,'Enable','off'); % %Computes areas from weight of the frog we=(str2double(get(handles.w,'String'))); %Reads weight in grams vala=(str2double(get(handles.a,'String'))); %Reads a valb=(str2double(get(handles.b,'String'))); %Reads b valc=(str2double(get(handles.c,'String'))); %Reads c vald=(str2double(get(handles.d,'String'))); %Reads d dorsa=vala*(we^valb); %Calculates dorsal area as a*W^b venta=valc*(we^vald); %Calculates ventral area as c*W^d set(handles.da,'String',dorsa); %Displays calculated dorsal area in cm2 set(handles.va,'String',venta); %Displays calculated ventral area in cm2

case 'snout' %If approximated from snout-vent set(handles.diam,'Enable','off'); %Disables the diameter section set(handles.a,'Enable','off'); %Disables weight section set(handles.b,'Enable','off'); % set(handles.c,'Enable','off'); % set(handles.d,'Enable','off'); % set(handles.svent,'Enable','on'); %Enables the snout-vent section set(handles.sdors,'Enable','on'); % %Computes areas from snout-vent length of the frog snvt=(str2double(get(handles.snoutvent,'String'))); %Reads snout-vent in cm vala=(str2double(get(handles.svent,'String'))); %Reads valb=(str2double(get(handles.sdors,'String'))); %Reads dorsa=valb*(snvt^2); %Calculates dorsal area as b*(Snout-Vent)^2 venta=vala*(snvt^2); %Calculates ventral area as a*(Snout-Vent)^2 set(handles.da,'String',dorsa); %Displays calculated dorsal area in cm2 set(handles.va,'String',venta); %Displays calculated ventral area in cm2 end 83

84

if get(handles.approxthick,'Value') %If the thickness is being approximated approxthick_Callback(handles.approxthick, [], handles) %Recalculates thickness through a fake callback end %------%------

%------INPUT AREA APPROXIMATION CONSTANTS ------%------INPUT AREA APPROXIMATION CONSTANTS ------function const_Callback(~, ~, handles) EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.areas,'SelectedObject')); areas_SelectionChangeFcn(handles.areas, EvDat, handles) %Recalculates areas through a fake callback %------%------

%------APPROXIMATE HEAT TRANSFER ------%------APPROXIMATE HEAT TRANSFER ------function approxhc_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked set(handles.hc,'Enable','off'); %Disables heat transfer coefficient input set(handles.heattransf,'Visible','on'); % Shows aproximation options EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.heattransf,'SelectedObject')); heattransf_SelectionChangeFcn(handles.heattransf, EvDat, handles) %Recalculates heat transfer coefficient through a fake callback else %If unticked set(handles.heattransf,'Visible','off'); %Hides aproximation options set(handles.hc,'Enable','on'); %Enables heat transfer coefficient input end %------%------

%------APPROXIMATE MASS TRANSFER ------%------APPROXIMATE MASS TRANSFER ------function approxhd_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked set(handles.hd,'Enable','off'); %Disables mass transfer coefficient input set(handles.masstransf,'Visible','on'); %Shows aproximation options EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.masstransf,'SelectedObject')); masstransf_SelectionChangeFcn(handles.masstransf, EvDat, handles) %Recalculates mass transfer coefficient through a fake callback else %If unticked set(handles.masstransf,'Visible','off'); %Hides aproximation options set(handles.hd,'Enable','on'); %Enables the heat transfer coefficient input end %------%------

%------HEAT TRANSFER APPROXIMATION CHOICE ------%------HEAT TRANSFER APPROXIMATION CHOICE ------function heattransf_SelectionChangeFcn(~, eventdata, handles) switch get(eventdata.NewValue,'Tag') %Gets the tag of the selected hc approximation choice case 'sphere' %If approximated as sphere of weigh calculated radius set(handles.diamcyl,'Enable','off'); %Disables the cylinder section kair=str2double(get(handles.condair,'String')); %Reads air conductivity ws=str2double(get(handles.windspeed,'String')); %Reads windspeed vis=(str2double(get(handles.visc,'String')))/10000; %Reads air kinematic viscosity and converts to m2/s densval=str2double(get(handles.dens,'String'))*1000; %Reads frog's densityand converts to g/m3 mass=str2double(get(handles.w,'String'))/1000; %Reads frog's mass and converts to kg hcvalue=0.34*kair*((ws/vis)^0.6)*((densval/mass)^(0.4/3)); %Computes hc for a spheric frog with radius r=(volume)^(1/3) set(handles.hc,'String',hcvalue); %Displays calculated hc case 'cylinder' %If approximated as smooth cylinder set(handles.diamcyl,'Enable','on'); %Enables the cylinder section diamcyl_Callback(handles.diamcyl, [], handles) %Recalculates hc through a fake callback end %------%------

%------INPUT CYLINDER DIAMETER ------%------INPUT CYLINDER DIAMETER ------function diamcyl_Callback(~, ~, handles) k=3.628908403; %Defines the smooth cylinder convection coefficient ws=str2double(get(handles.windspeed,'String')); %Reads wind speed fd=str2double(get(handles.diamcyl,'String'))/100; %Reads cylinder diameter and converts it to m hcvalue=k*((ws/(fd^2))^(1/3)); %Computes the heat transfer coefficient for a smooth cylinder set(handles.hc,'String',hcvalue); %Displays calculated hc %------%------

%------MASS TRANSFER APPROXIMATION CHOICE ------%------MASS TRANSFER APPROXIMATION CHOICE ------function masstransf_SelectionChangeFcn(~, eventdata, handles) switch get(eventdata.NewValue,'Tag') %Gets the tag of the selected area approximation choice case 'powfunc' %If approximated as a power function of wind speed set(handles.powfunce,'Enable','on'); %Enables power function section set(handles.powfuncf,'Enable','on'); % set(handles.powfuncg,'Enable','on'); % set(handles.expfuncA,'Enable','off'); %Disables exponential function section set(handles.expfunck,'Enable','off'); % set(handles.expfuncp,'Enable','off'); % eval=str2double(get(handles.powfunce,'String')); %Reads slope (e) fval=str2double(get(handles.powfuncf,'String')); %Reads power (f) gval=str2double(get(handles.powfuncg,'String')); %Reads y intersection (g) ws=str2double(get(handles.windspeed,'String')); %Reads wind speed (ws) hdval=eval*(ws^fval)+gval; %Calculates hd as a power function of wind speed (hd=e*(ws)^f + g) set(handles.hd,'String',hdval); %Displays calculated hd case 'expfunc' %If approximated as an exponential function of windspeed set(handles.powfunce,'Enable','off'); %Disables power function section set(handles.powfuncf,'Enable','off'); % set(handles.powfuncg,'Enable','off'); % set(handles.expfuncA,'Enable','on'); %Enables exponential function section set(handles.expfunck,'Enable','on'); % set(handles.expfuncp,'Enable','on'); % Aval=str2double(get(handles.expfuncA,'String')); %Reads amplitud (A) kval=str2double(get(handles.expfunck,'String')); %Reads exponential constant (k) pval=str2double(get(handles.expfuncp,'String')); %Reads windspeed power (p) ws=str2double(get(handles.windspeed,'String')); %Reads wind speed (ws) hdval=Aval*exp(kval*(ws^pval)); %Calculates hd as an exp. function of windspeed (hd=A*exp(k*((ws)^p)) set(handles.hd,'String',hdval); %Displays calculated hd end %------%------85

86

%------INPUT hd CONSTANTS ------%------INPUT hd CONSTANTS ------function hdconst_Callback(~, ~, handles) EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.masstransf,'SelectedObject')); masstransf_SelectionChangeFcn(handles.areas, EvDat, handles) %Recalculates hd through a fake callback %------%------

%------INPUT WIND SPEED ------%------INPUT WIND SPEED ------function windspeed_Callback(~, ~, handles) if get(handles.approxhc,'Value') %If the heat transfer coefficient is being approximated approxhc_Callback(handles.approxhc, [], handles); %Recalculates hc through a fake callback end if get(handles.approxhd,'Value') %If the mass transfer coefficient is being approximated approxhd_Callback(handles.approxhd, [], handles); %Recalculates hd through a fake callback end %------%------

%------INPUT VISCOCITY ------%------INPUT VISCOCITY ------function visc_Callback(~, ~, handles) if get(handles.approxhc,'Value')&&get(handles.sphere,'Value') %If the heat transfer coefficient is being approximated as a sphere approxhc_Callback(handles.approxhc, [], handles); %Recalculates hc through a fake callback end %------%------

%------INPUT AIR CONDUCTIVITY ------%------INPUT AIR CONDUCTIVITY ------function condair_Callback(~, ~, handles) if get(handles.approxhc,'Value')&&get(handles.sphere,'Value') %If the heat transfer coefficient is being approximated as a sphere approxhc_Callback(handles.approxhc, [], handles); %Recalculates hc through a fake callback end %------%------

%------INPUT FROG ZENITH ANGLE ------%------INPUT FROG ZENITH ANGLE ------function frogzen_Callback(~, ~, handles) fzenith=str2double(get(handles.frogzen,'String')); %Gets frog zenith angle if fzenith<0||fzenith>180 %Validates zenith angle value msgbox('The frog zenith angle has to be between 0 and 180°.'); %Prompts with error message set(handles.frogzen,'String',0); %Sets zenith angle to zero end %------%------

%------INPUT FROG AZIMUTH ANGLE ------%------INPUT FROG AZIMUTH ANGLE ------function frogazim_Callback(~, ~, handles) fazimuth=str2double(get(handles.frogazim,'String')); %Gets frog azimuth angle if fazimuth<0||fazimuth>360 %Validates azimuth angle value msgbox('The frog azimuth angle has to be between 0 and 360°.'); %Prompts with error message set(handles.frogazim,'String',0); %Sets azimuth angle to zero end %------%------%------BYPASS PROJECTION CALCULATION ------%------BYPASS PROJECTION CALCULATION ------function bypproj_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked set(handles.frogzen,'Enable','off'); %Disable frog zenith angle input set(handles.frogazim,'Enable','off'); %Disable frog azimuth angle input da=str2double(get(handles.da,'String')); %Gets current dorsal area value va=str2double(get(handles.va,'String')); %Gets current ventral area value proj=1.1*va/da; %Suggests a value of 1.1*ventral/dorsal, which is set(handles.project,'String',proj); %approximately the maximum exposed area. set(handles.txtproject,'Visible','on'); %Shows projection factor label set(handles.project,'Visible','on'); %Shows projection factor input set(handles.projectunits,'Visible','on'); %Shows projection factor units else %If unticked set(handles.frogzen,'Enable','on'); %Enable frog zenith angle input set(handles.frogazim,'Enable','on'); %Enable frog azimuth angle input set(handles.txtproject,'Visible','off'); %Hides projection factor label set(handles.project,'Visible','off'); %Hides projection factor input set(handles.projectunits,'Visible','off'); %Hides projection factor units end %------%------

%------INPUT PROJECTION FACTOR ------%------INPUT PROJECTION FACTOR ------function project_Callback(~, ~, handles) projection=str2double(get(handles.project,'String')); %Gets projection factor if projection<0||projection>100 %Validates projection value msgbox('The projection factor has to be between 0 and 100%.'); %Prompts with error message set(handles.project,'String',1); %Sets projection factor to one end %------%------

%------USE AMBIENT PROFILE ------%------USE AMBIENT PROFILE ------function profile_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked %Gets the file from which data is going to be loaded if isempty(get(handles.profilepath,'String')) %If there is no path available yet [filename,filefolder,~]=uigetfile('.xlsx'); %Prompts for path selection path=fullfile(filefolder,filename); %Saves the path else %If the path is already there path=get(handles.profilepath,'String'); %Copies path validate=exist(path,'file'); %Checks if the file is in place. if validate==0 %If the file is no longer available msgbox(['Ambient Profile not found. Restore the file to its'... %Prompts with an error message. ' path described in the data being loaded.']); filename=0; %Exits attempt to load file setappdata(handles.load,'ErrorAmbProf',1); %Lets the Load function know there was an error set(handles.profilepath,'String',[]); %Clears path box else %If the file is still there filename=1; %Lets the rest of the function know there is a valid path end end 87

88

if filename~=0 %Only continues with valid path (if "Cancel" was not selected) AmbProf=xlsread(path); %Loads the file ands saves everything in SolSpec if isequal(size(AmbProf,2),5)&&isa(AmbProf,'double') %Only continues if it's a 5 column matrix setappdata(handles.profile,'AmbientProfile',AmbProf) %Saves ambient profile for use in other functions setappdata(handles.profile,'AmbProfpath',path) %Saves full path to file for use in save function pathsize=size(path,2); %Finds the number of character in the path string if pathsize>55 %If it doesn't fit in the path box endpath=['...',path(pathsize-55:pathsize)]; %Creates a string with the last 85 charaacters of the path set(handles.profilepath,'String',endpath); %Sets the end of the path string in the path box else %If it could fit in the path box set(handles.profilepath,'String',path); %Sets the full path string in the path box end set(handles.profilepath,'Visible','on'); %Shows the path box set(handles.airtemp,'Enable','off'); %Disables Air Temperature input set(handles.windspeed,'Enable','off'); %Disables Wind Speed input set(handles.relhum,'Enable','off'); %Disables Relative Humidity input set(handles.floortemp,'Enable','off'); %Disables Substrate Temperature Input

else %If it is not a 5 column matrix msgbox(['Ambient Profile not compatible. The file must be a'... %Prompts with an error message. ' 5 column .xlsx file containing, in the following '... 'order, Time [in decimal hours, i.e. 2:30 pm should'... ' be in the file 14.5], Air Temperatures [°C], Wind'... ' Velocities [m/s], Relative Humidities [%] and'... ' Substrate Temperatures [°C].']); set(handles.profile,'Value',0); %Unticks solar spectrum bypass. end else %If there is no valid path (or cancel was selected) set(handles.profile,'Value',0); %Unticks Ambient Profile. end else %If Unticked set(handles.profilepath,'String',''); %Clears the path box set(handles.profilepath,'Visible','off'); %Hides path to spectrum bypass. set(handles.airtemp,'Enable','on'); %Enables Air Temperature input set(handles.windspeed,'Enable','on'); %Enables Wind Speed input set(handles.relhum,'Enable','on'); %Enables Relative Humidity input set(handles.floortemp,'Enable','on'); %Enables Substrate Temperature Input end %------%------

%------INPUT LONGITUDE ------%------INPUT LONGITUDE ------function longit_Callback(~, ~, handles) EvDat=struct('EventName','FakeSelectionChange','NewValue',... %Creates fake event data for selection change with current selection get(handles.timemode,'SelectedObject')); timemode_SelectionChangeFcn([], EvDat, handles) %Recalculates default timezone through a fake callback %------%------

%------TIME MODE ------%------TIME MODE ------function timemode_SelectionChangeFcn(~, eventdata, handles) switch get(eventdata.NewValue,'Tag') %Gets the tag of the selected time mode case 'gmt' %If GMT set(handles.loctimedif,'String',0); %Resets and hides local time difference input section set(handles.loctimedif,'Visible','off'); % set(handles.loctimedifunits,'Visible','off'); % case 'local' default=round((str2double(get(handles.longit,'String'))/180)*12); %Calculates the approximate time zone from longitude set(handles.loctimedif,'String',default); %Defaults and shows local time difference input section set(handles.loctimedif,'Visible','on'); % set(handles.loctimedifunits,'Visible','on'); % end %------%------

%------LOCAL TIME DIFFERENCE ------%------LOCAL TIME DIFFERENCE ------function loctimedif_Callback(~, ~, handles) loctimedif=str2double(get(handles.loctimedif,'String')); %Gets the given time difference approxtimezone=round((str2double(get(handles.longit,'String'))/180)*12);%Calculates the approximate time zone from longitude if abs(loctimedif-approxtimezone)>2 %Only allows change if time zone is off by less than 2 hours msgbox('The time difference is too far off from its time zone.'); %Prompts with an error message set(handles.loctimedif,'String',approxtimezone); %Returns the time difference to the default time zone value end %------%------

%------BYPASS SOLAR SPECTRUM ------%------BYPASS SOLAR SPECTRUM ------function bypsol_Callback(hObject, ~, handles) if get(hObject,'Value') %If ticked %Gets the file from which data is going to be loaded if isempty(get(handles.bypsolspec,'String')) %If there is no path available yet [filename,filefolder,~]=uigetfile('.xlsx'); %Prompts for path selection path=fullfile(filefolder,filename); %Saves the path else %If the path is already there path=get(handles.bypsolspec,'String'); %Copies path validate=exist(path,'file'); %Checks if the file is in place. if validate==0 %If the file is no longer available msgbox(['Solar Spectrum not found. Restore the file to the'... %Prompts with an error message. ' path described in the data being loaded.']); filename=0; %Exits attempt to load file setappdata(handles.load,'ErrorSolSpec',1); %Lets the Load function know there was an error set(handles.bypsolspec,'String',[]); %Clears path box else %If the file is still there filename=1; %Lets the rest of the function know there is a valid path end end if filename~=0 %Only continues with valid path (if "Cancel" was not selected) SolSpec=xlsread(path); %Loads the file ands saves everything in SolSpec if isequal(size(SolSpec,2),2)&&isa(SolSpec,'double') %Only continues if it's a 2 column matrix setappdata(handles.bypsol,'BypSolSpec',SolSpec) %Saves spectrum for use in other functions 89

90

setappdata(handles.bypsol,'BypSolpath',path) %Saves full path to file for use in save function pathsize=size(path,2); %Finds the number of character in the path string if pathsize>85 %If it doesn't fit in the path box endpath=['...',path(pathsize-85:pathsize)]; %Creates a string with the last 85 charaacters of the path set(handles.bypsolspec,'String',endpath); %Sets the end of the path string in the path box else %If it could fit in the path box set(handles.bypsolspec,'String',path); %Sets the full path string in the path box end set(handles.bypsolspec,'Visible','on'); %Shows the path box %Forces Projection Factor Bypass set(handles.bypproj,'Enable','off'); %Disables checkbox set(handles.bypproj,'Value',1); %Sets value to 1 bypproj_Callback(handles.bypproj,[], handles) %Fake callback to show/enable/hide appropriately else %If it is not a 2 column matrix msgbox(['Spectrum not compatible. The file must be a two '... %Prompts with an error message. 'column .xlsx file containing Wavelengths [nm] in '... 'the first column and Irradiances [W/m2] on the '... 'second column.']); set(handles.bypsol,'Value',0); %Unticks solar spectrum bypass. end else %If there is no valid path (or cancel was selected) set(handles.bypsol,'Value',0); %Unticks solar spectrum bypass. end else %If Unticked set(handles.bypsolspec,'String',''); %Clears the path box set(handles.bypsolspec,'Visible','off'); %Hides path to spectrum bypass. set(handles.bypproj,'Enable','on'); %Allows projection calculation end %------%------

%------LOAD SIMULATION DATA ------%------LOAD SIMULATION DATA ------function load_Callback(~, ~, handles) %Gets the file from which data is going to be loaded [filename,filefolder,~]=uigetfile('.xlsx'); %Prompts for file path path=fullfile(filefolder,filename); %Saves the file path

if filename~=0 %Only continues a path was chosen (if "Cancel" wasn't selected) [~,~,DataLoaded]=xlsread(path); %Loads the file ands saves everything in array "DataLoaded"

if isequal(size(DataLoaded,2),13)&&size(DataLoaded,1)>=71 %Only continues if the file is of the same "shape" as saved files. setappdata(handles.load,'ErrorAmbProf',0); %Initializes Load error for Solar Ambient Profile setappdata(handles.load,'ErrorSolSpec',0); %Initializes Load error for Solar Spectrum Bypass %Finds the appropiate spectrum Contents = cellstr(get(handles.listspectra,'String')); %Lists available spectra val=find(strcmp([DataLoaded{5,2} '.mat'],Contents)); %Saves the position of the spectrum in the spectra list

if val~=0 %Only continues if the spectrum is available. set(handles.listspectra,'Value',val); %Selects the spectrum in the spectra list %Loads Size Inputs i=8; %Starts row-counter at 8 set(handles.dens,'String',DataLoaded{i,2}); i=i+1; %Density set(handles.w,'String',DataLoaded{i,2}); i=i+1; %Weight set(handles.snoutvent,'String',DataLoaded{i,2}); i=i+1; %Snout-Vent set(handles.da,'String',DataLoaded{i,2}); i=i+1; %Dorsal Area set(handles.va,'String',DataLoaded{i,2}); i=i+1; %Ventral Area set(handles.thick,'String',DataLoaded{i,2}); i=i+1; %Thickness %Thickness Approximation if DataLoaded{i,2}==1 %If thickness was approximated set(handles.approxthick,'Value',1); i=i+1; %Ticks the approx box else %If thickness was not approximated set(handles.approxthick,'Value',0); i=i+1; %Unticks the approx box end approxthick_Callback(handles.approxthick,[], handles) %Fake callback to show/enable/hide appropriately %Area approximation if DataLoaded{i,2}==1 %If areas were approximated set(handles.approxareas,'Value',1); i=i+1; %Ticks the approx box areasapmode=DataLoaded{i,2}; %Copies approximation mode if strcmp(areasapmode,'As Hemisphere') %If approximated as Hemisphere set(handles.areas,'SelectedObject',handles.hemisphere) %Selects the "Hemisphere" option i=i+1; %Gets to hemisphere secion set(handles.diam,'String',DataLoaded{i,2}); %Sets frog diameter i=i+7; %Jumps out of area approximation section elseif strcmp(areasapmode,'From Weight') %If approximated from Weight set(handles.areas,'SelectedObject',handles.weight) %Selects the "Weighed" option i=i+2; %Gets to weigh secion set(handles.a,'String',DataLoaded{i,2}); i=i+1; %Sets power function constants set(handles.b,'String',DataLoaded{i,2}); i=i+1; %Sets power function constants set(handles.c,'String',DataLoaded{i,2}); i=i+1; %Sets power function constants set(handles.d,'String',DataLoaded{i,2}); %Sets power function constants i=i+3; %Jumps out of area approximation section elseif strcmp(areasapmode,'From Snout-Vent') %If approximated from Snout-Vent set(handles.areas,'SelectedObject',handles.snout) %Selects the "Snout-Vent" option i=i+6; %Gets to snout-vent secion set(handles.svent,'String',DataLoaded{i,2}); i=i+1; %Sets square function constants set(handles.sdors,'String',DataLoaded{i,2}); %Sets square function constants i=i+1; %Jumps out of area approximation section end else %If areas were not approximated set(handles.approxareas,'Value',0); %Unticks the approx box i=i+8; %Jumps out of area approximation section end approxareas_Callback(handles.approxareas,[], handles) %Fake callback to show/enable/hide appropriately

%Loads Thermal properties i=i+2; %Skips empty row and title set(handles.hc,'String',DataLoaded{i,2}); i=i+1; %Heat Transfer Coefficient set(handles.hd,'String',DataLoaded{i,2}); i=i+1; %Mass Transfer Coefficient 91

92 set(handles.emisty,'String',DataLoaded{i,2}); i=i+1; %Emissivity set(handles.condty,'String',DataLoaded{i,2}); i=i+1; %Conductivity %hc Approximation if DataLoaded{i,2}==1 %If hc was approximated set(handles.approxhc,'Value',1); i=i+1; %Ticks the approx box hcapmode=DataLoaded{i,2}; %Copies approximation mode if strcmp(hcapmode,'Smooth Cylinder') %If hc approximated as smooth cylinder set(handles.heattransf,'SelectedObject',handles.cylinder) %Selects the "cylinder" option i=i+1; %Gets to cylinder secion set(handles.diamcyl,'String',DataLoaded{i,2}); %Sets cylinder diameter i=i+1; %Jumps out of hc approximation section elseif strcmp(hcapmode,'Sphere') %If hc approximated as sphere set(handles.heattransf,'SelectedObject',handles.sphere) %Selects the "sphere" option i=i+2; %Jumps out of hc approximation section end else %If hc was not approximated set(handles.approxhc,'Value',0); %Unticks the approx box i=i+3; %Jumps out of hc approximation section end approxhc_Callback(handles.approxhc,[], handles) %Fake callback to show/enable/hide appropriately %hd Approximation if DataLoaded{i,2}==1 %If hd was approximated set(handles.approxhd,'Value',1); i=i+1; %Ticks the approx box hdapmode=DataLoaded{i,2}; %Copies approximation mode if strcmp(hdapmode,'Power Function') %If hd approximated as power function set(handles.masstransf,'SelectedObject',handles.powfunc) %Selects the "Power Function" option i=i+1; %Gets to the power function secion set(handles.powfunce,'String',DataLoaded{i,2}); i=i+1; %Sets power function constants set(handles.powfuncf,'String',DataLoaded{i,2}); i=i+1; %Sets power function constants set(handles.powfuncg,'String',DataLoaded{i,2}); %Sets power function constants i=i+4; %Jumps out of hd approximation section elseif strcmp(hdapmode,'Exponential Function') %If hd approximated as an exponential function set(handles.masstransf,'SelectedObject',handles.expfunc) %Selects the "Power Function" option i=i+4; %Gets to the exponential function secion set(handles.expfuncA,'String',DataLoaded{i,2}); i=i+1; %Sets exponential function constants set(handles.expfunck,'String',DataLoaded{i,2}); i=i+1; %Sets exponential function constants set(handles.expfuncp,'String',DataLoaded{i,2}); %Sets exponential function constants i=i+1; %Jumps out of hd approximation section end else %If hd was not approximated set(handles.approxhd,'Value',0); %Unticks the approx box i=i+5; %Jumps out of hd approximation section end approxhd_Callback(handles.approxhd,[], handles) %Fake callback to show/enable/hide appropriately

%Loads Ambient characteristics i=i+2; %Skips empty row and title set(handles.airtemp,'String',DataLoaded{i,2}); i=i+1; %Air Temperature set(handles.windspeed,'String',DataLoaded{i,2}); i=i+1; %Wind Speed set(handles.relhum,'String',DataLoaded{i,2}); i=i+1; %Relative Humidity set(handles.visc,'String',DataLoaded{i,2}); i=i+1; %Kinematic Viscosity set(handles.condair,'String',DataLoaded{i,2}); i=i+1; %Air Conductivity set(handles.pres,'String',DataLoaded{i,2}); i=i+1; %Pressure set(handles.floortemp,'String',DataLoaded{i,2}); i=i+1; %Substrate Temperature set(handles.scond,'String',DataLoaded{i,2}); i=i+1; %Substrate Conductivity set(handles.shade,'String',DataLoaded{i,2}); i=i+1; %Shade Percentage set(handles.frogzen,'String',DataLoaded{i,2}); i=i+1; %Frog Zenith set(handles.frogazim,'String',DataLoaded{i,2}); i=i+1; %Frog Azimuth %Bypass Projection Factor if DataLoaded{i,2}==0 %If projection factor was not bypassed set(handles.bypproj,'Value',0); i=i+2; %Unticks checkbox else %If projection factor was bypassed set(handles.bypproj,'Value',1); i=i+1; %Ticks checkbox set(handles.project,'String',DataLoaded{i,2}); i=i+1; %Loads Fixed Projection Factor end bypproj_Callback(handles.bypproj,[], handles) %Fake callback to show/enable/hide appropriately %Ambient Profile if strcmp(DataLoaded{i,2},'N/A') %If an ambient profile was not used set(handles.profile,'Value',0); i=i+1; %Unticks the ambient profile box else %If an Ambient Profile was used set(handles.profile,'Value',1); %Ticks the Ambient Profile box set(handles.profilepath,'String',DataLoaded{i,2}); i=i+1; %Sets the profile path end profile_Callback(handles.profile,[], handles) %Fake callback to show/enable/hide appropriately

%Loads Location characteristics i=i+2; %Skips empty row and title set(handles.latit,'String',DataLoaded{i,2}); i=i+1; %Latitude set(handles.longit,'String',DataLoaded{i,2}); i=i+1; %Longitude set(handles.altit,'String',DataLoaded{i,2}); i=i+1; %Altitude set(handles.year,'String',DataLoaded{i,2}); i=i+1; %Year set(handles.month,'String',DataLoaded{i,2}); i=i+1; %Month set(handles.day,'String',DataLoaded{i,2}); i=i+1; %Day set(handles.starth,'String',DataLoaded{i,2}); i=i+1; %Simulation Start Hour set(handles.startm,'String',DataLoaded{i,2}); i=i+1; %Simulation Start Minute set(handles.stoph,'String',DataLoaded{i,2}); i=i+1; %Simulation End Hour set(handles.stopm,'String',DataLoaded{i,2}); i=i+1; %Simulation End Minute %Time Mode if strcmp(DataLoaded{i,2},'GMT') %If GMT set(handles.timemode,'SelectedObject',handles.gmt); i=i+1; %Selects GMT mode EvDat=struct('EventName','Fake','NewValue',handles.gmt); %Creates fake event data else %If Local Time set(handles.timemode,'SelectedObject',handles.local); i=i+1; %Selects Local Time mode EvDat=struct('EventName','Fake','NewValue',handles.local); %Creates fake event data end timemode_SelectionChangeFcn([],EvDat, handles) %Fake callback to show/enable/hide appropriately set(handles.timestep,'String',DataLoaded{i,2}); i=i+1; %Time Step %Bypass Solar Spectrum 93

94

if strcmp(DataLoaded{i,2},'Generated Spectrum') %If it was not bypassed set(handles.bypsol,'Value',0); %Unticks the bypass box else %If it was bypassed set(handles.bypsol,'Value',1); %Ticks the bypass box set(handles.bypsolspec,'String',DataLoaded{i,2}); %Sets the bypass spectrum path end bypsol_Callback(handles.bypsol,[], handles) %Fake callback to show/enable/hide appropriately

%Loads Outputs tmin=num2str(round(DataLoaded{3,6}*100)/100); %Gets minimum temperature with 2 decimal digits tmax=num2str(round(DataLoaded{3,7}*100)/100); %Gets maximum temperature with 2 decimal digits trange=[tmin ' to ' tmax]; %Defines temperature range set(handles.temprange,'String',trange); %Displays temperature range set(handles.totwatlost,'String',DataLoaded(3,10)); %Loads total water lost

i=4; %Initializes column counter datasize=size(DataLoaded,1); %Finds the size of the loaded data Time=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Time Temp=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Temperature Sol=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Net Solar Dir=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Direct Solar Dif=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Diffuse Solar Rad=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Radiation EWL=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Evaporative Water Loss Cond=cell2mat(DataLoaded(6:datasize,i)); i=i+1; %Conduction Conv=cell2mat(DataLoaded(6:datasize,i)); %Convection %Shares results with rest of GUI setappdata(handles.output,'Time',Time); %Time setappdata(handles.output,'Temp',Temp); %Temperature setappdata(handles.output,'Sol',Sol); %Net Solar setappdata(handles.output,'Dir',Dir); %Direct Solar setappdata(handles.output,'Dif',Dif); %Diffuse Solar setappdata(handles.output,'Rad',Rad); %Radiation setappdata(handles.output,'EWL',EWL); %Evaporative Water Loss setappdata(handles.output,'Cond',Cond); %Conduction setappdata(handles.output,'Conv',Conv); %Convection

plot_Callback(handles.plottemp, [], handles) %Plots loaded data through a fake callback

%Prompts with an end message if getappdata(handles.load,'ErrorAmbProf')==1||... getappdata(handles.load,'ErrorSolSpec')==1 msgbox('Error loading data.'); %Prompts successful message else msgbox('Simulation data and results successfully loaded.'); %Prompts successful message end else %If spectrum is not available msgbox('The spectrum used in the simulation you are trying',... %Prompts with error message 'to load is not available. Please first import the',... 'spectrum with the same name, and then continue to',... 'load the simulation data again.') end else %If the file is not of the same "shape" msgbox('Simulation data not compatible.'); %Prompts with an error message. end end %------%------

%------RUN BUTTON ------%------RUN BUTTON ------function run_Callback(~, ~, handles) %======Loading Input Data ======%Loads the selected frog spectrum Contents = cellstr(get(handles.listspectra,'String')); %Creates a cell array of strings with the available values for spectra %in the spectra list selspec=Contents{get(handles.listspectra,'Value')}; %gets the name of the selected spectrum specstruct=load(['Spectra\' selspec]); %loads it and saves it in a struct... the actual spectrum has to be %called as specstruct.(selspec) FrogSpec=specstruct.(strtok(selspec,'.')); %saves the loaded spectrum in a matrix

w=str2double(get(handles.w,'String')); %Weight of the frog in grams da=str2double(get(handles.da,'String'))/10000; %Dorsal Area - From cm2 to m2 va=str2double(get(handles.va,'String'))/10000; %Ventral Area - From cm2 to m2 thickness=str2double(get(handles.thick,'String'))/100; %Thickness - From cm to m

hc=str2double(get(handles.hc,'String')); %Heat transfer coefficient hd=str2double(get(handles.hd,'String')); %Mass transfer coefficient emisty=str2double(get(handles.emisty,'String')); %Frog Emisivity frogcond=str2double(get(handles.condty,'String')); %Frog Conductivity

airtemp=str2double(get(handles.airtemp,'String')); %Air Temperature relhum=str2double(get(handles.relhum,'String')); %Relative Humidity if strcmp(get(handles.pres,'String'),'auto') %If Pressure auto calculated pressure=0; %Sets pressure to 0 so that GenSpec calculates it. else %If a value is given pressure=str2double(get(handles.pres,'String')); %Reads pressure end

floortemp=str2double(get(handles.floortemp,'String')); %Floor Temperature floorcond=str2double(get(handles.scond,'String')); %Floor Conductivity

95

96 shade=(str2double(get(handles.shade,'String')))/100; %Shade percentage - From 0-100 to 0-1 fzenith=str2double(get(handles.frogzen,'String')); %Frog zenith angle fazimuth=str2double(get(handles.frogazim,'String')); %Frog azimuth angle if get(handles.profile,'Value') %If an Ambient Profile it is being used UAmbProf=getappdata(handles.profile,'AmbientProfile'); %Gets the user provided ambient profile end lat=str2double(get(handles.latit,'String')); %Latitude long=str2double(get(handles.longit,'String')); %Longitude alt=str2double(get(handles.altit,'String')); %Altitude y=str2double(get(handles.year,'String')); %Year m=str2double(get(handles.month,'String')); %Month d=str2double(get(handles.day,'String')); %Day timedif=str2double(get(handles.loctimedif,'String')); %Local Time Difference from GMT start=(str2double(get(handles.starth,'String'))-timedif)*60+... str2double(get(handles.startm,'String')); %Start time in minutes with the appropriate local time shift stop=(str2double(get(handles.stoph,'String'))-timedif)*60+... str2double(get(handles.stopm,'String')); %Stop time in minutes with the appropriate local time shift step=str2double(get(handles.timestep,'String')); %Time step in minutes

%======Preliminary Calculations ======condty=min(floorcond,frogcond); %Chooses the limiting conductivity if (m*30+d)>80&&(m*30+d)<263 %Chooses the appropriate season if lat>0 %Summer set from March 21st to Sept 21st in north hemisphere season=2; else season=1; end else if lat>0 %Winter set from Sept 22nd to March 20th in north hemisphere season=1; else season=2; end end wa=2*thickness*sqrt(va/pi); %Wall area (max projection from one side of a disc-frog)

%Initializes Result Vectors it=fix((stop-start)/step)+1; %Finds number of iterations Time=zeros(it,1); %Time Temp=zeros(it,1); %Temperature Sol=zeros(it,1); %Solar (Direct+Diffuse) Dir=zeros(it,1); %Direct Solar Dif=zeros(it,1); %Diffuse Solar Rad=zeros(it,1); %Gray body Radiation EWL=zeros(it,1); %Evaporative Water Loss Cond=zeros(it,1); %Conducted Conv=zeros(it,1); %Heat Convection IntAmbProf=zeros(it,7); %Interpolated Ambient Profile

%======Start of iterated calculations ======for n=1:it time=start+step*(n-1); %Updates time hours=fix(time/60); %Extracts hours minutes=fix(mod(time,60)); %Extracts minutes seconds=mod(time,1)*60; %Extracts seconds Time(n,1)=time/60+timedif; %Saves time converted to hours with the appropriate local time shift

if get(handles.profile,'Value') %If an Ambient Profile is being used [airtemp,wind,relhum,floortemp]=AmbProfInterp(Time(n,1),UAmbProf); %Interpolates Ambient Profile data set(handles.windspeed,'String',wind); %Updates Wind Speed windspeed_Callback([],[],handles); %Updates convection coefficients through fake callback hc=str2double(get(handles.hc,'String')); %Heat transfer coefficient hd=str2double(get(handles.hd,'String')); %Mass transfer coefficient %Saves interpolated Ambient Profile for use in Save function IntAmbProf(n,1)=Time(n,1); %Time IntAmbProf(n,2)=airtemp; %Air Temperature IntAmbProf(n,3)=wind; %Wind Speed IntAmbProf(n,4)=relhum; %Relative Humidity IntAmbProf(n,5)=floortemp; %Substrate Temperature IntAmbProf(n,6)=hc; %Heat Transfer Coefficient IntAmbProf(n,7)=hd; %Mass Transfer Coefficient end %Computes Solar Spectrum if get(handles.bypsol,'Value') %If solar spectrum is being bypassed SolSpec=getappdata(handles.bypsol,'BypSolSpec'); %Loads bypassing spectrum SolSpec(:,3)=SolSpec(:,2)*.1; %Sets diffuse radiation to 10% zenith=0; %Sets zenith angle to 0° else %If solar spectrum is to be calculated [azimuth,zenith]=SolPos(y,m,d,hours,minutes,seconds,lat,long); %Computes solar azimuth and zenith angles [SolSpec(:,1),~,SolSpec(:,2),~,SolSpec(:,3),~]=... %Computes the solar spectrum at that time GenSpec(lat,alt,pressure,airtemp,relhum,season,zenith); end %Computes projection factor if get(handles.bypproj,'Value') %If projection factor is being bypassed pro=str2double(get(handles.project,'String')); %Gets the bypassing value else %If projection factor is to be calculated pzenith=acosd(sind(zenith)*sind(fzenith)*... %Calculates the angle between the sun beam and the normal to the cosd(azimuth-fazimuth)+cosd(zenith)*cosd(fzenith)); %frog's ventral area if pzenith<0||pzenith>90 %Sets projection factor to zero when sun is nothitting the dorsal area. pro=0; else pro=(wa*sind(pzenith)+va*cosd(pzenith))/da; %Calculates the projection factor in any other angle end end 97

98

%Finds the equilibrium temperature if zenith>=0&&zenith<=90 %Finds the absorption power input [dir,dif]=Absorption(FrogSpec,da,pro,shade,SolSpec); %If sun is over the horizon, Computes absorption power input else %If sun is under the horizon dir=0; %Sets direct solar to 0 dif=0; %Sets diffuse solar to 0 end %Defines functions of the frog's temperature cond=@(frogtemp) (FlatSlabConduction(condty,va,thickness,... %Conduction floortemp,frogtemp)); conv=@(frogtemp) (Convection(hc,da,frogtemp,airtemp)); %Convection ewl=@(frogtemp) (EvapWatLoss(relhum,frogtemp,airtemp,hd,da)); %Evaporative Water Loss rad=@(frogtemp) (NetRadiation(frogtemp,emisty,da,airtemp,... %Gray body Radiation floortemp,shade));

netpower=@(frogtemp) (dir+dif+cond(frogtemp)+conv(frogtemp)+... %Defines a net power function using all of the above ewl(frogtemp)+rad(frogtemp)); Temp(n,1)=fzero(netpower,airtemp); %Finds the equilibrium temperature, in which net power is zero.

%Saves resulting power contribution at the equilibrium temperature Sol(n,1)=dir+dif; %Solar (Direct+Diffuse) Dir(n,1)=dir; %Direct Solar Dif(n,1)=dif; %Diffuse Solar Rad(n,1)=rad(Temp(n,1)); %Gray body Radiation EWL(n,1)=ewl(Temp(n,1)); %Evaporative Water Loss Cond(n,1)=cond(Temp(n,1)); %Conduction Conv(n,1)=conv(Temp(n,1)); %Convection end %======End of iterated calculations ======

%======Concluding operations ======tmin=num2str(round(min(Temp)*100)/100); %Finds minimum equilibrium temperature of the frog with 2 decimal places tmax=num2str(round(max(Temp)*100)/100); %Finds maximum equilibrium temperature of the frog with 2 decimal places trange=[tmin ' to ' tmax]; %Defines temperature range string set(handles.temprange,'String',trange); %Displays temperature range WatLost=step*60*EWL/(-2260); %Computes water loss at every time step in grams FrogWeight=(w - WatLost'*(triu(ones(it,it),+1)))'; %Computes the weight of the frog minus the cummulative water loss watlost=round(WatLost'*(ones(it,1))*100)/100; %Computes total water loss in the simulated period with 2 decimal places set(handles.totwatlost,'String',watlost); %Displays total water loss

%Shares the result vectors with other functions setappdata(handles.output,'Time',Time); %Time [hours] setappdata(handles.output,'Temp',Temp); %Temperature [°C] setappdata(handles.output,'Sol',Sol); %Net Solar (Direct+Diffuse) [W] setappdata(handles.output,'Dir',Dir); %Direct Solar [W] setappdata(handles.output,'Dif',Dif); %Diffuse Solar [W] setappdata(handles.output,'Rad',Rad); %Gray body Radiation [W] setappdata(handles.output,'EWL',EWL); %Evaporative Water Loss [W] setappdata(handles.output,'Cond',Cond); %Conduction [W] setappdata(handles.output,'Conv',Conv); %Convection [W] setappdata(handles.output,'Weight',FrogWeight); %Frog weight after water evaporation [g] setappdata(handles.output,'IntAmbProf',IntAmbProf); %Interpolated Ambient Profile

plot_Callback(handles.plottemp, [], handles) %Plots selected checkboxes creating a fake callback

msgbox('Simulation completed successfully.'); %Prompts with end mesage %------%------

%------PLOT CHECKBOXES ------%------PLOT CHECKBOXES ------function plot_Callback(hObject, ~, handles) Time=getappdata(handles.output,'Time'); %Copies the time vector to check if there is a plot to save if ~isempty(Time) %Only continues if there is plotable data Temp=getappdata(handles.output,'Temp'); %Copies the data to plot Sol=getappdata(handles.output,'Sol'); % Dr=getappdata(handles.output,'Dir'); % Df=getappdata(handles.output,'Dif'); % Rad=getappdata(handles.output,'Rad'); % EWL=getappdata(handles.output,'EWL'); % Cond=getappdata(handles.output,'Cond'); % Conv=getappdata(handles.output,'Conv'); % %Formats Axes cla(handles.axtemp); %Clears the plot area for temperature cla(handles.axpow); %Clears the plot area for power components xlim(handles.axpow,[Time(1,1),Time(end,1)]); %Sets same limits to the X axis in both axes (Power) xlim(handles.axtemp,[Time(1,1),Time(end,1)]); %Sets same limits to the X axis in both axes (Temperature) btickstep=max(round((Time(end,1)-Time(1,1))/12),.5); %Calculates the size of the gap between the big ticks stkstp=str2double(get(handles.timestep,'String'))/60; %Calculates the size of the gap between the small ticks set(handles.axpow,'XTick',0:btickstep:24); %Creates big ticks in Pewer axis set(handles.axtemp,'XTick',0:stkstp:24,'TickLength',[0.005 0.025]); %Creates small ticks in Temperature axis Empty=cell(floor(24/stkstp)+1); %Creates an empty cell so that smaller ticks have no label set(handles.axtemp,'XTickLabel',Empty); %Shows no number for the smaller ticks ShowLegend=zeros(8,1); %Creates a matrix to check whether a legend is to be displayed or not %Plots each line if checkbox is ticked if get(handles.plottemp,'Value') %Temperature (thick black) line(Time,Temp,'Color','k','Parent',handles.axtemp,'LineWidth',2); %Plots line as thick black in the Temperature axis line(Time(1),0,'Color','k','Parent',handles.axpow,'LineWidth',2); %Plots a single dot in Power axis so that it shows in legend ShowLegend(1,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotsolar,'Value') %Net Solar (red) line(Time,Sol,'Color','r','Parent',handles.axpow); %Plots line as red in the Power axis ShowLegend(2,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotdirsun,'Value') %Direct Solar (dashed red) line(Time,Dr,'Color','r','LineStyle','--','Parent',handles.axpow); %Plots line as dashed red in the Power axis ShowLegend(3,1)=1; %Confirms that it is to be shown in legend end 99

100

if get(handles.plotdifsun,'Value') %Diffuse Solar (dotted red) line(Time,Df,'Color','r','LineStyle',':','Parent',handles.axpow); %Plots line as dotted red in the Power axis ShowLegend(4,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotrad,'Value') %Radiation (orange) line(Time,Rad,'Color',[1 .5 0],'Parent',handles.axpow); %Plots line as orange in the Power axis ShowLegend(5,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotewl,'Value') %Evaporation (blue) line(Time,EWL,'Color',[0 0 1],'Parent',handles.axpow); %Plots line as blue in the Power axis ShowLegend(6,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotcond,'Value') %Conduction (green) line(Time,Cond,'Color',[.1 .6 .3],'Parent',handles.axpow); %Plots line as green in the Power axis ShowLegend(7,1)=1; %Confirms that it is to be shown in legend end if get(handles.plotconv,'Value') %Convection (cian) line(Time,Conv,'Color',[0 1 1],'Parent',handles.axpow); %Plots line as cian in the Power axis ShowLegend(8,1)=1; %Confirms that it is to be shown in legend end % Prints the legend of the plotted lines Legend={'Temperature';... %Creates a cell array with a list of all possible legends 'Net Solar Absorption';... 'Direct Beam';... 'Diffuse Light';... 'Radiation';... 'Evaporation';... 'Conduction';... 'Convection'}; ShowLegend=ShowLegend>0; %Turns the matrix with which legends to show into a conditional Legend=Legend(ShowLegend); %Creates a list with only the names of lines that are ploted handles.Legend=Legend; %Makes the array useable for the save plot function if get(handles.showlegend,'Value') %If the legend is to be shown (if checkbox ticked) legend(handles.axpow,Legend,'Location','NorthEast'); %Prints the legend end

guidata(hObject, handles); %Updates handles end %------%------

%------SHOW LEGEND ------%------SHOW LEGEND ------function showlegend_Callback(hObject, ~, handles) if get(hObject,'Value')&&(~isempty(handles.Legend)) %If ticked legend(handles.axpow,handles.Legend,'Location','NorthEast'); %Prints the legend if ticked else %If unticked legend(handles.axpow,'hide'); %Hides the legend if unticked end %------%------

%------SAVE BUTTON ------%------SAVE BUTTON ------function save_Callback(~, ~, handles) %Gets the name of the selected spectrum Contents = cellstr(get(handles.listspectra,'String')); %Copies a list of available spectra selspec=strtok(Contents{get(handles.listspectra,'Value')},'.'); %Picks the selected one and copies it before the "." %Shows where the file is going to be saved [filename,filefolder,~]=uiputfile([selspec '_Simulation' '.xlsx']); %Prompts with default name and format path=fullfile(filefolder,strtok(filename,'.')); %Saves the path without the file format

if filename~=0 %Only continues a path was chosen (if "Cancel" wasn't selected) %Gets the optional data %Areas Calculation if get(handles.approxareas,'Value') %If areas are being approximated if eq(get(handles.areas,'SelectedObject'),handles.hemisphere) %If approximated as hemisphere areasapmode='As Hemisphere'; %Sets approximation mode as "As Hemisphere" frogdiam=get(handles.diam,'String'); %Gets hemisphere diameter vala='N/A'; %N/A valb='N/A'; %N/A valc='N/A'; %N/A vald='N/A'; %N/A valventral='N/A'; %N/A valdorsal='N/A'; %N/A elseif eq(get(handles.areas,'SelectedObject'),handles.weight) %If approximated from weight areasapmode='From Weight'; %Sets approximation mode as "From Weight" frogdiam='N/A'; %N/A vala=get(handles.a,'String'); %Gets weight approximation constants valb=get(handles.b,'String'); %Gets weight approximation constants valc=get(handles.c,'String'); %Gets weight approximation constants vald=get(handles.d,'String'); %Gets weight approximation constants valventral='N/A'; %N/A valdorsal='N/A'; %N/A else %If approximated from snout-vent areasapmode='From Snout-Vent'; %Sets approximation mode as "From Snout-Vent" frogdiam='N/A'; %N/A vala='N/A'; %N/A valb='N/A'; %N/A valc='N/A'; %N/A vald='N/A'; %N/A valventral=get(handles.svent,'String'); %Gets snout-vent approximation constants valdorsal=get(handles.sdors,'String'); %Gets snout-vent approximation constants end else %If areas are not being approximated areasapmode='N/A'; %N/A frogdiam='N/A'; %N/A vala='N/A'; %N/A valb='N/A'; %N/A valc='N/A'; %N/A vald='N/A'; %N/A valventral='N/A'; %N/A valdorsal='N/A'; %N/A 101

102 end %For Heat Transfer Approximation if get(handles.approxhc,'Value') %If heat transfer is being approximated if eq(get(handles.heattransf,'SelectedObject'),handles.cylinder) %If approximated as a smooth cylinder hcapmode='Smooth Cylinder'; %Sets approximation mode as "Smooth Cylinder" cyldiam=get(handles.diamcyl,'String'); %Gets cylinder diameter else %If approximated as a sphere hcapmode='Sphere'; %Sets approximation mode as "Sphere" cyldiam='N/A'; %N/A end else %If heat transfer is not being approximated hcapmode='N/A'; %N/A cyldiam='N/A'; %N/A end %For Mass Transfer Approximation if get(handles.approxhd,'Value') %If mass transfer is being approximated handhdapmode=get(handles.masstransf,'SelectedObject'); %Gets handle to approximation mode object if eq(handhdapmode,handles.powfunc) %If approximated as a power function hdapmode='Power Function'; %Sets approximation mode as "Power Funciton" eval=get(handles.powfunce,'String'); %Gets power function constants fval=get(handles.powfuncf,'String'); % gval=get(handles.powfuncg,'String'); % Aval='N/A'; %Sets Exponential function constants to N/A kval='N/A'; % pval='N/A'; % elseif eq(handhdapmode,handles.expfunc) %If approximated as an exponential function hdapmode='Exponential Function'; %Sets approximation mode as "Power Funciton" eval='N/A'; %Sets power function constants to N/A fval='N/A'; % gval='N/A'; % Aval=get(handles.expfuncA,'String'); %Gets exponential function constants kval=get(handles.expfunck,'String'); % pval=get(handles.expfuncp,'String'); % end else %If mass transfer is not being approximated hdapmode='N/A'; %N/A eval='N/A'; % fval='N/A'; % gval='N/A'; % Aval='N/A'; % kval='N/A'; % pval='N/A'; % end %For Projection Factor bypass if get(handles.bypproj,'Value') %If projection factor is being bypassed fixproj=get(handles.project,'String'); %Gets projection factor value else %If projection factor is not being bypassed fixproj='N/A'; %N/A end %For Ambient Profile if get(handles.profile,'Value') %If an ambient profile is being used ambprof=getappdata(handles.profile,'AmbProfpath'); %Gets projection factor value else %If projection factor is not being bypassed ambprof='N/A'; %N/A end %For Time Mode if get(handles.gmt,'Value') %If using GMT timemode='GMT'; %Sets time mode to GMT else %If using Local Time timemode='Local Time'; %Sets time mode to Local end %For Solar Spectrum bypass if get(handles.bypsol,'Value') %If solar spectrum is being bypassed spec=getappdata(handles.bypsol,'BypSolpath'); %Gets path to the bypassing spectrum else %If solar spectrum is not being bypassed spec='Generated Spectrum'; %Sets spectrum as "Generated Spectrum" end

%Creates arrays with all the data to save DataIn={... %Inputs, two columns: Name, Value 'Inputs', ''; ... %Inputs '', ''; ... %(gap row) 'Frog Characteristics', ''; ... %Frog Characteristics '', ''; ... % 'Spectrum', selspec; ... %Spectrum '', ''; ... % 'Size', ''; ... %Size 'Density', get(handles.dens,'String'); ... Density 'Weight', get(handles.w,'String'); ... Weight 'Snout-Vent', get(handles.snoutvent,'String'); ... Snout-Vent 'Dorsal Area', get(handles.da,'String'); ... Dorsal Area 'Ventral Area', get(handles.va,'String'); ... Ventral Area 'Thickness', get(handles.thick,'String'); ... Thickness 'Thickness Approximated?', get(handles.approxthick,'Value'); ... Thickness Approximated? 'Areas Approximated?', get(handles.approxareas,'Value'); ... Areas Approximated? 'Approximation mode', areasapmode; ... Area Approximation Mode 'Frog Diameter', frogdiam; ... Area Approximation constants, hemisphere diameter 'a',vala; ... Area Approximation constants, from weight 'b',valb; ... Area Approximation constants, from weight 'c',valc; ... Area Approximation constants, from weight 'd',vald; ... Area Approximation constants, from weight 'ventral',valventral; ... Area Approximation constants, from snout-vent 'dorsal',valdorsal; ... Area Approximation constants, from snout-vent '', ''; ... % 'Thermal Properties', ''; ... %Thermal Properties 'Heat Transfer Coefficient', get(handles.hc,'String'); ... %Heat Transfer Coefficient 'Mass Transfer Coefficient', get(handles.hd,'String'); ... %Mass Transfer Coefficient 'Emissivity', get(handles.emisty,'String'); ... %Emissivity 103

104

'Frog''s Thermal Conductivity', get(handles.condty,'String'); ... %Frog's Thermal Conductivity 'hc Approximated?', get(handles.approxhc,'Value'); ... %hc Approximated? 'Approximation mode', hcapmode; ... %hc Approximation mode 'Cylinder Diameter', cyldiam; ... %hc Approximation constants, cylinder diameter 'hd Approximated?', get(handles.approxhd,'Value'); ... %hd Approximated? 'Approximation mode', hdapmode; ... %hd Approximation mode 'e',eval; ... %hd Approximation constants, power funciton of wind 'f',fval; ... %hd Approximation constants, power funciton of wind 'g',gval; ... %hd Approximation constants, power funciton of wind 'A',Aval; ... %hd Approximation constants, exponential funciton of wind 'k',kval; ... %hd Approximation constants, exponential funciton of wind 'p',pval; ... %hd Approximation constants, exponential funciton of wind '', ''; ... % 'Ambient Characteristics', ''; ... %Ambient Characteristics 'Air Temperature', get(handles.airtemp,'String'); ... %Air Temperature 'Wind Speed', get(handles.windspeed,'String'); ... %Wind Speed 'Relative Humidity', get(handles.relhum,'String'); ... %Relative Humidity 'Kinematic Viscosity', get(handles.visc,'String'); ... %Kinematic Viscosity 'Air''s Thermal Conductivity', get(handles.condair,'String'); ... %Air's Thermal Conductivity 'Pressure', get(handles.pres,'String'); ... %Pressure 'Substrate Temperature', get(handles.floortemp,'String'); ... %Substrate Temperature 'Substrate Thermal Conductivity', get(handles.scond,'String'); ... %Substrate Thermal Conductivity 'Shade Percentage', get(handles.shade,'String'); ... %Shade Percentage 'Frog Zenith',get(handles.frogzen,'String');... %Frog Zenith 'Frog Azimuth',get(handles.frogazim,'String');... %Frog Azimuth 'Projection Factor Bypassed?',get(handles.bypproj,'Value');... %Projection Factor Bypassed? 'Fixed Projection Factor',fixproj;... %Fixed Projection Factor 'Ambient Profile',ambprof;... %Ambient Profile '', ''; ... % 'Location Characteristics', ''; ... %Location Characteristics 'Latitude', get(handles.latit,'String'); ... %Latitude 'Longitude', get(handles.longit,'String'); ... %Longitude 'Altitude', get(handles.altit,'String'); ... %Altitude 'Year', get(handles.year,'String'); ... %Year 'Month', get(handles.month,'String'); ... %Month 'Day', get(handles.day,'String'); ... %Day 'Simulation start Hour', get(handles.starth,'String'); ... %Simulation start Hour 'Simulation start Minute', get(handles.startm,'String'); ... %Simulation start Minute 'Simulation end Hour', get(handles.stoph,'String'); ... %Simulation end Hour 'Simulation end Minute', get(handles.stopm,'String'); ... %Simulation end Minute 'Time Mode', timemode; ... %Time Mode 'Time Step', get(handles.timestep,'String'); ... %Time Step 'Solar Spectrum Used', spec; ... %Solar Spectrum Used }; mint=min(getappdata(handles.output,'Temp')); %Gets minimum temperature maxt=max(getappdata(handles.output,'Temp')); %Gets maximum temperature DataOut={... %Outputs (Headings), 1 columns total (1 for time, 9 for results) 'Outputs', '', '', '' ,'', '', '', '', '',''; ... %Outputs '', '', '', '' ,'', '', '', '', '','Latent Heat'; ... % Latent Heat '', 'Temp. Range', mint, maxt ,'', 'Lost Water', ... %Temperature Range Total Water Loss 2260000 get(handles.totwatlost,'String'), '', '','2260000'; ... '', '', '' ,'', '', '', '', '','',''; ... 'Time', 'Temperature', 'Net Solar', 'Direct' ,'Diffuse', ... %Vector titles 'Gray Body', 'Evaporation', 'Conduction', 'Convection', ... 'Frog Weight'}; ResultsCell=num2cell([... %Otputs (Results) getappdata(handles.output,'Time'),... %Time getappdata(handles.output,'Temp'),... %Temperature getappdata(handles.output,'Sol'),... %Net Solar getappdata(handles.output,'Dir'),... %Direct Solar getappdata(handles.output,'Dif'),... %Diffuse Solar getappdata(handles.output,'Rad'),... %Radiation getappdata(handles.output,'EWL'),... %Evaporative Water Loss getappdata(handles.output,'Cond'),... %Conduction getappdata(handles.output,'Conv'),... %Convection getappdata(handles.output,'Weight')]); %Frog Weight DataOut=vertcat(DataOut,ResultsCell); %Concatenates output headings and results

%Makes both arrays of same size and combines them if size(DataIn,1)>size(DataOut,1) %If more inputs than outputs DataOut{size(DataIn,1),1}=[]; %Adds empty cells to outputs elseif size(DataIn,1)

%Writes the file if get(handles.bypsol,'Value') %If solar spectrum is being bypassed SolSpec=num2cell(getappdata(handles.bypsol,'BypSolSpec')); %Loads bypassing spectrum SolSpecHeadings={'Wavelengths','Irradiances'}; %Generates Headings Row BSS=vertcat(SolSpecHeadings,SolSpec); %Merges headings and ambient profile xlswrite([path '.xlsx'],BSS,'Sheet3'); %Solar Spectrum Bypass end if get(handles.profile,'Value') %If an Ambient Profile it is being used IntAmbProf=num2cell(getappdata(handles.output,'IntAmbProf')); %Gets the Interpolated Ambient Profile IAPHeadings={'Time','Air Temperature','Wind Speed',... %Generates Headings Row 'Relative Humidity','Substrate Temperature',... 'Heat Transfer Coefficient','Mass Transfer Coefficient'}; IAP=vertcat(IAPHeadings,IntAmbProf); %Merges headings and ambient profile xlswrite([path '.xlsx'],IAP,'Sheet2'); %Ambient Profile end xlswrite([path '.xlsx'],DatatoSave,'Sheet1'); %Simulation Data

%Autosizes column widths and renames sheets hExcel = actxserver('Excel.Application'); %Opens hidden Excel application hWorkbook = hExcel.Workbooks.Open([path '.xlsx']); %Loads saved file 105

106

hWorkbook.Sheets.Item(1).Name='Simulation Data'; %Renames Sheet 1 to Simulation Data hWorkbook.Sheets.Item(2).Name='Ambient Profile'; %Renames Sheet 2 to Ambient Profile hWorkbook.Sheets.Item(3).Name='Solar Spectrum Bypass'; %Renames Sheet 3 to Solar Spectrum Bypass hWorksheet = hWorkbook.Sheets.Item(1); %Selects sheet 1 hWorksheet.Columns.AutoFit; %Autosizes columns hWorksheet.Columns.Item(2).columnWidth=20; %Resizes column 2 hWorksheet = hWorkbook.Sheets.Item(2); %Selects sheet 2 hWorksheet.Columns.AutoFit; %Autosizes columns hWorksheet = hWorkbook.Sheets.Item(3); %Selects sheet 3 hWorksheet.Columns.AutoFit; %Autosizes columns hWorkbook.Save %Saves with new column widths hWorkbook.Close %Closes file hExcel.Quit %Exits hidden Excel application

msgbox('Simulation data and results saved successfully.'); %Prompts with an end message. end %------%------

%------SAVE PLOT BUTTON ------%------SAVE PLOT BUTTON ------function saveplot_Callback(~, ~, handles) %Gets the name of the selected spectrum Contents = cellstr(get(handles.listspectra,'String')); %Copies the list of available spectra selspec=strtok(Contents{get(handles.listspectra,'Value')},'.'); %Picks the selected one and copies it before the "."

%Shows where the file is going to be saved [filename,filefolder,~]=uiputfile([selspec '_Plot' '.png']); %Prompts with default name and format path=fullfile(filefolder,filename); %Saves the path including file format

if filename~=0 %Only continues a path was chosen (if "Cancel" wasn't selected) printfigure=figure('Visible','off'); %Creates a new invisible figure powplotcopy=copyobj(handles.axpow,printfigure); %Copies the Power plot to that new figure tempplotcopy=copyobj(handles.axtemp,printfigure); %Copies the Temperature plot to that new figure %Plot positions and units set(printfigure,'Units','pixels'); %Sets matching pixel units for both plots and figure set(powplotcopy,'Units','pixels'); % set(tempplotcopy,'Units','pixels'); % plotpos=get(powplotcopy,'Position'); %Gets the position of the plot plotpos(1,1)=50; %Moves the plot to the "origin", at the left bottom corner, with a plotpos(1,2)=40; %gap to include axes names set(powplotcopy,'Position',plotpos); %Moves the Power plot copy to the same position set(tempplotcopy,'Position',plotpos); %Moves the Temperature plot copy to the same position %Figure position and margins printfigpos=get(printfigure,'Position'); %Copies the position of the invisible figure printfigpos(1,3)=plotpos(1,3)+90; %Adds space for the X axis label printfigpos(1,4)=plotpos(1,4)+50; %Adds space for the Y axis label set(printfigure,'Position',printfigpos); %Resizes the figure with new margins set(printfigure,'PaperPositionMode','auto'); %Automatically fits the print area to the figure size

if get(handles.showlegend,'Value') %If the legend is to be shown (if checkbox ticked) legend(powplotcopy,handles.Legend,'Location','NorthEast'); %Prints the legend end

saveas(printfigure,path,'png'); %Saves the figure as png close(printfigure); %Closes the invisible figure

msgbox('Plot saved successfully.'); %Prompts with an end message end %------%------

107

108

SpectrumImport.m

%Spec=SpectrumImport(file,lowerwvl,upperwvl,normfactor,SolSWvl) % Inputs: % file: Path to an xlsx file with two columns,the first for wavelengths % and the second for reflectivities. % lowerwvl: lowest reliable reflectivity meassurement wavelength. % upperwvl: highest reliable reflectivity meassurement wavelength. % normfactor: normalization factor. If it is not bigger than the % higgest reflectivity inside the confidece range, it will be % ignored and that value will be used to normalize reflectivities. % SolSWvl: Reference vector with wavelengths of solar spectrum. % Outputs: % Spec: A two- column matrix with the clipped and normalized spectrum % imported from the file, with a wavelength range equal to that % of SolSpecWvl,extrapolated by exponentially decreasing % reflectivities outside of the confidence range. % %Column1: Wavelengths with a range equal to SolSpecWvl. % %Column2: Normalized reflectivities (values from 0 to 1). % function Spec=SpectrumImport(file,lowerwvl,upperwvl,normfactor,SolSWvl) RawSpectrum=xlsread(file); %Loads file containing raw spectra.

ssol=size(SolSWvl,1); %Gets the size of the solar spectrum minsolw=SolSWvl(1,1); %Gets the smalles wavelength from the solar spectrum maxsolw=SolSWvl(ssol,1); %Gets the biggest wavelength from the solar spectrum if lowerwvlmaxsolw %If the highest trusted wavelength is bigger than the solar wavelength upperwvl=maxsolw; %Overrides high clipping value end %Clips the spectra and keeps the wavelengths inside the confidence range. Clip=RawSpectrum(:,1)>=lowerwvl&RawSpectrum(:,1)<=upperwvl; %Creates a Logical matrix with zeros in wavelengths to be deleted ClippedWavelength=RawSpectrum(Clip,1); %Creates a clipped wavelength matrix ClippedReflectivity=RawSpectrum(Clip,2); %Creates a clipped reflectivity matrix %Normalizes the values for reflectivity so that they are between 0 and 1. maxref=max(ClippedReflectivity); %Gets the current maximum value in the clipped reflectivity matrix if normfactor=ClippedWavelength(1),1,'first'); %Finds the row number of the min frog wavelength on the solar spectrum [maxrow,~]=find(SolSWvl(:,1)>ClippedWavelength(sclip),1,'first'); %Finds the row number of the max frog wavelength on the solar spectrum Spec=zeros((minrow-1)+sclip+(ssol-maxrow+1),2); %Creates a matrix with enough spaces to extrapolate Spec(1:minrow-1,1)=SolSWvl(1:minrow-1,1); %Copies lower wavelengths from solar spectrum Spec(minrow:minrow+sclip-1,2)=NormRef(:,1); %Copies clipped wavelengths Spec(minrow+sclip:minrow+sclip+ssol-maxrow,1)=SolSWvl(maxrow:ssol,1); %Copies higher wavelengths from solar spectrum %Lower wavelength extrapolation, exponentially increasing for i=1:(minrow-1) %Generates values so that it goes from e^-5 to 1 times the value of Spec(i,2)=NormRef(1,1)*exp(-5*(minrow-(i+1))/(minrow-2)); %the lowest clipped wavelength reflectivity. end Spec(minrow:minrow+sclip-1,1)=ClippedWavelength(:,1); %Copies clipped spectrum %Upper wavelength extrapolation, exponentially decreasing for i=(minrow+sclip):(minrow+sclip+ssol-maxrow) %Generates values so that it goes from 1 to e^-5 times the value of Spec(i,2)=NormRef(sclip,1)*exp(-5*(i-(minrow+sclip))/(ssol-maxrow)); %the highest clipped wavelength reflectivity. end end AmbProfInterp.m

%[airtemp,wind,relhum,floortemp] = AmbProfInterp(time,UserAmbProf) % Inputs: % time: Time of the day in decimal hours at which to interpolate. % UserAmbProf: 5 column matrix composed of:[Time,Air Temperature, % Wind Speed,Relative Humidity,Substrate Temperature] % Outputs: % airtemp: Temperature of the air. % wind: Wind velocity. % relhum: Relative humidity. % floortemp: Floor temperature. function [airtemp,wind,relhum,floortemp] = AmbProfInterp(time,UserAmbProf) s=size(UserAmbProf,1); %Finds the size of the User Ambient Profile [~,closestindex] = min(abs(UserAmbProf(:,1)-time)); %Finds the index of the closest User Ambient Profile time if UserAmbProf(closestindex,1) > time && closestindex > 1 %If the closest user defined time is before the interpolating time gap = UserAmbProf(closestindex,1) - UserAmbProf(closestindex - 1,1); %Finds the gap between the closest time and the previous user defined time weight = (gap - abs(UserAmbProf(closestindex,1) - time))/gap; %Defines a weight for the closest time InterpProf = weight*UserAmbProf(closestindex,:) + ... %Interpolates the Ambient Profile (1-weight)*UserAmbProf(closestindex - 1,:); elseif UserAmbProf(closestindex,1) < time && closestindex < s %If the closest user defined time is before the interpolating time gap = UserAmbProf(closestindex+1,1)-UserAmbProf(closestindex,1); %Finds the gap between the closest time and the previous user defined time weight = (gap - abs(UserAmbProf(closestindex,1) - time))/gap; %Defines a weight for the closest time InterpProf = weight*UserAmbProf(closestindex,:) + ... %Interpolates the Ambient Profile (1-weight)*UserAmbProf(closestindex + 1,:); else %If the index is an edge, or the time is equal to the interpolating time InterpProf = UserAmbProf(closestindex,:); %Copies the closest value end %Copies results for outputs airtemp = InterpProf(2); %Air Temperature wind = InterpProf(3); %Wind Speed relhum = InterpProf(4); %Relative Humidity floortemp = InterpProf(5); %Floor Temperature end 109

110

Absorption.m

%[direct,diffuse]=Absorption(FrogSpec,dorsarea,proj,shade,SolSpec) % Inputs: % FrogSpec: Spectrum of the frog as a two column matrix in which: % Column1=Wavelengths [nm] % Column2=Reflectivities (values from 0 to 1) % dorsarea: Dorsal area of a frog [m2] % proj: A projection factor that accounts for the percentage of % dorsal area that is receiving perpendicular direct sun. 1 would % mean that the sun is coming from everywhere, 0 that there is no % sun. Tipically, it will have values between 1/4 and 2/3. % shade: A factor in which 0 means no shade 1 is completely covered. % SolSpec: Spectrum of the frog as a three column matrix in which: % Column1 = Wavelengths [nm] % Column2 = Direct light irradiances [W/m2 nm] % Column3 = Diffuse light irradiances [W/m2 nm] % Outputs: % direct: power absorved from direct sunlight [W] % diffuse: power absorved from diffuse, scatered or reflected light [W] % %The function assumes that the area through which radiation is absorbed is: % DirectSurface = dorsarea*projection*(1-shade) % DiffuseSurface = dorsarea %The wavelength range of the FrogSpectrum has to be contained in the %wavelength range of the SolarSpectrum. % function [direct,diffuse]=Absorption(FrogSpec,dorsarea,proj,shade,SolSpec) s=size(FrogSpec,1); %Gets the size of the frog spectrum InterpIrrad=[FrogSpec(:,1),zeros(s,2)]; %Generater space for the irradiance interpolation

for n=1:s %Interpolates values from IrradianceTable and assigns them to new table [~,closestindex]=min(abs(SolSpec(:,1)-InterpIrrad(n,1))); %Finds the index of the wavelength in the irradiance table closest to the %spectra wavelength. InterpIrrad(n,2)=SolSpec(closestindex,2); %Assigns the closest direct irradiance value. InterpIrrad(n,3)=SolSpec(closestindex,3); %Assigns the closest diffuse irradiance value. end %Calculates the area under that gap as in a trapezoid. If=InterpIrrad(2:s,:); %Copies the top irradiance values Io=InterpIrrad(1:s-1,:); %Copies the bottom irradiance values Dwvl=If(:,1)-Io(:,1); %Calculates the gap between wavelengths AvgDir=(If(:,2)+Io(:,2))/2; %Calculates average energy in that gap from direct sunlight AvgDif=(If(:,3)+Io(:,3))/2; %Calculates average energy in that gap from diffuse light DirIrrad=Dwvl.*AvgDir; %Multiplies the average energy times the wavelength gap (direct) DifIrrad=Dwvl.*AvgDif; %Multiplies the average energy times the wavelength gap (diffuse)

AvgAbs=1-((FrogSpec(2:s,2)+FrogSpec(1:s-1,2))/2); %Calculates the average absorptivity that corresponds to each gap %Calculates absorved power as Pabs=absorptivity*energy at each gap. direct=(AvgAbs'*DirIrrad)*dorsarea*proj*(1-shade); %For direct sunlight diffuse=(AvgAbs'*DifIrrad)*dorsarea; %For diffuse radiation end

NetRadiation.m

%rad=NetRadiation(frogtemp,emisty,dorsarea,airtemp,floortemp,shade) % Inputs: % frogtemp: Temperature of the frog [°C]. % emisty: Emissivity of the frog. % dorsarea: Dorsal area of the frog [m2] % airtemp: Temperature of the surounding air [°C]. % floortemp: Temperature of the substrate under the frog standing [°C]. % shade: Percentage of "substrate" covering the frog (0 to 1). % Outputs: % rad: Net gray body radiation of the frog, accounting for the % radiation received from thermal radiation of the surroundings % and the one radiated by the frog itself. % function rad=NetRadiation(frogtemp,emisty,dorsarea,airtemp,floortemp,shade)

covertemp=(airtemp*(1-shade)+floortemp*shade); %Calculates a mean temperature of what is directly over the dorsal area %of the frog. c=.5; %Creates a mean temperature of the environment, using c as a proportion environtemp=covertemp*c+floortemp*(1-c); %of the radiation to be received from over the frog and under it. rad=-emisty*(((frogtemp+273.15)^4)-... %Computes the net gray body radiation of the frog ((environtemp+273.15)^4))*(5.670373e-8)*dorsarea; End

111

112

Convection.m

%convection=Convection(heatransfer,convarea,tempfrog,tempair) % Inputs: % heatransfer: heat transfer coefficient % convarea: Area through which heat is lost by convection [m2], usually % equal to the dorsal area. % tempfrog: Temperature of the frog's skin [°C] % tempair: Temperature of the surrounding air [°C] % Outputs: % convection: Power transmited through convection. A negative result % implies the frog is loosing energy. % function convection=Convection(heatransfer,convarea,tempfrog,tempair) convection=-heatransfer*convarea*(tempfrog-tempair); %PowerConvection=hd*A*(Temperature difference) end

FlatSlabConduction.m

%conduction=FlatSlabConduction(condty,csarea,thickness,tsubs,tfrog) % Inputs: % condty: Limiting conductivity. % csarea: Cross sectional area ~ ventral area. % thickness: Thickness of the flat slab. % tsubs: Temperature of the substrate [°C]. % tfrog: Temperature of the frog [°C]. % Outputs: % conduction: power conducted to or from the frog as if it was a flat % slab. If negative, the frog is loosing energy. % function conduction=FlatSlabConduction(condty,csarea,thickness,tsubs,tfrog) conduction=condty*(csarea/thickness)*(tsubs-tfrog); end

EvapWatLoss.m

%ewl=EvapWatLoss(relhum,frogtemp,airtemp,masstransfer,ewlarea) % Inputs: % relhum: Relative Humidity of the surrounding air [0 to 100] % frogtemp: Temperature of the frog [°C] % airtemp: Temperature of the surrounding air [°C] % masstransfer: mass transfer coefficient % ewlarea: Area through which water can evaporate [m2], usually equal % to the dorsal area. % Outputs: % ewl: Power transmited through evaporative water loss. % function ewl=EvapWatLoss(relhum,frogtemp,airtemp,masstransfer,ewlarea) latheat=2260000; %Used value for evaporating water latent heat. densfrog=WatVapSat(frogtemp+273.15); %Calculates water vapour saturation on frog's skin, assuming 100% saturation densair=relhum*WatVapSat(airtemp+273.15)/100; %Calculates water vapour saturation in the surrounding air ewl=-latheat*masstransfer*ewlarea*(densfrog-densair); %PowerEWL=-LatentHeat*hd*A*(Water vapour saturation difference) end

% Given a temperature in °K, the function returns the water vapor %saturation at that temperature, in Pa/°K, using the fit proposed in the %Engeneering Toolbox site: http://www.engineeringtoolbox.com/water-vapor-saturation-pressure-air-d_689.html % function watervapoursaturation=WatVapSat(temperature) watervapourpressure=(exp(77.345+0.0057*(temperature)-... %Computes the water vapour pressure (7235/(temperature))))/(temperature^(8.2)); % watervapoursaturation=0.0022*watervapourpressure/temperature; %Computes the water vapour saturation end

113

114

Appendix B, Solar Position Code

This appendix contains the code that corresponds to the PSA algorithm translation. The translation is full, for which it has the exact same functionality as the original code. See Chapter 7 for further details.

SolPos.m

% Given the date, time and global posiiton, this funtion returns the solar %position as two angles, the azimuth and the zenith. % % [azimuth,zenith]=SolPos(year,month,day,hour,min,sec,latitude,longitude) % %----- INPUT PARAMETERS ----- % Date and time in the usual 24 hour format (yyyy,mm,dd,hh,mm,ss). % Latitude in degrees, north positive and south negative. % Longitude in degrees, east positive and west negative. % %----- OUTPUT PARAMETERS ----- % Azimuth angle, measured from the north and towards east. % Zenith angle, measured from the normal to the ground. Zenith=0 at noon % and Zenith=90 at sunset/sundown. % % It is a translation of the code given in C++ at M. Blanco-Muriel et al %2001 paper, available at http://www.psa.es/sdg/archive/SunPos.cpp. %------% function [azimuth,zenith]=SolPos(year,month,day,hours,min,sec,latit,longit) %Declaration of some constants torad = pi/180; %Conversion factor between degrees and radians. earthmeanradius = 6371.01; %Earth's radius in km astronomicalunit = 149597890; %Astronomical unit in km

%Calculate difference in days between the current Julian Day and JD 2451545.0 %which is noon 1st January 2000 Universal Time (GMT) decimalhours = hours + (min + sec/60)/60; %Calculate time of the day in UT decimal hours a =(month-14)/12; %Calculate current Julian Day b=(1461*(year + 4800 + a))/4 + (367*(month - 2-12*a))/12 - ... % (3*((year + 4900 + a)/100))/4+day-32075; % juliandate = b - 0.5 + decimalhours/24; %Current julian date ejd = juliandate-2451545; %Elapsed Julian Days %Calculate ecliptic coordinates (ecliptic longitude and obliquity of the omega = 2.1429 - 0.0010394594*ejd; %ecliptic in radians but without limiting the angle to be less than 2*Pi meanlongitude = 4.8950630 + 0.017202791698*ejd; %(i.e., the result may be greater than 2*Pi)) meananomaly = 6.2400600+ 0.0172019699*ejd; % eclipticlongitude = meanlongitude + 0.03341607*sin(meananomaly) ... % + 0.00034894*sin(2*meananomaly) - 0.0001134 - 0.0000203*sin(omega); % eclipticobliquity = 0.4090928 - 6.2140e-9*ejd + 0.0000396*cos(omega); % %Calculates celestial coordinates ( right ascension and declination ) in sinel= sin(eclipticlongitude); %radians but without limiting the angle to be less than 2*Pi (i.e., the dy = cos(eclipticobliquity) * sinel; %result may be greater than 2*Pi) dx = cos(eclipticlongitude); % rightascension = atan2(dy,dx); % if rightascension < 0 % rightascension = rightascension + 2*pi; %Ensures right ascension is positive end declination = asin(sin(eclipticobliquity)*sinel); %

%Calculate local coordinates ( azimuth and zenith angle ) in degrees grenwichmst = 6.6974243242 + 0.0657098283*ejd + decimalhours; %Grenwich Mean Sideral Time localmst = (grenwichmst*15 + longit)*torad; %Local Mean Sideral Time hourangle = localmst - rightascension; % latinrad = latit*torad; %Latitude in radians coslat = cos(latinrad); % sinlat = sin(latinrad); % coshourangle = cos(hourangle); % zenith = acos(coslat*coshourangle*cos(declination) +... %Calculates the zentih angle sin(declination)*sinlat); % dy = -sin(hourangle); % dx = tan(declination)*coslat - sinlat*coshourangle; % azimuth = atan2(dy,dx); %Calculates the azimuth angle if azimuth < 0 % azimuth = azimuth + 2*pi; %Ensures azimuth is positive end azimuth = azimuth/torad; %Converts azimuth angle to degrees. parallax=(earthmeanradius/astronomicalunit)*sin(zenith); %Parallax Correction zenith=(zenith + parallax)/torad; %Converts zenith angle to degrees. end

115

116

Appendix C, Solar Spectrum Code

This appendix contains the code that corresponds to the SMARTS translation. It is again noted that it is vectorised and highly simplified, for which not all of the original code’s functions are available, and many parameters were fixed to be similar to a tropical forest. See Chapter 7 for further details.

It is divided into 3 sections. First, the main function “GenSpec”, and then 2 sub functions (“Intp” and “Ozon”), also translated from the original code.

GenSpec.m

% [Wavelengths,H0,Dir,DirH,Dif,Glob]=GenSpec(latitude,altitude,pressure,... % airtemp,relhum,season,zenit) % latitude: Latitude in degrees, north positive, south negative % altitude: Altitude above sea level in m, has to be less than 6000 % pressure: Site's pressure in hecto pascals. Input 0 if to be % calculated by program % airtemp: Air temperature in °C % relhum: Relative humidity in percentage (0-100) % season: Winter=Fall=1 or Summer=Spring=2 % zenit: Zenith angle in degrees (0=noon, 90=sunset/sunrise, % if >90 output=0) % Outputs: % Wavelengths: Spectrum wavelengths [nm], from 280 to 4000 % H0: Extraterrestrial irradiance [W/m2 nm] % Dir: Direct solar beam irradiance [W/m2 nm] % DirH: Direct horizontal irradiance [W/m2 nm], DirH=Dir*cos(zenith) % Dif: Diffuse irradiance [W/m2 nm] % Glob: Global irradiance [W/m2 nm], Glob=DirH + Diffuse % %% function [Wavelengths,H0,Dir,DirH,Dif,Glob]=GenSpec(latitude,altitude,pressure,airtemp,relhum,season,zenit) %% Input check ERROR={}; %Initializes an error array if altitude >=6000 ERROR=[ERROR;'Altitude has to be below 6000 m, using 0']; altitude=0; end if ~(season==1||season==2) ERROR=[ERROR;'Season input is not correct, using 1']; season=1; end if (airtemp<-120)||(airtemp>50) ERROR=[ERROR;'Temperatures are out of admissible range, using 22°C']; airtemp=22; end if relhum>100||relhum<0 ERROR=[ERROR;'Relative humidity has to be from 0 and 100, using 50']; relhum=50; end if zenit<0 ERROR=[ERROR;'Zenith angle is negative, using 0']; zenit=0; end

%% Constant definition and data loading nlosch=2.6867775e+19;

load('Abs_Alb_Spec.mat') %Loads all absorptivities, the albido and solar spectrum

abO3=0.3341; %Average ozone absorption qCO2=370; %Average ozone CO2 content

suncor=1.0; %Sun correction factor solarC=1366.1; %Solar constant

%% Input unit conversion and Run check altitude=altitude/1000; %converts altitude to km if zenit>90 %returns empty spectrum at night Wavelengths=SynthSolarSpectrumGueymard(:,1)/10; H0=(SynthSolarSpectrumGueymard(:,2))*(suncor*solarC/1366.1); Dir=zeros(size(Wavelengths,1),1); DirH=zeros(size(Wavelengths,1),1); Dif=zeros(size(Wavelengths,1),1); Glob=zeros(size(Wavelengths,1),1); return end

%% Temperature tk=airtemp+273.15; %Air temperature in °K tt0=tk/273.15; 117

118

%% Presure if pressure==0 %Calculates pressure if not given in inputs (pressure=0) alati=abs(latitude); PHI2=latitude*latitude; PCOR1=.993+2.0783E-04*alati-1.1589E-06*PHI2; PCOR2=8.855E-03-1.5236E-04*alati-9.2907E-07*PHI2; PCOR=PCOR1+altitude*PCOR2; pressure=1013.25*PCOR*exp(.00177-.11963*altitude-... .00136*altitude*altitude); end pp0=pressure/1013.25; %Defines a pressure ratio with sea level pressure qp=1-pp0; %Defines the complement of the pressure ratio.

%% Ozone Temperature [tempa,tmin,tmax,~,~]=Ozon(altitude,tk); %Converts Temperature at given altitude to ozone temperature

if tempatmax %Only continues if ozone temperature is correct ERROR=[ERROR;'Ozone temperatures are out of admissible range']; end

%% Vapor & Precipitable water %Calculates saturation vapor pressure from Gueymard (J. Appl. Met. 1993) tk1=tk/100; evs=exp(22.329699-49.140396/tk1-10.921853/tk1/tk1-.39015156*tk1); ev=evs*relhum/100; %Calculates precipitable water using empirical model of Gueymard (Solar Energy 1994) W=f(T,RH) rov=216.7*ev/tk; tt=1+(airtemp/273.15); hv=0.4976+1.5265*tt+exp(13.6897*tt-14.9188*tt^3); w=0.1*hv*rov;

if w>12 %Only continues if precipitable water is correct ERROR=[ERROR;'Precipitable water out of bounds']; end

%% Humidity dependent rural aerosol model xrh=cos(0.9*relhum*pi/180); xrh2=xrh*xrh; xrh3=xrh2*xrh; alpha1=(.4998+45.236*xrh+96.233*xrh2-13.067*xrh3)/(1+55.506*xrh+83.115*xrh2); alpha2=(0.86887+43.547*xrh-29.719*xrh2-1.8192*xrh3)/(1.+33.783*xrh-24.849*xrh2); rhc=max(50,relhum); rhc2=rhc*rhc; %COEFFICIENTS FOR OMEGL (SINGLE SCATTERING ALBEDO) bp0=1.0151-6.0574E-3*rhc+5.5945E-5*rhc2; bp1=-1.2901E-1+2.1565E-2*rhc-1.95E-4*rhc2; bp2=2.0622E-1-3.1109E-2*rhc+2.8096E-4*rhc2; bp3=-8.1528E-2+1.0582E-2*rhc-9.5007E-5*rhc2; bq0=-3.0306+.12324*rhc-6.408E-4*rhc2; bq1=exp(1.0949+5.4308E-3*rhc+1.7654E-5*rhc2); bq2=2.5572+7.2117E-3*rhc-2.5712E-5*rhc2; %COEFFICIENTS FOR GG (ASYMMETRY FACTOR) ag0=.75831+9.5376E-4*rhc+-2.3126E-6*rhc2; ag1=6.5007E-2-1.9238E-2*rhc+1.6785E-4*rhc2; ag2=-2.5092E-2+1.5397E-2*rhc-1.3813E-4*rhc2; ag3=-4.7607E-4-4.0963E-3*rhc+3.6814E-5*rhc2; ag4=7.4163E-4+3.5332E-4*rhc-3.146E-6*rhc2;

%% Turbidity tau5=0.084; t55=tau5/(1.1^alpha2); t552=t55*t55; if season==1 %If winter frctn=min(1,exp((-1.6435+1.4011*t55-8.2491*t552+0.065552/t55)/(1+1.936*t552))); alfa2=1.565; elseif season==2 %If summer frctn=min(1,exp((-1.8181+0.84983*t55-8.641*t552+0.0436/t55)/(1+1.8959*t552))); alfa2=1.584; end alpha1=alpha1*(1.-frctn)+.999*frctn; alpha2=alpha2*(1.-frctn)+alfa2*frctn; beta=(0.5^alpha2)*tau5; tau550=tau5/(1.1^alpha2);

if tau550>=5 ERROR=[ERROR;'Turbidity value too high.']; end

%% Gas air masses (am) and abundances (ab) betac=beta*(2.^(alpha2-alpha1)); zcos=cos(zenit*pi/180); amR=1/(zcos+.48353*(zenit^.095846)*(96.741-zenit)^(-1.754)); amH2O=1/(zcos+.10648*(zenit^0.11423)*(93.781-zenit)^(-1.9203)); amO3=1/(zcos+1.0651*(zenit^.6379)*(101.8-zenit)^(-2.2694)); amNO2=1/(zcos+1.1212*(zenit^1.6132)*(111.55-zenit)^(-3.2629)); amNO=1/(zcos+.77738*(zenit^.11075)*(100.34-zenit)^(-1.5794)); amN2=1/(zcos+.38155*(zenit^8.871e-05)*(95.195-zenit)^(-1.8053)); amCO2=1/(zcos+.65786*(zenit^.064688)*(96.974-zenit)^(-1.8083)); amCO=1/(zcos+.505*(zenit^.063191)*(95.899-zenit)^(-1.917)); amCH4=1/(zcos+.49381*(zenit^.35569)*(98.23-zenit)^(-2.1616)); amN2O=1/(zcos+.61696*(zenit^.060787)*(96.632-zenit)^(-1.8279)); amO2=1/(zcos+.65779*(zenit^.064713)*(96.974-zenit)^(-1.8084)); amNH3=1/(zcos+.32101*(zenit^.010793)*(94.337-zenit)^(-2.0548)); amSO2=1/(zcos+.63454*(zenit^.0099198)*(95.804-zenit)^(-2.0573)); amHNO3=1/(zcos+1.044*(zenit^.78456)*(103.15-zenit)^(-2.4794)); amAER=1/(zcos+.16851*(zenit^.18198)*(95.318-zenit)^(-1.9542)); amCH2O=amN2O; 119

120

amClNO=amNO2; amHNO2=amHNO3; amNO3=amNO2; amBrO=amO3; amdif=1.732; epsir=0.17*(1.-exp(-8.*zcos)); sigmar=3.65-2.3*exp(-4.*zcos); expr=0.72+zcos; fhtcy=(-11.012+12.392*amO3)/(1.+.23644*amO3); fhtcx=3.2656*(1.-exp(-.46464*amO3^1.25))-.965936*fhtcy; fhtcz=2.*fhtcx+1.93187*fhtcy; fhtdx=exp(.31045+.001684*amO3-.28549/amO3^4); abCO2=.802685*qCO2*pp0; abO2=1.67766E5*pp0; abO4=1.8171d4*nlosch*nlosch*(pp0^1.7984)/(tt0^.344); abBrO=2.5E-06; abNO3=.00005; abCH2O=.0003; abHNO2=.0001; abClNO=.00012; pp0x2=pp0*pp0; pln=log(pp0); pln2=pln*pln; pln3=pln2*pln; abCH4=1.31195*(pp0*1.1245)*(tt0^.047283); abCO=.31491*(pp0^2.6105)*exp(.82546-2.9753*pp0+.88437*pp0x2); abN2O=.24344*(pp0^1.1625); abN2=3.8298*(pp0^1.8643)/(tt0^.50342); abHNO3=3.6739e-4*(pp0^.13568)/(tt0^.0714); abNO2=1e-4*min(1.864+.20314*pp0,41.693*pp0); abNO=1e-4*min(.74039+2.4154*pp0,57.314*pp0); abSO2=1.114e-5*(pp0^.81319)*exp(.81356+3.0448*pp0x2-1.5652*pp0x2*pp0); abNH3=exp(-8.6472+2.239*pln-2.3822*pln2-1.4408*pln3-.46322*pln3*pln);

%% Turbidity dependent coefficient for difuse algorythms t5=tau550; t52=t5*t5; t53=t5*t52; t54=t5*t53; t505=t5^0.5; t515=t5^1.5; t503=t5-.03; t5032=t503*t503; t5033=t503*t5032; t5034=t503*t5033; t5035=t503^.5; t56=t5-.6; t562=t56*t56; ama1=min(amAER,20); ama11=ama1-1; ama12=ama11*ama11; ama15=ama11^1.5; ama05=ama11^0.5; ama2=ama1*ama1; ama3=ama1*ama2; ama4=ama1*ama3; ama5=ama1^.5; tra0=(.79996+5.2399*t5-.45849*t52)/(1.+5.6621*t5+.67258*t52); tra1=(-.25538+5.4972*t5-2.484*t52)/(1.+3.0475*t5+3.1615*t52); tra2=(1.7845+8.5655*t5-2.8046*t52)/(1.+1.9911*t5+1.0593*t52); trb0=(.98+4.2022*t5-.36341*t52)/(1.+4.1566*t5-.24198*t52); trb1=(-2.927-3.5797*t5+19.036*t52)/(1.+28.266*t5+1.4545*t52); trb2=(.017854+6.9189*t5+3.1496*t52)/(1.+7.1728*t5-.75729*t52); if zenit>=45 fdifa0=(-81.197-42.369*ama1+1.6385*ama2+117.14*ama5)/(1.+.0048737*ama2); fdifa1=(287.15+148.6*ama1-5.6994*ama2-410.8*ama5)/(1.+.005139*ama2); fdifb0=(3.1461+4.3549*t5-.023703*t52-5.3845*t505)/(1.+1.8418*t52); fdifb1=(-.34571-.1714*t5-.0022115*t52+.55363*t505)/(1.+.046034*t52); fdifb2=(.017953+.087827*t5-.016289*t52-.065605*t505)/(1.+3.231*t52); else fdifa0=(-405.89+669.51*ama1-421.72*ama3+163.26*ama4)/(1.-1.7483*ama1+.86666*ama2); fdifa1=(1375.2-2268.7*ama1+1430.2*ama3-553.82*ama4)/(1.-1.7459*ama1+.86337*ama2); end if zenit<=80 tzc1b0=(1.0303-.29853*t5+3.0145*t52-5.1787*t53+.75487*t54)/(1.+48.21*t5-11.627*t505); tzc2b0=(.0087736-.023675*t5+.038433*t52-.02068*t53+.0025949*t54)/(1.+.75681*t5-1.102*t505); tzc3b0=(-1.6395+4.6978*t5-9.2494*t52+5.9966*t53-.78497*t54)/(1.+37.007*t5-3.1734*t505); tzd1b1=(.79647-.34098*t56+.23205*t562)/(1.-.6048*t56+.16386*t562); tzd2b1=(-.059924+.084758*t56-.025479*t562)/(1.-.60223*t56+.12697*t562); tzd3b1=(-.042678+.34131*t56-.28495*t562)/(1.+.14978*t562); tzd4b1=(-.013436+.23576*t56+.016945*t562)/(1.-.61716*t56+.13362*t562); tze1b2=-1.4472+.67069*t5-.18447*t52+.031889*t53; tze2b2=.10793-.054098*t5+.072644*t52-.015276*t53; tze3b2=.4919-1.0133*t5+.35268*t52-.044266*t53; tze4b2=.073577-.036235*t5+.066935*t52-.014448*t53; if tau550<=1.75 tze1b2=(-1.7064-3.3834*t5-.47597*t54+2.6748*t505)/(1.+.92521*t52); tze2b2=(.16239+.5601*t5+.13857*t54-.39887*t505)/(1.+1.1706*t52); tze3b2=(-.14892-.084698*t5+.020901*t54+.19723*t505)/(1.+.074613*t52); tze4b2=(.11187+.36411*t5+.19632*t54-.168*t505)/(1.+.42997*t52); end if tau550<=0.6 tzc1b0=(.068343-1.4788*t5+23.173*t52-50.108*t53+42.158*t54)/(1.+14.968*t5-7.0445*t505); tzc2b0=(.010684-.10861*t5-4.3737*t52+9.6237*t53-8.1427*t54)/(1.+70.477*t5-19.077*t505); tzc3b0=(.0055635+.15348*t5-2.3326*t52+6.547*t53-5.2644*t54)/(1.+26.745*t5-9.9257*t505); tzc4b0=(.030341-1.0782*t5+23.098*t52-49.809*t53+44.96*t54)/(1.+18.655*t5-7.7781*t505); tzd1b1=(2.4+24.478*t503-3.8623*t5032-10.047*t5035)/(1.+14.505*t503); tzd2b1=(-.068+.68664*t503-.40106*t5032-.26178*t5035)/(1.-1.6208*t503); 121

122

tzd3b1=(-1.2-15.514*t503+10.004*t5032+8.1483*t5035)/(1.+19.234*t503); tzd4b1=(.5-.12601*t503+7.0083*t5032-3.805*t5035)/(1.+34.177*t503); end

tzb0=1.+tzc1b0*ama11+tzc2b0*ama12+tzc3b0*ama15; tzb1=(tzd1b1*ama11+tzd2b1*ama12+tzd3b1*ama05)/(1.+tzd4b1*ama11); tzb2=(tze1b2*ama11+tze2b2*ama12+tze3b2*ama05)/(1.+tze4b2*ama12); if tau550<=1.75 tzb2=(tze1b2*ama11+tze2b2*ama12+tze3b2*ama05)/(1.+tze4b2*ama11); if tau550<=0.6 tzb0=(1.+tzc1b0*ama11+tzc2b0*ama12+tzc3b0*ama05)/(1.+tzc4b0*ama11); tzb1=(tzd1b1*ama11+tzd2b1*ama12+tzd3b1*ama05)/(1.+tzd4b1*ama11); end end else tzc1b0=(-.21837+.42655*t5-.25804*t52+.053587*t53-.0034933*t54)/(1.-1.0045*t5); tzc2b0=(.007183-.011421*t5+.0048386*t52-.00060429*t53-1.1538e-5*t54)/(1.-1.0044*t5); tzc3b0=(.41391-.94615*t5+.66482*t52-.14276*t53+.010187*t54)/(1.-1.0012*t5); tzd1b1=(-1.28-10.727*t5-.84523*t52+1.6956*t53-.26123*t54)/(1.+6.48*t5); tzd2b1=(-.014423+5.2179*t5+.10566*t52-.52195*t53+.08956*t54)/(1.+51.341*t5); tzd3b1=3.3705+.91411*t5-1.1374*t52+.27451*t53-.020812*t54; tze1b2=(4.8107+9.1856*t5-2.4024*t52+.29673*t53-10.278*t505)/(1.+.16684*t52); tze2b2=(-.18328-.39604*t5+.098351*t52-.011915*t53+.43926*t505)/(1.+.17865*t52); tze3b2=(-9.9946-14.963*t5+4.0066*t52-.50372*t53+18.124*t505)/(1.+.13084*t52); if tau550<=0.6 tzc1b0=(-.076486-2.9836*t5-3.6388*t52+5.2983*t53+1.0036*t505)/(1.+31.865*t5-11.358*t505); tzc2b0=(.0075+.060214*t503+.20831*t5032-.40488*t5033+.20894*t5034)/(1.+15.819*t503+2.2681*t5035); tzc3b0=(.072803+7.6593*t5+3.2585*t52-11.177*t53-1.9115*t505)/(1.+37.274*t5-12.44*t505); tze1b2=(-.09282+3.6079*t5+72.469*t52-42.168*t53-.81503*t505)/(1.+34.684*t5-11.93*t505); tze2b2=(-.051779+.36296*t5-2.8752*t52)/(1.+52.058*t52); tze3b2=(-.94044-51.232*t5-120.6*t52+88.994*t53+15.858*t505)/(1.+35.032*t5-11.999*t505); if tau550<=0.1 tzd1b1=(-3.6546-15.903*t5+15.443*t505)/(1.-7.4089*t5); tzd2b1=(.2838+3.3062*t5-1.3909*t505)/(1.+11.041*t5); tzd3b1=(8.0948+25.437*t5-31.606*t505)/(1.-8.1072*t5); end end tzb0=1.+tzc1b0*ama11+tzc2b0*ama12+tzc3b0*ama05; tzb1=tzd1b1*ama11+tzd2b1*ama12+tzd3b1*ama05; tzb2=tze1b2*ama11+tze2b2*ama12+tze3b2*ama05; end alba00=21.712-74.917*t5; alba01=-79.895+263.33*t5; alba0=(-13.126+331.3*t5+48.496*t52)/(1.+4.5503*t515); alba1=(113.53-2152.3*t5-280.*t52)/(1.+4.7907*t515); alba2=(-260.19+3516.8*t5+438.98*t52)/(1.+5.1594*t515); albb0=(-169.74+366.27*t5-1497.4*t52+417.66*t53)/(1.+211.44*t52); albb1=(695.55-2080.1*t5+5470.9*t52-1385.8*t53)/(1.+178.71*t52); albb2=(-724.21+2368.7*t5-5331.3*t52+1335.4*t53)/(1.+158.89*t52); albc0=(.030827+2.1215*t5+.23068*t52)/(1.+.84396*t5); albc1=(-.03264-2.1233*t5-.29271*t52)/(1.+1.1121*t5); albc2=(.015472+.7404*t5+.12473*t52)/(1.+1.1626*t5); albc3=(-.002198-.084679*t5-.015984*t52)/(1.+1.1628*t5); albc4=(1.019+1.6635*t5+.47646*t52)/(1.+80.333*t5);

%% Ozone dependent coefficients for diffuse algorithm amO32=amO3*amO3; amO33=amO32*amO3; fhta0=(-.47724+2.4591*amO3-1.5553*amO32+.36215*amO33)/(1.-1.5041*amO3+.58992*amO32); fhta1=(.018787-.010397*amO3-.017601*amO32+.0052716*amO33)/(1.-1.4903*amO3+.56957*amO32); fhtb0=(15.376-4.3125*amO3+.83276*amO32-.040636*amO33)/(1.-4.6253*amO3+2.8311*amO32); fhtb1=(-.13145+.035853*amO3-.0076174*amO32+.00038038*amO33)/(1.-1.9406*amO3+.93498*amO32); fhtc0=(-62.912+49.558*amO3)/(1.-.027447*amO3); fhtc1=(3.3372-2.4508*amO3)/(1.-.035041*amO3); fhtd0=(30.875-4.5802*amO3+.50428*amO32)/(1.-2.5567*amO3+1.8116*amO32); fhtd1=(-.23641+.020167*amO3-.004264*amO32)/(1.-1.3537*amO3+.59902*amO32); fhte0=(2.5689-4.824*amO3+2.07*amO32)/(1.-1.1905*amO3+.3643*amO32); fhte1=(-.066605+.21397*amO3-.10567*amO32)/(1.-1.2116*amO3+.37579*amO32); fhtf0=(2.2348-.44161*amO3+.3772*amO32-.020273*amO33)/(1.-.97556*amO3+.28047*amO32); fhtf1=(-.012594-.012008*amO3-.015456*amO32+.00085387*amO33)/(1.-.96938*amO3+.26425*amO32); ra00=(1.8973-2.8609*amO3+1.4498*amO32-.18485*amO33)/(1.-.95212*amO3+.24444*amO32); ra01=(.35236-.2446*amO3+.24659*amO32-.013065*amO33)/(1.-.88635*amO3+.22055*amO32); ra10=(-.58215+.31643*amO3-.023724*amO32+.00068713*amO33)/(1.-.1444*amO3-.11746*amO32); ra11=(18.015-121.17*amO3+81.105*amO32-13.644*amO33)/(1.-7.7047*amO3); ra12=(.092338+1.1519*amO3-2.3328*amO32+1.1325*amO33)/(1.-1.4379*amO3+.7014*amO32); ra02=(1.4738-.90914*amO3+.14322*amO32)/(1.-.30469*amO3+.027331*amO32); ra13=(-.20733+.19451*amO3-.029374*amO32)/(1.-.51985*amO3+.081935*amO32); ra03=(-8.1831+3.2169*amO3-.18812*amO32)/(1.+.32473*amO3); ra14=(2.1533-.57263*amO3+.03416*amO32)/(1.+.0027812*amO3); ra04=(1.9915-.58894*amO3+.05611*amO32-.0013311*amO33)/(1.-.26987*amO3+.02113*amO32); ra15=(1.7389-3.3761*amO3+2.1498*amO32-.40236*amO33)/(1.-.71275*amO3+.16324*amO32); ra16=(1.4282-.61201*amO3+.10302*amO32-.0055147*amO33)/(1.-.6277*amO3+.12961*amO32); ra05=(18.214+65.305*amO3-8.6308*amO32+1.1603*amO33)/(1.0+69.727*amO3-.34374*amO32); ra17=(-.12865-.18023*amO3+.084979*amO32-.0068614*amO33)/(1.-.18029*amO3+.020348*amO32); ra06=(1.0122-.18077*amO3+.43678*amO32)/(1.-.15562*amO3+.47075*amO32); ra18=(1.9286-2.0616*amO3+.24389*amO32)/(1.+.2096*amO3+.030102*amO32);

%% Spectrum H0=(SynthSolarSpectrumGueymard(:,2))*(suncor*solarC/1366.1); Wavelengths=SynthSolarSpectrumGueymard(:,1)/10; Wvl=Wavelengths/1000; Wvl2=Wvl.*Wvl; Wvl3=Wvl.*Wvl2; Wvl4=Wvl.*Wvl3;

%% Rayleigh scattering function TauRl=pp0./(117.3405*Wvl4-1.5107*Wvl2 + .017535-8.7743e-4./Wvl2); TR=exp(-amR*TauRl); 123

124

%% Water vapor absorption AW=Abs_H2O(:,2); Iband=Abs_H2O(:,3); Ifitw=Abs_H2O(:,4); Bwa0=Abs_H2O(:,5); Bwa1=Abs_H2O(:,6); Bwa2=Abs_H2O(:,7); Ifitm=Abs_H2O(:,8); Bma0=Abs_H2O(:,9); Bma1=Abs_H2O(:,10); Bma2=Abs_H2O(:,11); Ifitmw=Abs_H2O(:,12); Bmwa0=Abs_H2O(:,13); Bmwa1=Abs_H2O(:,14); Bmwa2=Abs_H2O(:,15); Bpa1=Abs_H2O(:,16); Bpa2=Abs_H2O(:,17);

W0ref=[4.11467,2.92232,1.41642,.41612,.05663]; W0=W0ref(Iband)'; Ww0=w-W0; Ww02=Ww0.*Ww0; Bw=1+Bwa0.*Ww0+Bwa1.*Ww02; Bw=Bw./(1+((Ifitw==1).*((1+Bwa2.*Ww0)-1))); %if Ifitw(i)==1, Bw=1+bwa0*ww0+bwa1*ww02/(1+bwa2*ww0) Bw=Bw./(1+((Ifitw==2).*((1+Bwa2.*Ww02)-1))); %if Ifitw(i)==2, Bw=1+bwa0*ww0+bwa1*ww02/(1+bwa2*ww02) Bw=Bw+((Ifitw==6).*((Bwa0+Bwa1.*Ww0)-Bw)); %if Ifitw(i)==6, Bw=bwa0+bwa1*ww0; Bw=max(Bw,.05); Bw=min(Bw,7);

Bm=(Ifitm==0).*(Bma1.*(amH2O.^Bma2)); %if Ifitm(i)==0, Bm(i)=Bma1(i)*(amH2O^Bma2(i)); amH2O1=amH2O-1; amH2O2=amH2O1*amH2O1; Bm=Bm+(Ifitm~=0).*(1+Bma0*amH2O1+Bma1*amH2O2); %if Ifitm(i)~=0, Bm(i)=1+Bma0(i)*amH2O1+Bma1(i)*amH2O1^2); Bm=Bm./(1+(((Ifitm==1).*((1+Bma2*amH2O1)-1)))); %if Ifitm(i)==1, Bm(i)=Bm(i)/(1.+Bma2(i)*amH2O1); Bm=Bm./(1+(((Ifitm==2).*((1+Bma2*amH2O2)-1)))); %if Ifitm(i)==2, Bm(i)=Bm(i)/(1.+Bma2(i)*amH2O1^2); Bm=Bm./(1+(((Ifitm==3).*((1+Bma2*amH2O1^.5)-1)))); %if Ifitm(i)==3, Bm(i)=Bm(i)/(1.+Bma2(i)*amH2O1^.5); Bm=Bm+((Ifitm==5).*(((1+Bma0*amH2O1^.25)./(1+Bma2*amH2O1^.1))-Bm)); %if Ifitm(i)==5, Bm(i)=(1+Bma0*amH2O1^.25)/(1+Bma2*amH2O1^.1); Bm=max(Bm,.05); Bm=min(Bm,7.0);

Check=((Bw==1)|((Ifitm~=0)&(Bm==1))|((Ifitm==0)&(Bm>0.968)&(Bm<1.0441))|(Ifitmw==-1));

Bmp=(Ifitm==0).*(Bma1.*(amdif.^Bma2)); %if Ifitm(i)==0, Bm(i)=Bma1(i)*(amH2O^Bma2(i)); amdif1=amdif-1; amdif2=amdif1*amdif1; Bmp=Bmp+(Ifitm~=0).*(1+Bma0*amdif1+Bma1*amdif2); %if Ifitm(i)~=0, Bmp(i)=1+Bma0(i)*amdif1+Bma1(i)*amdif1^2); Bmp=Bmp./(1+((Ifitm==1).*((1+Bma2*amdif1)-1))); %if Ifitm(i)==1, Bmp(i)=Bmp(i)/(1.+Bma2(i)*amdif1); Bmp=Bmp./(1+((Ifitm==2).*((1+Bma2*amdif2)-1))); %if Ifitm(i)==2, Bmp(i)=Bmp(i)/(1.+Bma2(i)*amdif1^2); Bmp=Bmp./(1+((Ifitm==3).*((1+Bma2*amdif1^.5)-1))); %if Ifitm(i)==3, Bmp(i)=Bmp(i)/(1.+Bma2(i)*amdif1^.5); Bmp=Bmp+((Ifitm==5).*(((1+Bma0*amdif1^.25)./(1+Bma2*amdif1^.1))-Bmp)); %if Ifitm(i)==5, Bmp(i)=(1+Bma0*amdif1^.25)/(1+Bma2*amdif1^.1); Bmp=max(Bmp,.1); Bmp=min(Bmp,6.0);

Yamw=amH2O*w./W0; Yamw1=Yamw-1; Yamw12=Yamw1.*Yamw1; Bmw=Bmwa1.*(Yamw.^Bmwa2); %if Ifitmw(i)==0, Bmw(i)=Bmwa1(i)*(yamw^Bmwa2(i)); Bmw=Bmw+((Ifitmw>0).*((1+Bmwa0.*Yamw1+Bmwa1.*Yamw12)-Bmw)); %if Ifitmw(i)>0, Bmw(i)=1+Bmwa0(i)*yamw1+Bmwa1(i)*yamw12; Bmw=Bmw./(1+((Ifitmw==1).*((1+Bmwa2.*Yamw1)-1))); %if Ifitmw(i)==1, Bmw(i)=Bmw(i)/(1+Bmwa2(i)*yamw1); Bmw=Bmw./(1+((Ifitmw==2).*((1+Bmwa2.*Yamw12)-1))); %if Ifitmw(i)==2, Bmw(i)=Bmw(i)/(1+Bmwa2(i)*yamw12); Bmw=max(Bmw,.05); Bmw=min(Bmw,7); Bmw=Bmw+(Check.*((Bm.*Bw)-Bmw)); %if Check(i)==1, Bmw(i)=Bm(i)*Bw(i);

Yamwp=amdif*w./W0; Yamwp1=Yamwp-1; Yamwp12=Yamwp1.*Yamwp1; Bmwp=Bmwa1.*(Yamwp.^Bmwa2); %if Ifitmw(i)==0, Bmwp(i)=Bmwa1(i)*(yamw^Bmwa2(i)); Bmwp=Bmwp+((Ifitmw>0).*((1+Bmwa0.*Yamwp1+Bmwa1.*Yamwp12)-Bmwp)); %if Ifitmw(i)>0, Bmwp(i)=1+Bmwa0(i)*yamw1+Bmwa1(i)*yamw12; Bmwp=Bmwp./(1+((Ifitmw==1).*((1+Bmwa2.*Yamwp1)-1))); %if Ifitmw(i)==1, Bmwp(i)=Bmwp(i)/(1+Bmwa2(i)*yamw1); Bmwp=Bmwp./(1+((Ifitmw==2).*((1+Bmwa2.*Yamwp12)-1))); %if Ifitmw(i)==2, Bmwp(i)=Bmwp(i)/(1+Bmwa2(i)*yamw12); Bmwp=max(Bmwp,.1); Bmwp=min(Bmwp,6); Bmwp=Bmwp+(Check.*((Bmp.*Bw)-Bmwp)); %if Check(i)==1, Bmpw(i)=Bmp(i)*Bw(i);

BPref=ones(2002,5); if abs(qp)>=1e-5 wamw=w*amH2O; qp1=min(.35,qp); pp01=max(.65,pp0); pp02=pp01*pp01; qp2=qp1*qp1; BPref(:,1)=1+.1623*qp; BPref(:,2)=1+.08721*qp1; BPref(:,3)=1-Bpa1*qp1-Bpa2*qp2; BPref(:,4)=(1-exp(-.63486+6.9149*pp01-13.853*pp02)*wamw)*(1-Bpa1*qp1-Bpa2*qp2); BPref(:,5)=(1-wamw*exp(8.9243-18.197*pp01+2.4141*pp02))*(1-Bpa1*qp1-Bpa2*qp2); BPref=max(BPref,.3); BPref=min(BPref,1.7); end %This sections chooses the appropriate BP from the BPref matrix Dtemp=[ones(2002,1),2*ones(2002,1),3*ones(2002,1),4*ones(2002,1),5*ones(2002,1)]; Etemp=(Dtemp==[Iband,Iband,Iband,Iband,Iband]); BPrefp=BPref'; BP=BPrefp(Etemp'); 125

126

TH2O=exp(-Bmw.*BP.*AW*((w*amH2O)^.9426)); TH2OP=exp(-Bmwp.*BP.*AW*((amdif*w)^.9426));

%% Absorption from all other gases %Uniformly mixed gases % 1. Oxygen (O2) TauO2=Abs_O2(:,2)*abO2; TO2=exp(-(TauO2*amO2)); TO2P=exp(-(TauO2*amdif)); % 2. Methane (CH4) ACH4=Abs_CH4(:,2); TCH4=exp(-(ACH4*abCH4*amCH4)); TCH4P=exp(-(ACH4*abCH4*amdif)); % 3. Carbon Monoxide (CO) ACO=Abs_CO(:,2); TCO=exp(-ACO*abCO*amCO); TCOP=exp(-ACO*abCO*amdif); % 4. Nitrous oxide (N2O) AN2O=Abs_N2O(:,2); TN2O=exp(-(AN2O*abN2O*amN2O)); TN2OP=exp(-(AN2O*abN2O*amdif)); % 5. Carbon Dioxide (CO2) TauCO2=Abs_CO2(:,2)*abCO2; TCO2=exp(-(TauCO2*amCO2)); TCO2P=exp(-(TauCO2*amdif)); % 6. Nitrogen (N2) AN2=Abs_N2(:,2); TN2=exp(-(AN2*abN2*amN2)); TN2P=exp(-(AN2*abN2*amdif)); % 7. Oxygen-oxygen (O2-O2 or O4) [Collision-induced absorption; also includes O2-N2] AO4=Abs_O4(:,2)*1e-46; TO4=exp(-AO4*abO4*amO2); TO4P=exp(-AO4*abO4*amdif); %Misc. Trace gases % 1. Nitric acid (HNO3) AHNO3=Abs_HNO3(:,2)*0.1.*exp(Abs_HNO3(:,3)*1e-3*(234.2-298.))*nlosch*1e-19; THNO3=exp(-AHNO3*abHNO3*amHNO3); THNO3P=exp(-AHNO3*abHNO3*amdif); % 2. Nitrogen dioxide (NO2) ANO2=(Abs_NO2(:,2)+Abs_NO2(:,3)*(tempa-220))*nlosch; TNO2=exp(-ANO2*abNO2*amNO2); TNO2P=exp(-ANO2*abNO2*amdif); % 3. Nitrogen trioxide (NO3) ANO3=(Abs_NO3(:,2)+Abs_NO3(:,3)*(tempa-230))*nlosch; TNO3=exp(-ANO3*abNO3*amNO3); TNO3P=exp(-ANO3*abNO3*amdif); % 4. Nitric oxide (NO) ANO=Abs_NO(:,2); TNO=exp(-ANO*abNO*amNO); TNOP=exp(-ANO*abNO*amdif); % 5. Sulfur Dioxide (SO2) ASO2=(Abs_SO2(:,2)+Abs_SO2(:,3)*(247.1-213))*nlosch; TSO2=exp(-ASO2*abSO2*amSO2); TSO2P=exp(-ASO2*abSO2*amdif); % 6. Ozone (O3) fto3=1-tempa/228; AO3=amO3*abO3*nlosch*Abs_O3(:,2).*(1+Abs_O3(:,3)*fto3)./(1+Abs_O3(:,4)*fto3); TO3=exp(-AO3.*(AO3<=499)); %If AO3(i)>499,TO3(i)=1 TauZ3=(AO3/amO3).*(Wavelengths<=1092); %TAUZ3=0 for wavelengths above 1092 % 7. Ammonia (NH3) ANH3=Abs_NH3(:,2); TNH3=exp(-ANH3*abNH3*amNH3); TNH3P=exp(-ANH3*abNH3*amdif); % 8. Bromine monoxide (BrO) ABrO=Abs_BrO(:,2)*nlosch; TBrO=exp(-ABrO*abBrO*amBrO); TBrOP=exp(-ABrO*abBrO*amdif); % 9. Formaldehyde (CH2O) ACH2O=(Abs_CH2O(:,2)+Abs_CH2O(:,3)*(tk-24-293))*nlosch; TCH2O=exp(-ACH2O*abCH2O*amCH2O); TCH2OP=exp(-ACH2O*abCH2O*amdif); % 10. Nitrous acid (HNO2) AHNO2=Abs_HNO2(:,2)*nlosch; THNO2=exp(-AHNO2*abHNO2*amHNO2); THNO2P=exp(-AHNO2*abHNO2*amdif); % 11. Chlorine nitrate (ClNO3) AClNO=Abs_CINO(:,2).*(1+Abs_CINO(:,3)*(-66)+Abs_CINO(:,4)*(-66)*(-66))*nlosch; TClNO=exp(-AClNO*abClNO*amClNO); TClNOP=exp(-AClNO*abClNO*amdif);

%% Total gaseous absorption excluding H2O and O3 Tmixd=TO2.*TO4.*TN2.*TN2O.*TCO.*TCO2.*TCH4; TmixdP=TO2P.*TO4P.*TN2P.*TN2OP.*TCOP.*TCO2P.*TCH4P; Trace=TNO.*TNO2.*TNO3.*THNO3.*TSO2.*TNH3.*TBrO.*TCH2O.*THNO2.*TClNO; TraceP=TNOP.*TNO2P.*TNO3P.*THNO3P.*TSO2P.*TNH3P.*TBrOP.*TCH2OP.*THNO2P.*TClNOP;

%% Aerosol extinction TAUA=zeros(2002,1); TAA=ones(2002,1); TAS=ones(2002,1); OmegL=bp0+bp1*Wvl+bp2*Wvl2+bp3*Wvl3; BQ=exp(bq1*(Wvl-bq2)); OmegL=OmegL+((Wavelengths>1999).*((1-(bq0*BQ)./(1+BQ).^2)-OmegL)); %if Wavelengths>1999, OMEGL(i)=(1-(bq0*BQ(i))/(1+BQ(i))^2) 127

128

if beta>0 TAUA=beta./(Wvl.^alpha2); TAUA=TAUA+((Wavelengths<=499).*((betac./(Wvl.^alpha1))-TAUA)); %if Wavelengths<=499, TAUA(i)=betac/(Wvl(i)^alpha1) TAUAS=OmegL.*TAUA; TAUAA=TAUA-TAUAS; TAS=exp(-TAUAS*amAER); TAA=exp(-TAUAA*amAER); else OmegL=ones(2002,1); end %% Beam Radiation TScat=TR.*TAS; TAbs0=TH2O.*Tmixd.*Trace.*TAA; TAAP=exp(-TAUAA*amdif); TAbs0P=TH2OP.*TmixdP.*TraceP.*TAAP; TAbs=TAbs0.*TO3; TDir=TAbs.*TScat; Dir=H0.*TDir; DirH=Dir*zcos; FhtO=ones(2002,1); Fht1=ones(2002,1); FhtO=FhtO+((TauZ3>5e-6).*((exp(-fhtcz-fhtdx*(TauZ3-2)))-FhtO)); %if TAUZ3(i)>5e-6, FHTO(i)=exp(-fhtcz-fhtdx*(TAUZ3(i)-2)) FhtO=FhtO+((TauZ3<=2).*((exp(-fhtcx*TauZ3-fhtcy*(TauZ3.^.95)))-FhtO)); %if TAUZ3(i)<=2, FHTO(i)=exp(-fhtcx*TAUZ3(i)-fhtcy*(TAUZ3(i)^.95)) % Multiple scattering algorithm Fda00=ones(2002,1); Fdazt=ones(2002,1); if t5>0.03 Taurf=((TauRl./(TauRl+TauZ3)).^.5).*TauRl.*TauRl; Fda00=(trb0+trb1*Taurf)./(1+trb2*(Taurf.^.5)); Fdazt=Fdazt+((Wavelengths>294).*((tzb0+tzb1*Taurf+tzb2*Taurf.^.5)-Fdazt)); %if Wavelengths(i)>294, Fdazt(i)=tzb0+tzb1*Taurf(i)+tzb2*Taurf(i)^.5 end Fda00=Fda00+((Wavelengths<=400).*((1)-Fda00)); %if Wavelengths(i)<400, Fda00(i)=1 if tau5>0.03 Fda00=Fda00+(((Wavelengths>294)&(Wavelengths<=400)).*... %if Wavelengths between 294 and 400, (((tra0+tra1*Taurf)./(1+tra2*Taurf))-Fda00)); %Fda00(i)=(tra0+tra1*Taurf(i))/(1+tra2*Taurf(i)) end Fht1UV=.962-9.1*TauZ3; %For TauZ3 <0.01 Fht1UV=Fht1UV+((TauZ3>=0.01).*((min(1,ra06+TauZ3*ra18))-Fht1UV)); %For 0.01 <= TauZ3 <= 0.1 if amO3>2 %For 0.1 < TauZ3 <= 1 Fht1UV=Fht1UV+((TauZ3>0.1).*((min(1.6,ra05+TauZ3*ra17))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>0.1).*((min(1,ra05+TauZ3*ra17))-Fht1UV)); end if amO3>3.2 %For 1 < TauZ3 <= 2.505 Fht1UV=Fht1UV+((TauZ3>1).*((min(2,ra03+TauZ3*ra14))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>1).*((min(2,ra02+TauZ3*ra13))-Fht1UV)); end if amO3>3.5 ra0=ra04; elseif amO3>3.2 ra0=min(2,ra03+2.505*ra14); else ra0=min(2,ra02+2.505*ra13); end if amO3>2.4 %For 2.505 < TauZ3 <= 6 Fht1UV=Fht1UV+((TauZ3>2.505).*((min(7.5,ra0+(TauZ3-2.505)*ra16))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>2.505).*((min(7.5,ra0+(TauZ3-2.505)*ra15))-Fht1UV)); end if amO3>2.2 ra0=ra01; else ra0=ra00; end if amO3>2.6 %For 6< TauZ3 <=10 Fht1UV=Fht1UV+((TauZ3>6).*((min(10,ra0+(TauZ3-6)*ra10))-Fht1UV)); elseif amO3>1.72 Fht1UV=Fht1UV+((TauZ3>6).*((min(10,ra0+(TauZ3-6)*ra11))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>6).*((min(10,ra0+(TauZ3-6)*ra12))-Fht1UV)); end if amO3>1.9 %For 10 < TauZ3 <= 15.5 Fht1UV=Fht1UV+((TauZ3>10).*((min(8,fhtf0+TauZ3*fhtf1))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>10).*((min(9,fhte0+TauZ3*fhte1))-Fht1UV)); end if amO3>1.6 %For 15.5 < TauZ3 <= 22.5 Fht1UV=Fht1UV+((TauZ3>15.5).*((min(6,fhtd0+TauZ3*fhtd1))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>15.5).*((min(7,fhtc0+TauZ3*fhtc1))-Fht1UV)); end if amO3>2 %For 22.5 < TauZ3 Fht1UV=Fht1UV+((TauZ3>22.5).*((min(12,fhtb0+TauZ3*fhtb1))-Fht1UV)); else Fht1UV=Fht1UV+((TauZ3>22.5).*((min(12,fhta0+TauZ3*fhta1))-Fht1UV)); end Fht1=Fht1+((Wavelengths<=400).*((Fht1UV)-Fht1)); %if Wavelengths(i)<400, Fht1(i)=Fht1UV(i) Fht1=max(Fht1,2e-03); Fht1=Fht1+((TauZ3<5.0).*((max(Fht1,5e-01))-Fht1)); %if TauZ3<5.0, Fht1=max(Fht1,5e-01) FhtO=FhtO./Fht1; if zenit>=89 HT=H0/amR; else HT=H0*zcos; end HTa=HT.*TAbs0P.*FhtO;

129

130

%% Difffuse Radiation GG=ag0+ag1*Wvl+ag2*Wvl2+ag3*Wvl3+ag4*Wvl4; GG=min(0.99,GG); ALG=log(1-GG); AFS=ALG.*(1.459+ALG.*(.1595+ALG*.4129)); BFS=ALG.*(.0783+ALG.*(-.3824-ALG*.5874)); FA1=1-.5*exp((AFS+BFS*zcos)*zcos); FA1P=1-.5*exp((AFS+BFS*.6)*.6); % 1. Diffuse Radiation from Rayleigh Scattering FR=0.5*ones(2002,1); FRP=0.5*ones(2002,1); FR=FR+((TauRl>=epsir).*((.5*exp(-((TauRl-epsir)/sigmar).^expr))-FR)); %if TauRl(i)>=epsir, FR=.5*exp(-((TauRl(i)-epsir)/sigmar)^expr) FRP=FRP+((TauRl>=0.1686).*((.5*exp(-.1957*(TauRl-0.0648).^1.32))-FRP)); %if TauRl(i)>=0.1686, FRP=.5*exp(-.1957*(TauRl(i)-0.0648)^1.32) DRay=HTa.*FR.*(1-TR).*(max(TAS,1e-10).^.167); % 2. Diffuse Radiation from Aerosol Scattering DAer=zeros(2002,1); if beta>0 DAer=HTa.*FA1.*(TR.^.167).*(1-TAS).*Fda00.*Fdazt; end %Sky diffuse before backscattering Fdifz=ones(2002,1); Fdiftz=ones(2002,1); Fdifz=Fdifz+((Wavelengths<=294).*((fdifa0+fdifa1*Wvl)-Fdifz)); %if Wavelengths(i)<=294, Fdifz(i)=fdifa0+fdifa1*Wvl(i) if zenit>=45 Fdiftz=Fdiftz+((Wavelengths<=294).*... %if Wavelengths(i)<=294, ((fdifb0+fdifb1*ama1+fdifb2*ama2)-Fdiftz)); %fdiftz=fdifb0+fdifb1*ama1+fdifb2*ama2 end Dif0=Fdifz.*Fdiftz.*(DRay+DAer); Glob0=DirH+Dif0; % 3. Backscattering (reflection from ground to space and back) TRP=exp(-amdif*TauRl); TauAP=TAUA*amdif; TASP=exp(-OmegL.*TauAP); TTp5=TAbs0P.^.5; GamOZ=ones(2002,1); GamOZ=GamOZ+((Wavelengths<=379.5).*((exp(-1e+5*(4.8344+23.088*abO3)*... %if Wavelengths<=379.5, (.38-Wvl).^5.8))-GamOZ)); %GamOZ(i)=exp(-1e+5*(4.8344+23.088*abO3)*(.38-Wvl(i))^5.8) Rocb=(Glob0>0).*(DirH./Glob0); %if Glob0>0, Rocb=DirH/Glob0 Rocb(isnan(Rocb))=0; %if Glob0<=0, Rocb=0 % Non-Lambertian reflection based on the "land albedo" formula of Larsen & Barkstrom Rhob=AlbedoGreenGrass(:,2)/.35; Rhod=AlbedoGreenGrass(:,2)*1.167; if(zcos>1e-6) Rhob=Rhob*(1-zcos*log(1+1/zcos)); end Rhob=min(Rhob,1); Rhod=min(Rhod,1); RHOR=(TTp5>1e-12).*((TTp5.*((1-FRP).^.85).*(TASP.^.05).*... %if TTp5(i)>1e-12, (1-TRP).*GamOZ)); %RHOR=TTp5(i)*((1-FRP(i))^.85)*(TASP(i)^.05)*(1-TRP(i))*GamOZ(i) RHOA=zeros(2002,1); if tau550>=0.03 if t5>0.2 FaTau=exp(alba0+alba1*Wvl+alba2*Wvl2); else FaTau=exp(alba00+alba01*Wvl); end FaTau=FaTau+((Wavelengths>350).*... %if Wavelengths>350, ((exp(albb0+albb1*Wvl+albb2*Wvl2))-FaTau)); %FaTau(i)=exp(albb0+albb1*Wvl(i)+albb2*Wvl2(i) FaTau=FaTau+((Wavelengths>500).*(((albc0+albc1*Wvl+... %if Wavelengths>500, albc2*Wvl2+albc3*Wvl3)./(1+albc4*Wvl))-FaTau)); %FaTau(i)=(albc0+albc1*Wvl(i)+albc2*Wvl2(i)+albc3*Wvl3(i))/(1.+albc4*Wvl(i)) RHOA=TTp5.*((1-FA1P).^.85).*GamOZ.*FaTau; end RHOS=RHOR+RHOA; RHO=Rhob.*Rocb+Rhod.*(1-Rocb); RORO=RHO.*RHOS; Upward=RHO.*Glob0; DGrnd=Upward.*RHOS./(1-RORO);

Dif=Dif0+DGrnd; Glob=DirH+Dif;

if ~isempty(ERROR) %Displays any error encountered in the program display(ERROR) end end

Ozon.m

% Converts Temperature at given altitude to ozone temperature. %In the original code, it is called as: Ozon(Z,Tz,Tm,Tmin,Tmax,Ozmin,Ozmax) %In translated code, it is called as: [Tm,Tmin,Tmax,Ozmin,Ozmax]=Ozon(Z,Tz) % Z = Altitude in km % Tz = Temperature at Z in °K % Tm = Average temperature % Tmin = Minimum temperature % Tmax = Maximum temperature % Ozmin = Minimum ozone content % Ozmax = Maximum Ozon content % function [Tm,Tmin,Tmax,Ozmin,Ozmax]=Ozon(Z,Tz) Zref=[0:1:25,30:5:100];

131

132

A0=[-128.24,-118.47,-99.894,-99.881,-102.06,-106.79,-112.54,... -115.88,-117.69,-115.02,-91.984,-18.072,68.685,7.1018,-83.208,... -145.22,-165.41,-166.81,-145.86,-113.39,-74.301,-26.34,23.488,... 54.405,60.253,51.106,7.4044,-16.679,-21.216,-43.058,-44.575,... -55.374,-99.21,44.285,43.945,32.81,-19.095,-16.587,-9.3195,... -6.7324,-10.863]; A1=[0.65139,0.61388,0.54085,0.53352,0.5325,0.54076,0.55315,... 0.55586,0.55201,0.52965,0.41801,0.078528,-0.32603,-0.058176,... 0.34991,0.6326,0.72425,0.72921,0.63055,0.47874,0.2971,0.075867,... -0.15234,-0.29358,-0.31898,-0.27613,-0.073547,0.034212,0.060706,... 0.1574,0.18328,0.23388,0.42174,-0.15026,-0.14293,-0.096462,... 0.13032,0.087694,0.029694,0.0187,0.028993]; O3min=[0.2434,0.2416,0.2389,0.2364,0.2339,0.2319,0.2297,... 0.2276,0.2259,0.2247,0.2245,0.2248,0.2243,0.2232,0.2236,0.2239,... 0.226,0.2279,0.2256,0.211,0.1866,0.1607,0.1362,0.1145,0.0961,... 0.0807,0.0409,0.0201,7.99E-03,2.63E-03,8.89E-04,3.36E-04,... 9.51E-05,3.31E-05,1.37E-05,7.50E-06,4.38E-06,2.37E-06,8.94E-07,... 2.59E-07,8.00E-08]; O3max=[0.4444,0.4428,0.4406,0.4383,0.4359,0.4336,0.4308,... 0.4278,0.4235,0.4182,0.4092,0.3979,0.3856,0.3727,0.3552,0.336,... 0.3132,0.289,0.2669,0.2537,0.2464,0.239,0.2302,0.219,0.2048,... 0.1887,0.113,0.0482,1.69E-02,5.43E-03,1.91E-03,8.24E-04,... 3.03E-04,9.99E-05,2.93E-05,1.04E-05,5.92E-06,4.39E-06,1.95E-06,... 6.75E-07,1.50E-07]; TO3min=[211.,210.8,210.5,210.3,210.1,209.9,209.7,209.6,209.4,... 209.3,209.2,209.1,208.9,208.8,208.7,208.6,208.5,208.4,208.4,... 208.4,208.6,208.9,209.2,209.6,210.1,210.7,214.8,223.1,234.,244.9,... 250.3,246.5,237.7,218.8,188.2,163.1,151.6,149.2,154.5,166.6,173.]; TO3max=[241.4,241.1,240.5,240.,239.6,239.3,238.9,238.7,238.5,... 238.3,238.3,238.4,238.6,238.8,239.1,239.5,240.,240.5,241.1,241.8,... 242.7,243.8,244.9,246.3,247.8,249.3,257.2,267.5,277.3,282.3,... 277.3,268.1,253.1,241.5,235.6,226.9,219.7,216.8,213.5,218.4,230.]; %Ozone temperature at altitude z vs air temperature at z: % To3(z)=(1.-a1)*T(z)-a0 INTRP=0; n=41; for iz=1:n if INTRP==0 if abs(Z-Zref(iz))<=0.0001 %If at the right altitude INTRP=2; Tm=(1-A1(iz))*Tz-A0(iz); Tmin=TO3min(iz); Tmax=TO3max(iz); Ozmin=O3min(iz); Ozmax=O3max(iz); elseif Z>Zref(iz) elseif iz<=2 INTRP=1; j1=max(iz-1,1); elseif iz>=(n-1) INTRP=1; j1=min(iz-1,(n-1)); else INTRP=1; j1=iz-1; end end end if INTRP~=2 xp=Zref(j1); xp1=Zref(j1+1); Tm0=(1.-A1(j1))*Tz-A0(j1); Tm1=(1.-A1(j1+1))*Tz-A0(j1+1); Tmin0=TO3min(j1); Tmin1=TO3min(j1+1); Tmax0=TO3max(j1); Tmax1=TO3max(j1+1); Ozmin0=O3min(j1); Ozmin1=O3min(j1+1); Ozmax0=O3max(j1); Ozmax1=O3max(j1+1);

Tm=Intp(1,xp,xp1,Z,Tm0,Tm1); Tmin=Intp(1,xp,xp1,Z,Tmin0,Tmin1); Tmax=Intp(1,xp,xp1,Z,Tmax0,Tmax1); Ozmin=Intp(1,xp,xp1,Z,Ozmin0,Ozmin1); Ozmax=Intp(1,xp,xp1,Z,Ozmax0,Ozmax1); end end

Intp.m

%Interpolation routine using either a linear interpolation (IntTyp=1) or %logarithmic interpolation (IntTyp=2). The log interpolation returns to a %linear interpolation if the gradient is very small. % In the original code, it is called as: Interp (IntTyp,X1,X2,X,Y1,Y2,Y) % In the translated code, it is called as: [y]=Intp(IntTyp,x1,x2,x,y1,y2) % function [y]=Intp(IntTyp,x1,x2,x,y1,y2) if y1<=1e-5||y2<=1e-5 IntTyp=1; end %Logaritmic interpolation if IntTyp==2 a1=log(y1); 133

134

a2=log(y2); Grad=(a2-a1)/(x2-x1); if abs(Grad)<=.01 IntTyp=1; end a=a1+(x-x1)*Grad; y=exp(a); end %Linear interpolation if IntTyp==1 y=y1+(x-x1)*(y2-y1)/(x2-x1); end end

135

136

References

[1] J. T. Bagnara and W. Ferris, “Localization of rhodomelanochrome in melanosomes of leaf frogs,” J. Exp. Zool., vol. 190, no. 3, pp. 367–372, 1974.

[2] J. T. Bagnara, “Enigmas of Pterorhodin, a Red Melanosomal Pigment of Tree Frogs,” Pigment Cell Res., vol. 16, no. 5, pp. 510–516, Oct. 2003.

[3] F. Pinto, M. Mielewczik, F. Liebisch, A. Walter, H. Greven, and U. Rascher, “Non-invasive measurement of frog skin reflectivity in high spatial resolution using a dual hyperspectral approach.,” PLoS One, vol. 8, no. 9, p. e73234, Jan. 2013.

[4] S. B. Emerson, T. A. Cooper, and J. R. Ehleringer, “Convergence in reflectance spectra among treefrogs,” Funct. Ecol., vol. 4, no. 1, pp. 47–51, 1990.

[5] W. P. Porter and D. M. Gates, “Thermodynamic equilibria of animals with environment,” Ecol. Monogr., vol. 39, no. 3, pp. 227–244, 1969.

[6] C. R. Tracy, “A model of the dynamic exchanges of water and energy between a terrestrial and its environment,” Ecol. Monogr., vol. 46, no. 3, pp. 293–326, 1976.

[7] C. R. Tracy, “Biophysical Modeling in Reptilian Physiology and Ecology,” in Biology of the reptilia, 2nd ed., Academic Press, 1982, pp. 275–321.

[8] P. E. Bartelt, R. W. Klaver, and W. P. Porter, “Modeling amphibian energetics, habitat suitability, and movements of western toads, Anaxyrus (=Bufo) boreas, across present and future landscapes,” Ecol. Modell., vol. 221, no. 22, pp. 2675–2686, Nov. 2010.

[9] M. Kearney, B. L. Phillips, C. R. Tracy, K. A. Christian, G. Betts, and W. P. Porter, “Modelling species distributions without using species distributions: the cane toad in Australia under current and future climates,” Ecography (Cop.)., vol. 31, pp. 423–434, 2008.

137

[10] P. E. Bartelt and C. R. Peterson, “Physically modeling operative temperatures and evaporation rates in amphibians,” J. Therm. Biol., vol. 30, no. 2, pp. 93–102, Feb. 2004.

[11] C. R. Tracy, K. A. Christian, and C. R. Tracy, “Not just small, wet, and cold: effects of body size and skin resistance on thermoregulation and arboreality of frogs,” Ecology, vol. 91, no. 5, pp. 1477–1484, 2010.

[12] A. Muth, “Thermoregulatory postures and orientation to the sun: a mechanistic evaluation for the zebra-tailed lizard, Callisaurus draconoides,” Copeia, vol. 1977, no. 4, pp. 710–720, 1977.

[13] P. N. Bartlett and D. M. Gates, “The energy budget of a lizard on a tree trunk,” Ecology, vol. 48, no. 2, pp. 315–322, 1967.

[14] K. A. Christian, C. R. Tracy, and C. R. Tracy, “Evaluating thermoregulation in reptiles: an appropriate null model,” Am. Nat., vol. 168, no. 3, pp. 421–430, 2006.

[15] J. R. Scott, C. R. Tracy, and D. Pettus, “A biophysical analysis of daily and seasonal utilization of climate space by a montane snake,” Ecology, vol. 63, no. 2, pp. 482–493, 1982.

[16] M. Kearney, R. Shine, and W. P. Porter, “The potential for behavioral thermoregulation to buffer ‘cold-blooded’ animals against climate warming.,” Proc. Natl. Acad. Sci. U. S. A., vol. 106, no. 10, pp. 3835–40, Mar. 2009.

[17] M. Kearney and W. P. Porter, “Mechanistic niche modelling: combining physiological and spatial data to predict species’ ranges.,” Ecol. Lett., vol. 12, no. 4, pp. 334–50, Apr. 2009.

[18] D. C. Woodhams, R. A. Alford, and G. Marantelli, “Emerging disease of amphibians cured by elevated body temperature,” Inter-Research, vol. 55, no. 2001, pp. 65–67, 2003.

[19] J. W. Mitchell, “Heat transfer from spheres and other animal forms.,” Biophys. J., vol. 16, no. 6, pp. 561–9, Jun. 1976.

[20] W. A. Buttemer and C. Thomas, “Influence of temperature on evaporative water loss and cutaneous resistance to water vapour diffusion in the orange-thighed frog (Litoria xanthomera),” Aust. J. Zool., vol. 51, no. 2, p. 111, 2003.

[21] C. R. Tracy, K. A. Christian, G. Betts, and C. R. Tracy, “Body temperature and resistance to evaporative water loss in tropical Australian frogs,” Comp. Biochem. Physiol. A. Mol. Integr. Physiol., vol. 150, no. 2, pp. 102–8, Jun. 2008.

138

[22] T. E. ToolBox, “Water Vapor Saturation Pressure and Density,” 2014. [Online]. Available: http://www.engineeringtoolbox.com/water-vapor-saturation-pressure-air-d_689.html. [Accessed: 30-Oct-2014].

[23] B. H. Brattstrom, “Amphibian Temperature Regulation Studies in the Field and Laboratory,” Integr. Comp. Biol., vol. 19, no. 1, pp. 345–356, 1979.

[24] C. R. Tracy and K. A. Christian, “Preferred temperature correlates with evaporative water loss in hylid frogs from northern Australia,” Physiol. Biochem. Zool., vol. 78, no. 5, pp. 839–846, 2005.

[25] F. Kasten and A. T. Young, “Revised optical air mass tables and approximation formula,” Appl. Opt., vol. 28, no. 22, pp. 4735–4738, 1989.

[26] C. Gueymard, SMARTS2: a simple model of the atmospheric radiative transfer of sunshine: algorithms and performance assessment. Florida: Florida Solar Energy Center/University of Central Florida, 1995.

[27] H. W. Baynton, W. G. Biggs, H. L. Hamilton Jr, P. E. Sherr, and J. B. Worth, “Wind structure in and above a tropical forest,” Journal of Applied Meteorology, vol. 4. pp. 670–675, 1965.

[28] M. Blanco-Muriel, D. C. Alarcón-Padilla, T. López-Moratalla, and M. Lara-Coira, “Computing the solar vector,” Sol. Energy, vol. 70, no. 5, pp. 431–441, 2001.

[29] J. J. Michalsky, “The Astronomical Almanac’s algorithm for approximate solar position (1950–2050),” Sol. Energy, vol. 40, no. 3, pp. 227–235, Jan. 1988.

[30] J. Spencer, “Comments on The Astronomical Almanac’s Algorithm for Approximate Solar Position (1950–2050),” Sol. Energy, vol. 42, no. 4, p. 353, 1989.

[31] S. B. Emerson, “Allometry and Jumping in Frogs: Helping the Twain to Meet,” Evolution (N. Y)., vol. 32, no. 3, pp. 551–564, 1978.

[32] M. S. Blouin, “Genetic Correlations among Morphometric Traits and Rates of Growth and Differentiation in the Green Tree Frog, Hyla cinerea,” vol. 46, no. 3, pp. 735–744, 1992.

[33] S. B. Emerson, “Testis size variation in frogs: Testing the alternatives,” Behav. Ecol. Sociobiol., vol. 41, no. 4, pp. 227–235, 1997.

[34] P. A. Schwalm, P. H. Starrett, and R. W. McDiarmid, “Infrared reflectance in leaf-sitting neotropical frogs,” Science (80-. )., vol. 196, no. January, pp. 3–4, 1977.

139

[35] E. L. Cussler, Diffusion: mass transfer in fluid systems, THIRD EDIT. New York: Cambridge University Press, 2009.

[36] T. E. ToolBox, “Dry Air Properties,” 2014. [Online]. Available: http://www.engineeringtoolbox.com/dry-air-properties-d_973.html. [Accessed: 01- Dec-2014].

[37] L. J. McClanahan and R. Baldwin, “Rate of water uptake through the integument of the desert toad, Bufo punctatus,” Comp. Biochem. Physiol., vol. 28, pp. 381–389, 1969.

[38] V. H. Hutchison, W. G. Whitford, and M. Kohl, “Relation of body size and surface area to gas exchange in anurans,” Physiol. Zool., vol. 41, no. 1, pp. 65–85, 1968.

[39] Acute3D, “Smart3DCapture.” [Online]. Available: https://community.acute3d.com/smart3dcapture-free-edition. [Accessed: 15-Dec- 2014].

[40] Blender, “Blender.” [Online]. Available: http://www.blender.org/. [Accessed: 18-Feb- 2015].

[41] A. Jorstad, B. Nigro, C. Cali, and M. Wawrzyniak, “NeuroMorph: A toolset for the morphometric analysis and visualisation of 3D models derived from electron microscopy image stacks,” Neuroinformatics, pp. 83–92, 2014.

[42] B. Lambson, “Image Resizer.” [Online]. Available: https://imageresizer.codeplex.com/. [Accessed: 14-Dec-2015].

[43] V. H. Shoemaker, M. A. Baker, and J. P. Loveridge, “Effect of water balance on thermoregulation in waterproof frogs (Chiromantis and Phyllomedusa),” Physiol. Zool., vol. 62, no. 1, pp. 133–146, 1989.

[44] G. J. Tattersall, P. C. Eterovick, and D. V. de Andrade, “Tribute to R. G. Boutilier: skin colour and body temperature changes in basking Bokermannohyla alvarengai (Bokermann 1956).,” J. Exp. Biol., vol. 209, no. Pt 7, pp. 1185–96, Apr. 2006.

[45] C. Honsberg and S. Bowden, “Air Mass,” PVCDROM, 2015. [Online]. Available: http://www.pveducation.org/pvcdrom/properties-of-sunlight/air- mass#footnote2_de3gcdt. [Accessed: 14-Jan-2015].

[46] E. G. Laue, “The measurement of solar spectral irradiance at different terrestrial elevations,” Sol. Energy, vol. 13, no. 1, pp. 43–57, 1970.

140

[47] M. Blumthaler, W. Ambach, and R. Ellinger, “Increase in solar UV radiation with altitude,” J. Photochem. Photobiol. B Biol., vol. 39, no. 2, pp. 130–134, Jun. 1997.

[48] M. Lowman and H. B. Rinker, Forest Canopies, Second Edi. Elsevier Academic Press, 2004.

141