From b4816de63f2b9cb0db57819172c0e9a35c69440a Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 15 Feb 2017 13:55:31 -0800 Subject: [PATCH 01/20] Squashed pre-EasyFlux changeset --- CHANGELOG.md | 43 ++ README.md | 24 +- doc/_sources.txt | 70 +-- doc/wiring.xlsx | Bin 0 -> 12206 bytes doc/wiring_details.ods | Bin 83336 -> 0 bytes src/default.cr3 | 994 ++++----------------------------------- src/email-template.cr3 | 27 -- src/readme.md | 13 +- src/scadabr-template.cr3 | 34 -- 9 files changed, 213 insertions(+), 992 deletions(-) create mode 100644 doc/wiring.xlsx delete mode 100644 doc/wiring_details.ods delete mode 100644 src/email-template.cr3 delete mode 100644 src/scadabr-template.cr3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ed7d4..d2ca895 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,49 @@ Change Log for GHG Monitoring Tower Program =========================================== +Next release +------------ + +> This release requires operating system `CR3000.Std.31` or newer. + +> Previous telemetry integrations (email, ScadaBR) have been removed in this +> version. + +### Data Table Changes + +* Remove 5-min flux/met and soil data tables +* Remove references to Picarro or Los Gatos instruments from `extra_info` table +* Remove conditionally-included data table `tsdata_extra` +* Fix issue which caused column `hfp_installed` in data table `site_info` to + always be false +* New columns associated with alt. CO2 flux calculations (see *Other changes*) + * `CO2_hf` in `tsdata` is carbon dioxide density derived using high-freq + sonic temperature instead of thermistor temperature + * in `stats30` table: + * `Fc_hf_wpl` is CO2 flux with WPL corrections + * `CO2_hf_mg_m3_Avg` is mean CO2 density + * `CO2_hf_mg_m3_Std` is standard deviation of CO2 density + +### Instrumentation Changes + +* Remove soil temp/moisture probes (8x Decagon Devices 5TM) +* Change soil temperature probes in layer above soil heat flux plates + (2x CSI model 109 probes → 1x CSI averaging thermocouple) +* Remove prototype NDVI/PRI sensors (Decagon Devices) +* Change PAR sensor back to LI190SB with Campbell Scientific-specific cabling + (versus Licor direct-purchase LI190R unit) + +### Other changes + +* Remove scheduled reporting to ScadaBR instance +* Remove automated email reporting +* Improved settings menu provides guidance on units where appropriate +* Produces two carbon dioxide flux estimates: the second value `Fc_hf_wpl` is + calculated using CO2 density derived using high-frequency sonic temperature + instead of slow-response thermistor temperature; for more information, refer + to http://dx.doi.org/10.1016/j.agrformet.2016.07.018 + + Initial commit diff --git a/README.md b/README.md index a8e3980..0d53790 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,28 @@ and access credentials. * [CR3000](https://campbellsci.com/cr3000) * network-enabled with an [NL115](https://campbellsci.com/nl115) module - * `CR3000.Std.27` or newer firmware -* Sensors and hardware (see documentation) + * `CR3000.Std.31` or newer firmware +* Base sensor suite + * Infrared CO2/H2O analyzer with ultrasonic + anemometer ([EC150](https://www.campbellsci.com/ec150) + + [CSAT3A](https://www.campbellsci.com/csat3a)) + * Cup and vane wind set ([034B](https://www.campbellsci.com/034b)) + * Temperature/humidity probe ([HMP-155A](https://www.campbellsci.com/hmp155a)) + * Net radiometer ([NL-Lite2](https://www.campbellsci.com/nr-lite2)) + * PAR sensor + ([LI-190SB](https://www.campbellsci.com/li190sb-l)) + * Tipping bucket rain gage ([TE525WS](https://www.campbellsci.com/te525ws-l)) +* Optional sensors + * Soil moisture/temperature probes ([TDR-315L](http://www.acclima.com)) + * Soil heat flux plates ([HFP01](https://www.campbellsci.com/hfp01)) + * Spectral reflectance (NDVI/PRI) sensors ([SRS series](http://www.decagon.com/en/canopy/canopy-measurements/spectral-reflectance-sensor-srs/)) +* Communications & power hardware + * GPS receiver ([GPS16X-HVS](https://www.campbellsci.com/gps16x-hvs)) + * modem + * ? + ### License #### diff --git a/doc/_sources.txt b/doc/_sources.txt index 0a5a07c..9f5194b 100644 --- a/doc/_sources.txt +++ b/doc/_sources.txt @@ -1,32 +1,44 @@ -http://s.campbellsci.com/documents/us/manuals/109ss.pdf CSI 109SS Manual.pdf -http://s.campbellsci.com/documents/us/manuals/cr3000.pdf CSI CR3000 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/cs616.pdf CSI CS616 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/csat3.pdf CSI CSAT3A Manual.pdf -http://s.campbellsci.com/documents/us/manuals/ec150.pdf CSI EC150 EC100 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/enclosures.pdf CSI Enclosure Manual.pdf -http://s.campbellsci.com/documents/us/manuals/gps16x-hvs.pdf CSI Garmin GPS16X-HVS Manual.pdf -http://s.campbellsci.com/documents/us/manuals/hmp155a.pdf CSI HMP155A Manual.pdf -http://s.campbellsci.com/documents/us/manuals/hfp01.pdf CSI Hukseflux HFP01 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/hfp01sc.pdf CSI Hukseflux HFP01SC Manual.pdf -http://s.campbellsci.com/documents/us/manuals/li190sb.pdf CSI LICOR LI190SB Manual.pdf -http://s.campbellsci.com/documents/us/manuals/loggernet.pdf CSI LoggerNet Manual.pdf -http://s.campbellsci.com/documents/us/manuals/034b.pdf CSI MetOne 034B Manual.pdf -http://s.campbellsci.com/documents/us/manuals/sunsaver.pdf CSI MorningStar SunSaver10 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/nl115.pdf CSI NL115 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/nr-lite2.pdf CSI Kipp&Zonen NR-Lite2 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/ravenxtv.pdf CSI Sierra Wireless RavenXT Manual.pdf -http://s.campbellsci.com/documents/us/manuals/sc105.pdf CSI SC105 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/sp70.pdf CSI SP70 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/te525.pdf CSI TE525 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/ut10.pdf CSI UT10 Manual.pdf -http://s.campbellsci.com/documents/us/manuals/hmp155a.pdf CSI Vaisala HMP155A Manual.pdf -http://manuals.decagon.com/Integration%20Guides/5TM%20Integrators%20Guide.pdf Decagon 5TM Integrators Guide.pdf -http://manuals.decagon.com/Manuals/13441_5TM_Web.pdf Decagon 5TM Manual.pdf +# daq/hardware/power/comm +http://s.campbellsci.com/documents/us/manuals/cr3000.pdf CSI CR3000 Operator's Manual.pdf +http://s.campbellsci.com/documents/us/manuals/nl115.pdf CSI NL115 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/ut10.pdf CSI UT10 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/enclosures.pdf CSI Enclosure Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/sunsaver.pdf MorningStar SunSaver10 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/sp70.pdf CSI SP70 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/gps16x-hvs.pdf CSI GPS16X-HVS Instruction Manual.pdf +http://static.garmincdn.com/pumac/GPS_16x_tech_specs.pdf Garmin GPS16x Technical Specifications.pdf +http://s.campbellsci.com/documents/us/manuals/sc105.pdf CSI SC105 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/ravenxtv.pdf CSI Sierra Wireless RavenXT Instruction Manual.pdf +http://web.archive.org/web/20170407210010/https://www.sierrawireless.com/~/media/support_downloads/airlink/docs/user_guides/rvn_pp_x_userguides/raven_x_evdo_userguide.ashx Sierra Wireless Raven X User Guide.pdf +http://web.archive.org/web/20170407210536/https://source.sierrawireless.com/~/media/support_downloads/airlink/docs/user_guides/rvn_pp_x_userguides/raven_xt_gprs_userguide.ashx?la=en Sierra Wireless Raven XT User Guide.pdf + +# instruments +http://s.campbellsci.com/documents/us/manuals/ec150.pdf CSI EC150 EC100 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/csat3.pdf CSI CSAT3A Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/034b.pdf CSI 034B Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/hmp155a.pdf CSI HMP155A Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/nr-lite2.pdf CSI NR-Lite2 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/li190sb.pdf CSI LI190SB Instruction Manual.pdf +https://s.campbellsci.com/documents/us/manuals/li190r.pdf CSI LI190R Instruction Manual.pdf +https://www.licor.com/documents/8yfdtw1rs27w93vemwp6 LICOR Terrestrial Quantum Sensors.pdf +http://s.campbellsci.com/documents/us/manuals/te525.pdf CSI TE525 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/hfp01.pdf CSI HFP01 Instruction Manual.pdf +http://s.campbellsci.com/documents/us/manuals/hfp01sc.pdf CSI HFP01SC Instruction Manual.pdf +http://www.hukseflux.com/sites/default/files/product_manual/HFP01_HFP03_manual_v1620.pdf Hukseflux HFP01 & HFP03 User Manual.pdf +http://s.campbellsci.com/documents/us/manuals/tcav.pdf CSI TCAV Instruction Manual.pdf +http://manuals.decagon.com/Manuals/14597_SRS_Web.pdf Decagon SRS Sensors Operator's Manual.pdf +http://manuals.decagon.com/Integration%20Guides/SRS-N%20Integrators%20Guide.pdf Decagon SRS-NDVI Integrator Guide.pdf +http://manuals.decagon.com/Integration%20Guides/SRS-P%20Integrators%20Guide.pdf Decagon SRS-PRI Integrator Guide.pdf http://www.decagon.com/assets/Uploads/SRS-pair-example-program.CR1.zip Decagon SRS Example CR1K Program.zip -http://manuals.decagon.com/Manuals/14597_SRS_Web.pdf Decagon SRS Sensors Manual.pdf -http://manuals.decagon.com/Integration%20Guides/SRS-N%20Integrators%20Guide.pdf Decagon SRS-NDVI Integrators Guide.pdf -http://manuals.decagon.com/Integration%20Guides/SRS-P%20Integrators%20Guide.pdf Decagon SRS-PRI Integrators Guide.pdf -http://static.garmincdn.com/pumac/GPS_16x_tech_specs.pdf Garmin GPS16x tech specs.pdf -https://dl.boxcloud.com/d/1/dGyDg84ynFgwGVxEeguRngz7xF5Zla-8WHTKXkba68dqkbP_BwksVgZCbtLI72-NfXO7MuaQMUQWobsED51um0Z9IJn-K__-eC8kVGjfMvYysf7we7tB0y-wwIqj0PpkPJB3u5iYrMpz0_3pFgLelXDfPXAJoCgz590aECX4ojbxbD8c2BbLkTbnNzenoaraGw1TNgJh0we0ZC1ZwZaU_M2fNZyD8Fjner3d9-n45yCMcLIMZMpb7-JGYfeQYlTTWLVG5s5E1hsDlbS0NRFwbsMHuJGwVZxgr_VLmmCj-LxmDiY3cb3XW8UpHcbeqdIjyFFF1CeYBvsWQGIq8SSy5Dr0cLkok77SDKMz8kuROaoCWCsBOBJN90R30tZmdKwZW3595ByqBT2FPgABfyGGJlKt8I8SET1BffRAolGY662At1EPipvKBtAxjCw2YU8QRMQprgsIQfKhbzc4iUgQK5gmuF0_MGfMKMyFQZo8P3sC3wYdC9ffrUYxfT_4UUocjIFG2lzgep3edHaFbWH6ayhEeujisKfELgBiWkfBD7Pms5qmMNrE7wFxLCPIRYZvAzqYs68gvZoXqu2y654DJcaVDMrGiY-kHxgjRfmBfOA6fyadaQVIx83R8p_awSvLPUxCZ_27AZ0zUVCWw-TTxRFtUWX5RfwiGJ2c8_MlsuxXpQRNdIKR7DTklRW_4BfCct_wDKbAujAPEI6kvBqXtNIJaLSghgTbWH5brh3JNGWvcJvu4VDQxSGxHzqIdI0L49YcKEfxQmLGcIfWLgsmxY-sK8uUi7QQ4ljYLZ_AGx8grwsdN2BaHdFdDWNfVhx7jsjAthiMMOdGB63Qy6705hozinXTd1REaWoSXAcOsizdDMQzgl7pp6JYlqVa4n2d33wwxZw4_9NQGT4t5EKmFBWNeGKQINDDTmbGK8_LxYcXVFPF2SoODTmSzCpHxoHLgYQ9i3uZahEoB-F27FcXoVRmc4Jxgd6zgZJUkh08TERwTKdm8uD054IL0nT-eAqIQ0wJ-nE-MptFMs89WviY7dMUdYlR6DKMNph4VHbM2BwZZ-W4HCxJXu6bOJdkqrYNUEpwlH-_TtuyzYliWFRJz5hEc0W7PvdeJVbmWjW8JocuxJjQuRK6oImAQ4554eiWhqG6ooSEaubHl8t0tDLiq7JzyWfLJRPAKcoFhtn7FklVsicq7n4iD3BtMUxtCczhXoTn4W5DIUIyDz7k9tWZCL3Oy3I-Bfzz6SN0Ra9eYPUMdaCbGOSUuaKRPPf5ZE3m2kPsPBCCbQW-58p7wtR020Q5kC5I1z2_ZFte2YhnaSrG/download LICOR Terrestrial Quantum Sensors.pdf +http://www.acclima.com/poc7/prodlit/TDR-315%20User%20Manual.pdf Acclima TDR-315 User Manual.pdf + + # software +http://s.campbellsci.com/documents/us/manuals/loggernet.pdf CSI LoggerNet Instruction Manual.pdf +http://web.archive.org/web/20170407210818/https://www.sierrawireless.com/~/media/support_downloads/airlink/docs/user_guides/4.0.11/4112515_aleos%204.0.11%20configuration%20user%20guide_r7.ashx Sierra Wireless ALEOS 4.0.11 User Guide.pdf + +# guidance +https://www.licor.com/documents/3vmte7rs3d5zu6swhbum LICOR LI-190 Quantum Sensor Calculation of Multiplier from Campbell Scientific Purchased Sensors.pdf +https://www.licor.com/documents/3xc19obvbdjezj7ahhgl LICOR Using LI-COR's Millivolt Adapters for Interfacing LI-COR Radiation Sensors to Voltage-reading Dataloggers.pdf +https://www.licor.com/documents/liuswfuvtqn7e9loxaut LICOR Principles of Radiation Measurement.pdf http://public.hortus.net.au/Portals/0/Page%20Content/H2Pro/Hortus%20Soil%20moisture%20probe%20installation%20instructions.pdf Hortus Soil moisture probe installation instructions.pdf http://mea.com.au/upload/NEW/PRODUCT_Brochures/B83_Soil-Moisture_Sensor_Installation_Guide_Web.pdf MEA Soil Moisture Sensor Installation Guide.pdf diff --git a/doc/wiring.xlsx b/doc/wiring.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bf9f38934ff4e9182cb0023b7eb36cee9cfeddf7 GIT binary patch literal 12206 zcmeHt1zQ};w)S9w;O=h02X`M_CqaTc1b26L55Yrl5AGV=A-KB*cel$va`!no`}_XD zJw4CUJvH6yovx}SRcpOqStw{sz#9M@001BZh;aFjSwjE-&@cc11^^CH6J%rUXl(7M ztL$cL?4Zr$YGp~94Gl??34nZk{=din;SnfR9z&Dal}fk{s`r*-n$#EkxZfA3)kTFjEt&4s6)E))3ZlN-p9wrk zeG~W3Eme)Gj*Z~R#6>zec{5oHE7!1Kz+_JTLQaLvQ3KDm+i|Y2Ct4CJ1fpuC+bM>; zn>!E~=v0T4rFFtJ;C2o8z=$ui^0B4mJu90kWqFzdkqT47O%yF=CAhKXo>*=_;2-^Q{?_rFC8pekTH*cR^ag9B%Y#4GcaQw!8k!G;O zp1HLK!Z`$^nk@rXnvT#e2_3#e{(5_Msmg_Oit~_w96iO&9h1HQNOIA~i7Vs1LWK51 zJOtUB&Rs_m-jysOFMrJzAz4d2Lne5BwX>HOC;<51%(Pa8nd0(Q_vBvhBD|WZuD!9P z1CZ&D^MB3r|FBK|OV>-|p9z*(Xrk7(;MP*$?q?*Z;y?v#ZP->%cC<&I^ z-w~oJ;|D-V`m}mK4lXY9NA35MU2m|LMxbNzQPjD74^FzbbAqL#wojC>D_!qKbDqAM zzD|*paiei=jiD=PD9n-_Sf!AdJQJ%#9b@{4{}v;UFc@1P#ZRMGUVX*jwhUrgRO#q@ za78^==KklgG@seT{5>S0P#(F%i4?4U2ZK-ZWuE<(WLJ0iDoUn2W)%h*_Ppe7x<-~i zF2vH>F`hgb71H}Zkh7!TvW`jiQDt8FXwK`Z zvrC#Y7TUZcko-{P00nNKhIWyfjLrLUm4L2ETWv-b2xSxOb~4iEe8Yjf0flkZL0=e- z4(*O%dBO){GjcHk1!r*do!DOz1_S+Y|Dfau0XfwHqfs!vpCJR2d*_yh3NIulpIq#+ zaUz)Ae3aRV)!gAH(cr7j4ApG;-Ulije)q4buP05VHQ9b?1T9{_`R4CNGJb*gR+=Bl z4KV&|ij4lYL;M=v5YoKp>^>wEIQ)MKGaJ*z*)g>Pq06=+t;#Fn-Rar`v-`k`yqk4a< zdC|N3>PuTg3t7xQG9{y;VyylUkJFdD)-yNEDVuHn;sqPYsHw|q1zegJ^l5u&u zw2(xbR|NJ2>l~*nGyA45?nLhofHscdB+~`v(d=PA4cMA+CDNpZFqPlKp z5Q#KccAwNsGpsk-l*0o-OMaxxia-D04JoH6yvv~oOR>6ry~@JRsK6=|O5(T2fPMOZ-%mI2j?3)e~8^b+_FrxvtSV zC{PJqT;KQUu>dpX4OUC;cSm|u{lJhPw+x6~Oz7dM(tT0c(POptKh{yMU%r$Rd+3;f zVHxj|RB@5z$Hx;3PV*SD2p*)ggET1E9%DIMAiLt68LJVG>X zOE%t_2uFt}8j8C}ztLI8%*_BJPl{1mcjDVG52141s@w!^BMwId+&A3({Dh<1k?tfh zFz-CTsnT{tl)HAq!dvzu-8;Ou{3JmiA;yElIkrFia5_cgy`A%U$SLyTbl~$#33sCaw&ohKwKj%6z>NG30v){ony> zX4SY4{gh$yl(7d)salCuhKFdZ^xoGox^L}2nh7QQrByj`#8E%NSlh?VD$9h$I=Wy- z$n|~xG^4aAOa4IuBJ+TOTMmOneAM_kuhDLf6^hs~xz3Z2^jA1Vi+^oW_E8S_6nfAE zx3ZMG=Xv>_<}wjN^5YI6O}Hs7N+ujgzxas2*dZ!35tKbI0Zyns49@J=U?y}hDFoio zw}HmA_}!%yf{jzYo|=Sv4fIRn`wSyuZoj?%w5CN2&RUI<$mOt3{j`a}01C08@FZHD zT%rChegSX1c%@7U{tnM9HhwjhzE4_^A22_L>^SaMv*=j$lfVFT8isAl^7$6l{8aHK z7i7{Gyu3FDt39!_pN2(;WR4=@!#e_Z>~??n?kkt{1H8SSM`2As`bY(r6UHwnw!1oM zUZ9K<@qA07OxfB|TJ_lzyIj*Ug!?3j$buSyIg{aBA6=oexCXTfo*9mj$lM->`egGE z7}!)h=54pUe#qMBir5!{DCzJqe%0*#v-GtxfDD_co-di@3w&r96Sey;T8rWrd!=Vc z(Q`qE+D~fgO)M1)+qysIns>OCRb9fC@!@Fp^~7AN7yXD>I%x(5WQdQ7(%8ccFEKSw zyJ}JbTrxNtyl|gM@|Oau20!V1Fr7W-s`a@qK|-wWVtkwJ4RpZ>!Q~^j`l5o(QI#?-=KbdFj2BmM#}5|MnE-P4_}!{}rOB+GHimR?JF>v{Y2AW7P2U<-vxSgXQe zN%=Q(8g4M-jd$WPP_0T^UB*}|BC1G(q|lv%kK&zL0g76rWL0i3ykd|mE8MFm~R>RWA!JQ+ESqu z6lB8sV%4w^DudorKH+wGch6Twzb%Rt+?kgSb7LO3iy-(}T5N80t_xcORH!{+*z)=q zz$@@U{rNE3i-g}gr+rlFd@N9!Cst1|TZ*S&{OH`*K;*#XI>W*X89Lu;c zPENG=A_I;_lh%4C!jjy|nG%cU96XWR+{(UEV4DWVL?FSwoRnWV4$|)nQ3+c^AfA}w z5v@7uJ%z?IzX(6US9o!orcfYQ3SZl5U3hB2g^NhaKH3@TV?3 zfxk)*=>b>=4c<87cZN?TaS%Z;?p$O%pG&MUlse!9?s5kyLjHQ zox&%~-^`o_h`{NvzkXl$icrL_{rShw>j4~|ITL$sNKoa%XjB91_)QzISGGKhSVo<{ zqOn%aTSamb34q{Oq>{sUkenJh=e9=VafKrQ@HST}wi_)1FC!Dp$S#zIM=GpZHXn_0 z1(7Nevu^pJ|6eCcOSn!KQB`tw0zEnA`+xz*%?*wJY3Ra8J2hJFp5T*@R>2hB{R4b zMw_ckK91-I=xCFgcR5w=wP@19MIyPndH1a~k>ojuFi_}*89+7k;T}~@?fcT(GmLa~ zxv|!wWQ;m3Aq7TT8ivrYh%SB`6IKr!F~Zdk*l`L+_si$*=!_eiBkN6^U#9LpJs`%* zi>wZ_wZ!(TJIe) zWdd8W@rbcZ6SYN%8BsL0OG)yUjlqbyhtoRT8xA*qAFIXODS>%{4~-Bw^l(H=>sO8i zrHyEJCr2Mvb}@^d4G*SJ#zjB*l8AA7OqV4&Uk}@Jo^c5L@!KNgWYRvW9*mu zC_?CEMAi(sQ>kD2vl_Vt)tca2Ir>sXm77`Ep$tpp^_7_3zEOy;1zf1P$*YAju+eWr zpfb&OMp*nXM!v*i-MJJqZ&#I&&=wO8E}(rCrzxjtO8#U^l}*pPZ@mq5#Pp4g+i^Jv zR!Lp&#c5igSy^_>EL(j_4y0lD~iY1`a+Oj-s!d{=yex6&*Gu`1)7f2ddt`TzD;v{nX0nRW?c#N$zLg zI@`i_=fLj%aG+~|r}FfWLSwkE`n)B_xrWt9f6hU!#dDERv+RM@z8Sg?}|0xL~U28DdSM5J85v@{5ohYnclQ#41dXfF%&n`Ykq`8UO?f(~obCZSzqm959?BeYf9Mnt zyNk4|!x!tTo%@I9u3CP<*ZDqkhX2)M^PS9T0*8{8ksQooU{pUUpL~eMJ z_qxa1#s&b8{vN{|9NjF9|F+T|R+F{aFBOG0uWXE&31D(nnM5-qyO*KJ zGe~*b+Il9WUE+q!rb(*iO@U$u>M1T)1s`G z!CM#3xNkrFri<4zAN5Fx&OgTJG14KiIpEvB85`_ZYq(*weUb+s@?>_ zq1&gFGPKPu&ZMFa?0HHIU4WzQ!~m~`5adF!WEAofWZ`_@7UYYEoUo*u!pBwYc}yG( zr$<_=a5@aTi|dqlyrBws$DV6tTR+3BXhX^T9>J#-;wRx3)Tgfk_kP|=PtI(qyme6( z?knPU9Ep4509oIbm~f8z6*G$P^T&`)E!gSg3;#zzC&c5{R2x(VnSEqHiHc+gY-%ZA;#Ww4lJ;1t9VgI7xa|eTJ$EYeYJ<*@|0c z7wGEl5?Rz#DL)(J;pQnQ{dN+vHZ>`}!mud)3yLUG&|;yG{9yq*G*VUL21qe|R$qPb zau-({^ns??sXBY8haqCjVBS75NTlpm1RDR*zM2cyhStae+T8`!9f}XRlT3WiB`bbvbx6j$&45`P}L8}2it9r&wN!wkWZpC$0{q9a~ zqeX)j*XZ_42aCMG^Ye>0qdp~Udv7*r+}+LQFF`^f1^$xVNcY6m4nM3nIh9zqC^=`Y z=)4&hr;3K$Zat-SIboq*~>PEEX*mMn3TP4TqyH$Xk-$?Km7yx*W^E2)Y4 zY9E>Q)myFKRZ#mKL^VJEVo8QZS_~MnbRk-Fx_bPGPjU$}z)V#dtwNMVjpYwr4$G-O z8&|<~vA6!${>-}(G-mp`S~sBw0C4|fSMuk6Bwa)E^9C=nw~)#MNns00EHoTgUXded zePVY?;V7m0Asso3k3*PS+TGp6=V`DmzQ5|NkuGn|xq70p^z-5E`o-8}ph{RYX^-r6ccki?`1dU(mq(d;I))0p5u& zvak(f{MK(94p|9CXDkdqo*x+-xAN+g9Alc4lD&M|J;Ns^VU$}a`*LrozVLokVqb2{ zm}Kze>1^<63Sg#l8uCHBDxe&k;1|Hu2G1%5ry6ElQVaaNyd`})52weJzOo4_7d^tjtw_#Oz$P&n{mkce-3LjI_M)&6lm2*&xjyvmj3qkU z6{zgg?bw>T=K`_hUkGG~1!S>ChHpu>gvRuxR6F$~yfAv8wbRp!O-_(6tm5$W=sgMw z2A=e7=%Q_oodgYhD4HMomy8Bl_?ah;^ z4ximG`*9)mGOh8Ad+6jAycBXxaH+_mXm(yet;RGRX9}So>1?#z#=~jiJKYvSWfU5I zDC&>UC5OILfSm(m7#A2;_p~ktWZ9pdwv<1har%Cm_u{gBzz{OMR`ESr3p?Vs)eLYT z!_755eQf{ACqi`EV&lk^K!$~Qnsb;a0pg(IB3x1up>{CB!(QJ6C3-t%P6)GaC4r|H zUG_VL$Ti4T#JVwUq%XZPieoFq%7p@#!UE&pWr>UPWICX}xE=~!dJ89t!KHjeMLWwL z?~G+Y8W@cAWTCVGRk2WNf~wdk$CM|aZj=T6e=vJeh6gzQtiL30HFW@QlVm}FQFFie z1VcE0gNg`^q!NRTjHPDk+Irn}338@qVh<4q*uIz|`y1%ujTi101OB_ppO3nL1l);*1v{$DvvD%b3xaF0Sy&M5ecco%dLy_yUzqZfiYivq0kJ zERKFNAqw=VLlZ`RwyEO``bpSuXyD?^MEDD9WNn&=I+<4;laIFQ zcDwQURNpUHcc7YG0aKf+bFWw3*Ie*L7!4lLr@esUgZ8*sUO4Z*dK4mPjCZW5s%trjCaDET- z3kEZ&aQ2f*W(`sa%`>$p-34a;3wpUDL8FT)uLMtmqG-Cp28mJ7vF?Z2vq9kJu8uq_zeGo;hcQzb0afIrTB2g5#JYoSs_ZuT2pip4z%b3lk+0# zAYxY~rQ{$5OmcLyqkyiA@g(@{na*Qv)I%6>cQmT*dqs`W^;bhJ5%QVl-MMQGht4Zf z;_&u)zMTLE-z1#k(gzIaJn_ysIxLQVoO`x^)(Ec=?=I|{i^i77Ax+D*_Y9hXbDtoe zqtbGzlCVWw(B?GVSjHZ%UFI}Wr*}9LiznoOLz;bCHU(6qIQR+;Wa1qD@>I!x74qCVRv?OH{G^6Ott=A_s;| zFV9p(zqkjDYT@m9GD*mEX4Ucx=8@cZHT6VH8&45fw_1bv$lW|ISdJDcEk{bz$hA^f zj^eIXuh&vT6)WHQ9lqE_DoI=#Y8}4id*F9tOBrWuIQoe(Y&agWd{7E@?>MRrb-;`UBStDZA7c(^q^7LuBj=|t~QQaCu7)K6NS1I0V%KLl=N+d(icj%Tv%_U6)V(l4r&6UoQfn$$@sMaH}KH4@Xc zmh{%=&}L+#-_yR?ByfN>%L^shq{xq}(_|Jruu#$Owt|#dd~%kP=)78n4acXaGf1uL zf-@UFkcnamcZTlk15sCnh`!(4fnteDL-}KdoouWHADz1;JKb0euI!nFomdQPaPr{& z*K6h=@wCXS1&u{3qB%&uOVzNqYkUnV(MTN6yQr&eK>e^f zvCqD>i)LFQZ(V6tb9w=X(0e;qR5n^9D^$Sk@nv@LTp^(?Le|uF=JFOCcEIOUMag!z za8Y1T4mjSiS$cLv3Tdz75^Ra{jJetHn0)8t6w`i|Z(H7zJrr4y5hOT+~dj6Dh zUeIy*wk=&vr-7-ZvdG;&U=QO^oYATUttD<2DoX$MR6^&BZADJ+*S>+F0F^BitL$ix z5bzxN(=LbXb^E(rHA0Ip@1CoEq0U1Np53p8p1zF-E?KBX`@va{+M&%-=d-dJKNv+G zcaf~qdTrlB(DahYBV1u{bOsIG$i9mawX3#)v`|i^vgLcfLh+SHvf&i|go#B9F#zX9 zetpEwP15_m0tGE55!H==#j(FL#?3h|PuiuleHq z*UBQ=Ya!am#t>|8W9tAkw6Qn-2c_!2_2<{2i;N#q=wikcyODYXZ6TF(k3!L?rpov> z`Gw0s`^~9eTUl_}kuSzxpV$#ILNw`_jSP=3#ZAtaF|;WDlu$Jf@AM@_!7L9{KA?3U z*nNg}>t&@{pEnCJ5hrUfjmOW_2_f=J3C@=_DD1I zwgT6FBDpfR!r#Gbo4c33W{$X$WLShh)A^Mp> zhMHmnBGxI-=ehI{;jgkFmdwo4zOQ;&^UD2u_xD|c?Q6Z!(b!(e*wOKi!XxmvHVc!1 znf0NHfNYl@s`t4*eWgDL7B&RYUltaNaA^t~rjmwkG~5YnNnh7c+}^Re{;~(QRZjmJ zHAba_u}X=R3#QR={oH(WoY8!Po}p|PjJ=>GxIfo{uUa`gBngYt&_i`Xqyd|?BFeSY zBg{|_-p~2ys6$LdfW6Xs?HDjtb%hs-#Dw56yq|Axn9y$KZykb_E2H5qu4hrN3QQo^ z9f8Rx8vGE~^4U|UPCxX3_fyYm{r9s?sn)& zdl-S%1=5`wo&_+6POzRGt?yQ-JCu42RWeCfqQ%I6F%qpT+%QN}E)173oOY5lFEGAG zXd||1@csKE+)5FS0ip2k{5g-*c>6;oIfaU0!CWnm{5^4>P#^iJCO^chxTpd5*(yg; zs2}=i_|{Cmb_jggn(!L&+Wrx>Y1EPbjKgLr_9;E(hkV$;=Xu1C%kwlj7GZrS&ViGj zVV{RyLe7VM=$FaXtDpw}wf(Pec^$HU9O>~QHjB)N zK_^hxB#6rdJj=X@ex(LdT$dFF5b@5Rc*$cJQkw1JY4U^q_s(S zbuVMbd%$7a*_bfU1Qs~gUm8}Q8gA*}DKX494Si(@A$n?`Z$+%^7!r zNQc!0jjs7`|B%6O_!PR>l2mDy9+YPKjTep*ICLHn2qjXO)h1OS%tBS>e!u#Ycfk*Z z#JR8ghlZEz0G~yuP0>mE2$~_N=OzHAd`nANt{&zgfr!YdXsbm<(}KU0M~$nOg657D zT(1|LXB9bAsG?Xx%+RBi`7mVBjM+mHz`UlM%{8AQ9LX`4Z&K%AVcU&YBRC8WnpK%_W+Dt=z$&;mF8Aa7 z!5kGvG(&pvHzxiKuZ120&}qx)Mb<(cHE0BAt8rtNY3=rT9);{+CQx8%ETg{j^cH0j zWp=1U{H|!r*={$B9?9pLx;`kw&1uNn70`t-lq z_TNQ+Pi6fnT2JtMXZ}oV{f_eQORhgL000##0N_6sV84t19vS}xIC>3~ukZg`T>QQL qw>bGb=)ZgFKOq5tD%yW}r+@fuuq@204gvs(uOI4HHMVE?qxC;Ld#d07 literal 0 HcmV?d00001 diff --git a/doc/wiring_details.ods b/doc/wiring_details.ods deleted file mode 100644 index 4ff20eda8c23b5616726f6fd6ca7e6ce043a886a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83336 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 VYs~}zfbjLQ{lXt0{x2W`_+PejXPp25 diff --git a/src/default.cr3 b/src/default.cr3 index fdae9e7..f8bf2e0 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -17,8 +17,7 @@ Const UTC_OFFSET = -8 'offset from UTC as +/- hours; PST = -8 Const FAST_INTV = 100 'length of primary scan interval, milliseconds Const SLOW_INTV = 1 'length of secondary scan interval, seconds Const SOIL_INTV = 30 'length of slowest sensors (soil probes, gps, shfp) -Const STAT_OUT_5 = 5 'stats output interval #1, minutes -Const STAT_OUT_30 = 30 'stats output interval #2, minutes; use multiple of STAT_INT1 +Const STAT_OUT_30 = 30 'stats output interval minutes Const SDM_PER = 30 'default SDM clock speed Const INTEG = 250 'analog measurement integration time (250/_50hz/_60hz) @@ -45,39 +44,16 @@ Const TE525_PULSE = 2 'TE525 rain gage pulse input chan # Const EC100_SDM_ADDR = 1 'SDM address for EC100/EC150/CSAT3A Const GPS_COM_ADDR = Com4 'GPS serial input port # Const SDI_COM_ADDR = 5 'serial port reserved for SDI communications = Com3 -Const DEC_5TM_ID5_SDI_ADDR = 5 'first 5TM sensor address -Const DEC_5TM_ID6_SDI_ADDR = 6 ' ... -Const DEC_5TM_ID7_SDI_ADDR = 7 ' ... -Const DEC_5TM_ID8_SDI_ADDR = 8 ' ... -Const DEC_5TM_ID9_SDI_ADDR = 9 ' fifth 5TM sensor address -Const DEC_5TM_IDA_SDI_ADDR = "A" -Const DEC_5TM_IDB_SDI_ADDR = "B" -Const DEC_5TM_IDC_SDI_ADDR = "C" '------ OPTIONAL SENSORS ANALOG INPUT MAP ----- Const HFP_1_SGNL_DIFF = 6 'heat flux plate sensor signal diff input chan # Const HFP_2_SGNL_DIFF = 7 ' plate #2 -Const SS109_001_SE = 27 'Model 109SS (CSI) #001 -Const SS109_002_SE = 28 ' #002 -Const LGR_N2O_DIFF = 8 'Los Gatos N2O diff input chan # -Const LGR_CO_DIFF = 9 'Los Gatos CO diff input chan # -Const LGR_H2O_DIFF = 10 'Los Gatos H2O diff input chan # -Const PIC_CO2_DIFF = 11 'Picarro CO2 diff input chan # -Const PIC_CH4_DIFF = 12 'Picarro CH4 diff input chan # -Const PIC_H2O_DIFF = 13 'Picarro H2O diff. input chan # -' 14 is designated as SE27/28 for the heat flux plate - -'----- OPTIONAL SENSORS DIGITAL INPUT MAP ------ -Const DEC_NDVI_UP_SDI_ADDR = 0 '2nd gen sensors from decagon (UI team) -Const DEC_NDVI_DN_SDI_ADDR = 1 -Const DEC_PRI_UP_SDI_ADDR = 2 -Const DEC_PRI_DN_SDI_ADDR = 3 + +Const TCAV_DIFF = 8 'averaging thermcouple diff input chan # + ConstTable Const SHFP_ENABLED = True - Const NDVIPRI_ENABLED = False - Const LGR_N2O_ENABLED = False - Const PIC_CH4_ENABLED = False EndConstTable '----- FIXED CALIBRATION VALUES ------ @@ -89,19 +65,15 @@ Const oh34B_WD_MULT = 720 '720/0 as specified in CSI manual: Const oh34B_WD_OFFSET = 0 ' Met One 034B Windset rev3/12, pg 6 Const oh34B_WS_MULT = 0.7989 '0.7989/0.28 as specified in above CSI manual Const oh34B_WS_OFFSET = 0.28 -' ** NRLITE_MULT -Const NRLITE_OFFSET = 0 -' ** LI190_DENS_MULT -' ** LI190_TOT_MULT -Const TE525_MULT = 0.254 -Const TE525_OFFSET = 0 -' **These values depend on site-specific values; assignment is deferred -' to program execution time. +Const TE525_MULT = 0.254 'Table 7-2, CSI manual rev 8/16 '========================== NO USER-SERVICEABLE PARTS BELOW =========================== '----- PHYSICAL CONSTANTS ----- -Const MU_WPL = 29/18 'Ratio of the molecular weight of dry air to water vapor +Const MW_CO2 = 44.01 'molecular weight of CO2, g/mol +Const MW_H2O = 18.016 'molecular weight of water, g/mol +Const MW_AIR = 28.964 'molecular weight of dry air, g/mol +Const MU_WPL = MW_AIR/MW_H2O 'Ratio of the molecular weight of dry air to water vapor Const R = .0083143 'Universal gas constant [kPa m^3/(K mol)] Const RD = R/29 'Gas constant for dry air [kPa m^3/(K g)] Const LV = 2440 'Estimate of the latent heat of vaporization [J/g] @@ -126,109 +98,34 @@ Units n = samples Dim sensor_shfp As Boolean 'set based on site SN '----- RETAINED SETTINGS ----- -Const NUM_SETTINGS = {36} 'set to length of settings array +Const NUM_SETTINGS = {24} 'set to length of settings array Const WRITEFILE = 0 Const READFILE = 1 Dim settings(NUM_SETTINGS) 'values retained via file written to datalogger CPU Alias settings(1) = sonic_azimuth Alias settings(2) = NRLite2_sens -Alias settings(3) = LI190_mult +Alias settings(3) = LI190SB_sens Alias settings(4) = cup_ws_enabled Alias settings(5) = vane_wd_enabled Alias settings(6) = rain_enabled -Alias settings(7) = soil_5_enabled -Alias settings(8) = soil_6_enabled -Alias settings(9) = soil_7_enabled -Alias settings(10) = soil_8_enabled -Alias settings(11) = soil_9_enabled -Alias settings(12) = soil_A_enabled -Alias settings(13) = soil_B_enabled -Alias settings(14) = soil_C_enabled -Alias settings(15) = soil_5_depth -Alias settings(16) = soil_6_depth -Alias settings(17) = soil_7_depth -Alias settings(18) = soil_8_depth -Alias settings(19) = soil_9_depth -Alias settings(20) = soil_A_depth -Alias settings(21) = soil_B_depth -Alias settings(22) = soil_C_depth Alias settings(23) = hfp1_sens Alias settings(24) = hfp2_sens -Alias settings(25) = lgr_n2o_mult -Alias settings(26) = lgr_n2o_offset -Alias settings(27) = lgr_co_mult -Alias settings(28) = lgr_co_offset -Alias settings(29) = lgr_h2o_mult -Alias settings(30) = lgr_h2o_offset -Alias settings(31) = pic_co2_mult -Alias settings(32) = pic_co2_offset -Alias settings(33) = pic_ch4_mult -Alias settings(34) = pic_ch4_offset -Alias settings(35) = pic_h2o_mult -Alias settings(36) = pic_h2o_offset -Units soil_5_depth = cm -Units soil_6_depth = cm -Units soil_7_depth = cm -Units soil_8_depth = cm -Units soil_9_depth = cm -Units soil_A_depth = cm -Units soil_B_depth = cm -Units soil_C_depth = cm Units hfp1_sens = uV/W/m^2 Units hfp2_sens = uV/W/m^2 -'ignore mults & offsets Units sonic_azimuth = degEofTN Units NRLite2_sens = uV/W/m^2 -Units LI190_mult = mmol/s/m^2/mV +Units LI190SB_sens = uA/mmol/m^2/s Public choice(NUM_SETTINGS) Alias choice(1) = set_sonic_azimuth Alias choice(2) = set_NRLite2_sens -Alias choice(3) = set_LI190_mult +Alias choice(3) = set_LI190SB_sens Alias choice(4) = set_cup_ws_enabled Alias choice(5) = set_vane_wd_enabled Alias choice(6) = set_rain_enabled -Alias choice(7) = set_soil_5_enabled -Alias choice(8) = set_soil_6_enabled -Alias choice(9) = set_soil_7_enabled -Alias choice(10) = set_soil_8_enabled -Alias choice(11) = set_soil_9_enabled -Alias choice(12) = set_soil_A_enabled -Alias choice(13) = set_soil_B_enabled -Alias choice(14) = set_soil_C_enabled -Alias choice(15) = set_soil_5_depth -Alias choice(16) = set_soil_6_depth -Alias choice(17) = set_soil_7_depth -Alias choice(18) = set_soil_8_depth -Alias choice(19) = set_soil_9_depth -Alias choice(20) = set_soil_A_depth -Alias choice(21) = set_soil_B_depth -Alias choice(22) = set_soil_C_depth Alias choice(23) = set_hfp1_sens Alias choice(24) = set_hfp2_sens -Alias choice(25) = set_lgr_n2o_mult -Alias choice(26) = set_lgr_n2o_offset -Alias choice(27) = set_lgr_co_mult -Alias choice(28) = set_lgr_co_offset -Alias choice(29) = set_lgr_h2o_mult -Alias choice(30) = set_lgr_h2o_offset -Alias choice(31) = set_pic_co2_mult -Alias choice(32) = set_pic_co2_offset -Alias choice(33) = set_pic_ch4_mult -Alias choice(34) = set_pic_ch4_offset -Alias choice(35) = set_pic_h2o_mult -Alias choice(36) = set_pic_h2o_offset - -'----- SELF-MONITORING ----- -Dim SkippedScans(3) -Alias SkippedScans(1) = skipped_10hz_scans -Alias SkippedScans(2) = skipped_1hz_scans -Alias SkippedScans(3) = skipped_5s_scans -Units SkippedScans = scans - -Dim watchdog_errors -Units watchdog_errors = counts '*********** CR3000 ************ @@ -244,7 +141,7 @@ Const BANDWIDTH = 20 '20 = 20 Hz Const DELAY_EC150 = INT (4000/FAST_INTV/BANDWIDTH) 'Automatically computed lag of the EC150 data. Const EC150_REC_BCK = OFFSET-DELAY_EC150 'Number of records back to align EC150 data. -Dim sonic_irga_raw(12) 'unlagged EC150 irga + CSAT3A sonic data +Dim sonic_irga_raw(13) 'unlagged EC150 irga + CSAT3A sonic data Dim sonic(5) 'lagged working CSAT3A data Alias sonic(1) = Ux @@ -267,6 +164,7 @@ Alias irga(5) = amb_press Alias irga(6) = CO2_signal Alias irga(7) = H2O_signal Alias irga(8) = Tc +Alias irga(9) = CO2_hf 'irga(1) calculated using sonic temp instead of thermistor Units CO2 = mg/m^3 Units H2O = g/m^3 Units diag_irga = bitmap @@ -275,6 +173,10 @@ Units amb_press = kPa Units CO2_signal = unity Units H2O_signal = unity Units Tc = C +Units CO2_hf = mg/m^3 + +Dim CO2_hf_ppm +Units CO2_hf_ppm = ppmv Dim mask As Long Dim diag_sonic_tmp As Long 'used to break out the CSAT3A sonic head diagnostic bits. @@ -283,7 +185,7 @@ Dim diag_irga_tmp As Long 'used to break out the EC150 diagnos Dim irga_disable_f As Boolean 'TRUE when EC150 sends bad data. Dim cov_array_sonic(1,4) 'used to hold input data for cov instructions -Dim cov_array_cs(3,4) +Dim cov_array_cs(4,4) Dim etcvar(3) Alias etcvar(1) = divisor 'used to find molar mixing ratio. @@ -330,6 +232,12 @@ Units CO2_wpl_H = mg/(m^2 s) Units H2O_wpl_LE = W/m^2 Units H2O_wpl_H = W/m^2 +Dim Fc_hf_irga 'CO2 flux using alt. CO2 value, without WPL +Dim CO2_hf_wpl_LE 'CO2 flux WPL latent heat component, using alt. CO2 value +Dim CO2_hf_wpl_H 'CO2 flux WPL sensible heat component, using alt. CO2 value +Dim Fc_hf_wpl 'CO2 flux using alt. CO2 value with WPL corrections +Units Fc_hf_wpl = mg/m^2/s + '********** HMP-155A temp/RH probe ********** Dim hmp(4) @@ -365,17 +273,13 @@ Dim hor_wind_raw '********** LI190SB quantum PAR sensor *********** Dim li190_dens_mult Dim li190_tot_mult -Dim LI190SB_sens -Dim LI190R_mult -Units LI190SB_sens = uA/mmol/s/m^2 -Units LI190R_mult = mmol/s/m^2/mV Dim par(3) Alias par(1) = PAR_mV Alias par(2) = PAR_flxdens Alias par(3) = PAR_totflx Units PAR_mV = mV -Units PAR_flxdens = umol/s/m^2 +Units PAR_flxdens = umol/m^2/s Units PAR_totflx = mmol/m^2 @@ -427,59 +331,6 @@ Units max_clock_change = ms Units nmbr_clock_change = occurrences -'********** Decagon 5TM soil moisture/temp ********** -' Required so soil table can record NAN if probes are not used. -Dim fiveTM(24) -Alias fiveTM(1) = soil_5TM_ID5_E -Alias fiveTM(2) = soil_5TM_ID5_T -Alias fiveTM(3) = soil_5TM_ID5_VWC -Alias fiveTM(4) = soil_5TM_ID6_E -Alias fiveTM(5) = soil_5TM_ID6_T -Alias fiveTM(6) = soil_5TM_ID6_VWC -Alias fiveTM(7) = soil_5TM_ID7_E -Alias fiveTM(8) = soil_5TM_ID7_T -Alias fiveTM(9) = soil_5TM_ID7_VWC -Alias fiveTM(10) = soil_5TM_ID8_E -Alias fiveTM(11) = soil_5TM_ID8_T -Alias fiveTM(12) = soil_5TM_ID8_VWC -Alias fiveTM(13) = soil_5TM_ID9_E -Alias fiveTM(14) = soil_5TM_ID9_T -Alias fiveTM(15) = soil_5TM_ID9_VWC -Alias fiveTM(16) = soil_5TM_IDA_E -Alias fiveTM(17) = soil_5TM_IDA_T -Alias fiveTM(18) = soil_5TM_IDA_VWC -Alias fiveTM(19) = soil_5TM_IDB_E -Alias fiveTM(20) = soil_5TM_IDB_T -Alias fiveTM(21) = soil_5TM_IDB_VWC -Alias fiveTM(22) = soil_5TM_IDC_E -Alias fiveTM(23) = soil_5TM_IDC_T -Alias fiveTM(24) = soil_5TM_IDC_VWC -Units soil_5TM_ID5_E = dimless -Units soil_5TM_ID5_T = C -Units soil_5TM_ID5_VWC = v/v -Units soil_5TM_ID6_E = dimless -Units soil_5TM_ID6_T = C -Units soil_5TM_ID6_VWC = v/v -Units soil_5TM_ID7_E = dimless -Units soil_5TM_ID7_T = C -Units soil_5TM_ID7_VWC = v/v -Units soil_5TM_ID8_E = dimless -Units soil_5TM_ID8_T = C -Units soil_5TM_ID8_VWC = v/v -Units soil_5TM_ID9_E = dimless -Units soil_5TM_ID9_T = C -Units soil_5TM_ID9_VWC = v/v -Units soil_5TM_IDA_E = dimless -Units soil_5TM_IDA_T = C -Units soil_5TM_IDA_VWC = v/v -Units soil_5TM_IDB_E = dimless -Units soil_5TM_IDB_T = C -Units soil_5TM_IDB_VWC = v/v -Units soil_5TM_IDC_E = dimless -Units soil_5TM_IDC_T = C -Units soil_5TM_IDC_VWC = v/v - - '********** HFP01SC heat flux plate ********** Dim hfp(4) Alias hfp(1) = soil_hfp1_heat_flux @@ -490,49 +341,17 @@ Units soil_hfp1_heat_flux = W/m^2 Units soil_hfp2_heat_flux = W/m^2 Units soil_hfp1_sensitivity = W/m^2/mV Units soil_hfp2_sensitivity = W/m^2/mV - -'********** Los Gatos N2O/CO analyzer ********** -Dim lgrn2oco(3) 'data variables -Alias lgrn2oco(1) = lgr_n2o -Alias lgrn2oco(2) = lgr_co -Alias lgrn2oco(3) = lgr_h2o -Units lgr_n2o = scale-dependent -Units lgr_co = scale-dependent -Units lgr_h2o = scale-dependent - -'********** Model 109SS temp probes ********** -Dim m109ss(2) -Alias m109ss(1) = soil_109SS_1_T -Alias m109ss(2) = soil_109SS_2_T -Units m109ss = degC - -'********** Picarro CO2/CH4 analyzer ********** -Dim picco2ch4(3) As Float -Alias picco2ch4(1) = pic_co2 -Alias picco2ch4(2) = pic_ch4 -Alias picco2ch4(3) = pic_h2o -Units pic_co2 = scale-dependent -Units pic_ch4 = scale-dependent -Units pic_h2o = scale-dependent - -'********** Decagon 2nd gen. sensors (UI) ********** -Dim decagon(8) As Float -Alias decagon(1) = dec_ndvi_up1 -Alias decagon(2) = dec_ndvi_up2 -Alias decagon(3) = dec_ndvi_dn1 -Alias decagon(4) = dec_ndvi_dn2 -Alias decagon(5) = dec_pri_up1 -Alias decagon(6) = dec_pri_up2 -Alias decagon(7) = dec_pri_dn1 -Alias decagon(8) = dec_pri_dn2 -Units decagon = unknown +'********** Averaging thermocouple ********** +Dim tcav(1) +Alias tcav(1) = tcav_T +Units tcav = degC '********** Intermediate variables ********** -Dim dly_data_out(12) 'used to temporarily store the lagged record. +Dim dly_data_out(13) 'used to temporarily store the lagged record. -Dim work_stats_out(35) +Dim work_stats_out(40) 'sonic processing Alias work_stats_out(1) = Ts_Std 'results of covariance instructions, 10 qntys Alias work_stats_out(2) = Ts_Ux_cov @@ -571,6 +390,11 @@ Alias work_stats_out(32) = irga_samples '1 @ totalize Alias work_stats_out(33) = e_hmp_Avg 'two averages Alias work_stats_out(34) = e_sat_hmp_Avg Alias work_stats_out(35) = samples_possible +Alias work_stats_out(36) = CO2_hf_mg_m3_Avg '1 average +Alias work_stats_out(37) = CO2_hf_mg_m3_Std 'results of 1 covariance, 4#s +Alias work_stats_out(38) = CO2_hf_Ux_cov +Alias work_stats_out(39) = CO2_hf_Uy_cov +Alias work_stats_out(40) = CO2_hf_Uz_cov Units Ts_Std = C Units Ts_Ux_cov = C m/s Units Ts_Uy_cov = C m/s @@ -606,12 +430,10 @@ Units irga_samples = samples Units e_hmp_Avg = kPa Units e_sat_hmp_Avg = kPa Units samples_possible = samples - -Dim out_daily(17) -Alias out_daily(10) = min_battery -Alias out_daily(12) = max_battery -Alias out_daily(14) = min_tmpr -Alias out_daily(16) = max_tmpr +Units CO2_hf_mg_m3_Std = mg/m^3 +Units CO2_hf_Ux_cov = mg/m^2/s +Units CO2_hf_Uy_cov = mg/m^2/s +Units CO2_hf_Uz_cov = mg/m^2/s '============================ REMOTE MONITORING ============================ @@ -622,41 +444,15 @@ DataTable(debug,True,2) Sample(2,oh34B(1),IEEE4) Sample(1,Rain_mm,IEEE4) Sample(15,gps_data(1),IEEE4) - Sample(24,fiveTM(1),FP2) Sample(4,hfp(1),IEEE4) - Sample(2,m109ss(1),IEEE4) - Sample(8,decagon(1),IEEE4) - Sample(1,smtp_response,String) - Sample(1,scadabr_success,Boolean) - Sample(1,scadabr_resp,String) + Sample(1,tcav(1),IEEE4) EndTable '=========================== PROCESSING DATA TABLES =================================== DataTable(work_delay_ec100,TRUE,OFFSET) 'handles lagging CSAT+IRGA data TableHide - Sample(12,sonic_irga_raw(1),IEEE4) -EndTable - -DataTable(work_5min,TRUE,1) - TableHide - DataInterval(0,STAT_OUT_5,Min,1) - Covariance(4,cov_array_sonic(1,1),IEEE4,sonic_disable_f,10) - WindVector(1,-1*Uy,Ux,IEEE4,sonic_disable_f,0,1,2) - Totalize(1,n,IEEE4,sonic_disable_f) - FieldNames("sonic_total") - Covariance(4,cov_array_cs(1,1),IEEE4,irga_disable_f,4) - Covariance(4,cov_array_cs(2,1),IEEE4,irga_disable_f,4) - Covariance(4,cov_array_cs(3,1),IEEE4,irga_disable_f,4) - Average(1,CO2,IEEE4,irga_disable_f) - Average(1,H2O,IEEE4,irga_disable_f) - Average(1,amb_press,IEEE4,irga_disable_f) - Average(1,Tc,IEEE4,irga_disable_f) - Totalize(1,n,IEEE4,irga_disable_f) - FieldNames("irga_total") - Average(1,e_hmp,IEEE4,(inbetween_1hz_scan OR e_hmp=NAN)) - Average(1,e_sat_hmp,IEEE4,(inbetween_1hz_scan OR e_sat_hmp=NAN)) - Totalize(1,n,IEEE4,False) + Sample(13,sonic_irga_raw(1),IEEE4) EndTable DataTable(work_30min,TRUE,1) @@ -678,6 +474,8 @@ DataTable(work_30min,TRUE,1) Average(1,e_hmp,IEEE4,(inbetween_1hz_scan OR e_hmp=NAN)) Average(1,e_sat_hmp,IEEE4,(inbetween_1hz_scan OR e_sat_hmp=NAN)) Totalize(1,n,IEEE4,False) + Average(1,CO2_hf,IEEE4,irga_disable_f) + Covariance(4,cov_array_cs(4,1),IEEE4,irga_disable_f,4) EndTable '=========================== BASE OUTPUT DATA TABLES ================================== @@ -692,82 +490,14 @@ DataTable (tsdata,TRUE,600 FieldNames ("Ux,Uy,Uz,Ts") Sample (1,sonic_irga_raw(5),FP2) FieldNames ("diag_sonic") + Sample (1,sonic_irga_raw(13),IEEE4) + FieldNames ("CO2_hf") Sample (5,sonic_irga_raw(6),IEEE4) FieldNames ("CO2,H2O,diag_irga,amb_tmpr,amb_press") Sample (2,sonic_irga_raw(11),FP2) FieldNames ("CO2_signal,H2O_signal") EndTable -'5min statistics -DataTable (stats5,TRUE,24) - DataInterval (0,STAT_OUT_5,Min,10) - CardOut(0, DAYS*288) - Sample(1,L,IEEE4) 'monin obukhov length, meters - Sample(1,u_star,FP2) 'friction velocity, m/s - Sample(1,tau,FP2) 'momemtum flux, kg/(m s^2) - Sample(1,Fc_wpl,IEEE4) 'density-corrected (WPL) CO2 flux, mg/m3 - Sample(1,LE_wpl,FP2) 'density-corrected (WPL) latent heat flux, W/m2 - Sample(1,Hc,FP2) 'density-corrected sensible heat flux, W/m2 - Average(1,Ts,FP2,sonic_disable_f) 'mean sonic temperature, degC - Sample(1,Ts_Std,FP2) 'stdev of sonic temp, degC - Sample(1,Tc_Avg,FP2) 'mean of corrected sonic temp, degC - Sample(1,Uz_Std,FP2) 'stdev of vertical wind, m/s - Sample(1,wnd_spd,FP2) 'mean scalar wind speed, m/s - Sample(1,rslt_wnd_spd,FP2) 'vector mean wind speed, m/s - Sample(1,rslt_wnd_dir,FP2) 'mean wind direction rel2 north, degrees - Sample(1,std_wnd_dir,FP2) 'scalar stdev of wind direction, degrees - Sample(1,sonic_uptime,FP2) - Average(1,CO2_ppm,FP2,irga_disable_f) - Sample (1,CO2_mg_m3_Avg,FP2) 'mean of CO2 conc, mg/m3 - Sample (1,CO2_mg_m3_Std,FP2) 'stdev of CO2 conc, mg/m3 - Average(1,CO2_signal,FP2,irga_disable_f) - Average(1,(Xv / MU_WPL),FP2,irga_disable_f) - FieldNames("H2O_g_kg_Avg") - Units H2O_g_kg_Avg = g/kg - Sample (1,H2O_g_m3_Avg,FP2) 'mean of H2O conc, g/m3 - Sample (1,H2O_g_m3_Std,FP2) 'stdev of H2O conc, g/m3 - Average(1,H2O_signal,FP2,irga_disable_f) - Average(1,amb_tmpr,IEEE4,irga_disable_f) - Sample (1,amb_press_Avg,IEEE4) 'mean of ambient pressure, kPa - Sample(1,irga_uptime,FP2) - Average(1,T_hmp,IEEE4,(inbetween_1hz_scan OR T_hmp=NAN)) - Sample (1,RH_hmp_Avg,FP2) 'mean HMP relative humidity, % - Sample (1,e_hmp_Avg,FP2) - Sample (1,e_sat_hmp_Avg,FP2) - Average(1,Rn,FP2,(inbetween_1hz_scan OR Rn=NAN)) - Average(1,Rn_meas,FP2,inbetween_1hz_scan OR Rn_meas=NAN)) - Totalize(1,PAR_totflx,FP2,(inbetween_1hz_scan OR PAR_totflx=NAN)) - Average(1,PAR_flxdens,FP2,(inbetween_1hz_scan OR PAR_flxdens=NAN)) - WindVector(1,WS_ms,WindDir,FP2,(WS_ms=NAN OR WindDir=NAN),0,0,2) - FieldNames("Met1_wnd_spd,Met1_rslt_wnd_spd,Met1_rslt_wnd_dir,Met1_std_wnd_dir") - Units Met1_wnd_spd = m/s - Units Met1_rslt_wnd_spd = m/s - Units Met1_rslt_wnd_dir = degrees - Units Met1_std_wnd_dir = degrees - Totalize(1,Rain_mm,FP2,Rain_mm=NAN) '10hz loop - Average(1,soil_5TM_ID5_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID5_E=NAN)) - Average(1,soil_5TM_ID5_T, FP2, (inbetween_5s_scan OR soil_5TM_ID5_T=NAN)) - Average(1,soil_5TM_ID5_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID5_VWC=NAN)) - Average(1,soil_5TM_ID6_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID6_E=NAN)) - Average(1,soil_5TM_ID6_T, FP2, (inbetween_5s_scan OR soil_5TM_ID6_T=NAN)) - Average(1,soil_5TM_ID6_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID6_VWC=NAN)) - Average(1,soil_5TM_ID7_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID7_E=NAN)) - Average(1,soil_5TM_ID7_T, FP2, (inbetween_5s_scan OR soil_5TM_ID7_T=NAN)) - Average(1,soil_5TM_ID7_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID7_VWC=NAN)) - Average(1,soil_5TM_ID8_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID8_E=NAN)) - Average(1,soil_5TM_ID8_T, FP2, (inbetween_5s_scan OR soil_5TM_ID8_T=NAN)) - Average(1,soil_5TM_ID8_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID8_VWC=NAN)) - Average(1,soil_5TM_ID9_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID9_E=NAN)) - Average(1,soil_5TM_ID9_T, FP2, (inbetween_5s_scan OR soil_5TM_ID9_T=NAN)) - Average(1,soil_5TM_ID9_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID9_VWC=NAN)) - Average(1,soil_hfp1_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp1_heat_flux=NAN)) - Sample (1,soil_hfp1_sensitivity,IEEE4) - Average(1,soil_hfp2_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp2_heat_flux=NAN)) - Sample (1,soil_hfp2_sensitivity,IEEE4) - Average(1,panel_tmpr,FP2,(inbetween_1hz_scan OR panel_tmpr=NAN)) - Average(1,batt_volt,FP2,(inbetween_1hz_scan OR batt_volt=NAN)) -EndTable - '30min statistics DataTable (stats30,TRUE,10) DataInterval (0,STAT_OUT_30,Min,10) @@ -776,6 +506,7 @@ DataTable (stats30,TRUE,10) Sample(1,u_star,FP2) 'friction velocity, m/s Sample(1,tau,FP2) 'momemtum flux, kg/(m s^2) Sample(1,Fc_wpl,IEEE4) 'density-corrected (WPL) CO2 flux, mg/m3 + Sample(1,Fc_hf_wpl,IEEE4) 'WPL-corrected CO2 flux using alt. CO2 value Sample(1,LE_wpl,FP2) 'density-corrected (WPL) latent heat flux, W/m2 Sample(1,Hc,FP2) 'density-corrected sensible heat flux, W/m2 Average(1,Ts,FP2,sonic_disable_f) 'mean sonic temperature, degC @@ -790,6 +521,8 @@ DataTable (stats30,TRUE,10) Average(1,CO2_ppm,FP2,irga_disable_f) Sample (1,CO2_mg_m3_Avg,FP2) 'mean of CO2 conc, mg/m3 Sample (1,CO2_mg_m3_Std,FP2) 'stdev of CO2 conc, mg/m3 + Sample(1,CO2_hf_mg_m3_Avg,FP2) + Sample(1,CO2_hf_mg_m3_Std,FP2) Average(1,CO2_signal,FP2,irga_disable_f) Average(1,(Xv / MU_WPL),FP2,irga_disable_f) FieldNames("H2O_g_kg_Avg") @@ -811,21 +544,6 @@ DataTable (stats30,TRUE,10) FieldNames("Met1_wnd_spd,Met1_rslt_wnd_spd,Met1_rslt_wnd_dir,Met1_std_wnd_dir") 'units propogate from other datatable since names match Totalize(1,Rain_mm,FP2,Rain_mm=NAN) '10hz loop - Average(1,soil_5TM_ID5_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID5_E=NAN)) - Average(1,soil_5TM_ID5_T, FP2, (inbetween_5s_scan OR soil_5TM_ID5_T=NAN)) - Average(1,soil_5TM_ID5_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID5_VWC=NAN)) - Average(1,soil_5TM_ID6_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID6_E=NAN)) - Average(1,soil_5TM_ID6_T, FP2, (inbetween_5s_scan OR soil_5TM_ID6_T=NAN)) - Average(1,soil_5TM_ID6_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID6_VWC=NAN)) - Average(1,soil_5TM_ID7_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID7_E=NAN)) - Average(1,soil_5TM_ID7_T, FP2, (inbetween_5s_scan OR soil_5TM_ID7_T=NAN)) - Average(1,soil_5TM_ID7_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID7_VWC=NAN)) - Average(1,soil_5TM_ID8_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID8_E=NAN)) - Average(1,soil_5TM_ID8_T, FP2, (inbetween_5s_scan OR soil_5TM_ID8_T=NAN)) - Average(1,soil_5TM_ID8_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID8_VWC=NAN)) - Average(1,soil_5TM_ID9_E, IEEE4,(inbetween_5s_scan OR soil_5TM_ID9_E=NAN)) - Average(1,soil_5TM_ID9_T, FP2, (inbetween_5s_scan OR soil_5TM_ID9_T=NAN)) - Average(1,soil_5TM_ID9_VWC,FP2, (inbetween_5s_scan OR soil_5TM_ID9_VWC=NAN)) Average(1,soil_hfp1_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp1_heat_flux=NAN)) Sample (1,soil_hfp1_sensitivity,IEEE4) Average(1,soil_hfp2_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp2_heat_flux=NAN)) @@ -865,8 +583,9 @@ DataTable (site_info,TRUE,20) Units UTC_OFFSET = hours Sample(1,sonic_azimuth,FP2) Sample(1,NRLite2_sens,FP2) + FieldNames("NR_sens") Sample(1,LI190SB_sens,FP2) - Sample(1,LI190R_mult,FP2) + FieldNames("PAR_sens") Sample(1,soil_hfp1_sensitivity,IEEE4) 'heat flux plate #1 info FieldNames("HFP_1_sens") Units HFP_1_SENS = W/m^2/mV @@ -887,112 +606,13 @@ DataTable (site_info,TRUE,20) FieldNames("hfp_installed") EndTable -'metadata pertaining to optional sensors -'XXXX TODO how should this table be changed? -#If (LGR_N2O_ENABLED OR PIC_CH4_ENABLED OR NDVIPRI_ENABLED) Then - DataTable(extra_info,True,10) - 'CardOut(0,1000) - Sample(1,NDVIPRI_ENABLED,Boolean) - FieldNames("Decagon_NDVI_installed") - Sample(1,NDVIPRI_ENABLED,Boolean) - FieldNames("Decagon_PRI_installed") - Sample(1,LGR_N2O_ENABLED,Boolean) - FieldNames("LGR_n2oco_installed") - Sample(1,lgr_n2o_mult,IEEE4) - Sample(1,lgr_n2o_offset,IEEE4) - Sample(1,lgr_co_mult,IEEE4) - Sample(1,lgr_co_offset,IEEE4) - Sample(1,lgr_h2o_mult,IEEE4) - Sample(1,lgr_h2o_offset,IEEE4) - Sample(1,PIC_CH4_ENABLED,Boolean) - FieldNames("Picarro_co2ch4_installed") - Sample(1,pic_co2_mult,IEEE4) - Sample(1,pic_co2_offset,IEEE4) - Sample(1,pic_ch4_mult,IEEE4) - Sample(1,pic_ch4_offset,IEEE4) - Sample(1,pic_h2o_mult,IEEE4) - Sample(1,pic_h2o_offset,IEEE4) - EndTable -#EndIf - '=========================== SUPPLEMENTAL OUTPUT DATA TABLES ========================== -#If (LGR_N2O_ENABLED OR PIC_CH4_ENABLED) Then - DataTable(tsdata_extra,True,-1) - DataInterval(0,FAST_INTV,mSec,100) - 'CardOut(0,-1) - Sample(1,lgr_n2o,IEEE4) - Sample(1,lgr_co,IEEE4) - Sample(1,lgr_h2o,IEEE4) - - Sample (1,pic_co2,IEEE4) - Sample (1,pic_ch4,IEEE4) - Sample (1,pic_h2o,IEEE4) - EndTable -#EndIf - -#If (NDVIPRI_ENABLED) Then - DataTable(stats5_ui,True,-1) - DataInterval(0,STAT_OUT_5,min,10) - 'CardOut(0,-1) - Average(1,dec_ndvi_up1,IEEE4,dec_ndvi_up1=NAN) - Average(1,dec_ndvi_up2,IEEE4,dec_ndvi_up2=NAN) - Average(1,dec_ndvi_dn1,IEEE4,dec_ndvi_dn1=NAN) - Average(1,dec_ndvi_dn2,IEEE4,dec_ndvi_dn2=NAN) - Average(1,dec_pri_up1,IEEE4,dec_pri_up1=NAN) - Average(1,dec_pri_up2,IEEE4,dec_pri_up2=NAN) - Average(1,dec_pri_dn1,IEEE4,dec_pri_dn1=NAN) - Average(1,dec_pri_dn2,IEEE4,dec_pri_dn2=NAN) - Totalize(1,n,UINT2,FALSE) - FieldNames("tblcalls_Tot") - EndTable - - DataTable(stats30_ui,True,-1) - DataInterval(0,STAT_OUT_30,min,10) - 'CardOut(0,-1) - Average(1,dec_ndvi_up1,IEEE4,dec_ndvi_up1=NAN) - Average(1,dec_ndvi_up2,IEEE4,dec_ndvi_up2=NAN) - Average(1,dec_ndvi_dn1,IEEE4,dec_ndvi_dn1=NAN) - Average(1,dec_ndvi_dn2,IEEE4,dec_ndvi_dn2=NAN) - Average(1,dec_pri_up1,IEEE4,dec_pri_up1=NAN) - Average(1,dec_pri_up2,IEEE4,dec_pri_up2=NAN) - Average(1,dec_pri_dn1,IEEE4,dec_pri_dn1=NAN) - Average(1,dec_pri_dn2,IEEE4,dec_pri_dn2=NAN) - Totalize(1,n,UINT2,FALSE) - FieldNames("tblcalls_Tot") - EndTable -#EndIf - DataTable(soil,True,100) DataInterval(0,5,Min,4) CardOut(0,DAYS*288) Average(1,soil_hfp1_heat_flux,IEEE4,soil_hfp1_heat_flux=NAN)) Average(1,soil_hfp2_heat_flux,IEEE4,soil_hfp2_heat_flux=NAN)) - Average(1,soil_109SS_1_T,IEEE4,soil_109SS_1_T=NAN) - Average(1,soil_109SS_2_T,IEEE4,soil_109SS_2_T=NAN) - Average(1,soil_5TM_ID5_T,FP2,soil_5TM_ID5_T=NAN) - Average(1,soil_5TM_ID6_T,FP2,soil_5TM_ID6_T=NAN) - Average(1,soil_5TM_ID7_T,FP2,soil_5TM_ID7_T=NAN) - Average(1,soil_5TM_ID8_T,FP2,soil_5TM_ID8_T=NAN) - Average(1,soil_5TM_ID9_T,FP2,soil_5TM_ID9_T=NAN) - Average(1,soil_5TM_IDA_T,FP2,soil_5TM_IDA_T=NAN) - Average(1,soil_5TM_IDB_T,FP2,soil_5TM_IDB_T=NAN) - Average(1,soil_5TM_IDC_T,FP2,soil_5TM_IDC_T=NAN) - Average(1,soil_5TM_ID5_E,IEEE4,soil_5TM_ID5_E=NAN) - Average(1,soil_5TM_ID6_E,IEEE4,soil_5TM_ID6_E=NAN) - Average(1,soil_5TM_ID7_E,IEEE4,soil_5TM_ID7_E=NAN) - Average(1,soil_5TM_ID8_E,IEEE4,soil_5TM_ID8_E=NAN) - Average(1,soil_5TM_ID9_E,IEEE4,soil_5TM_ID9_E=NAN) - Average(1,soil_5TM_IDA_E,IEEE4,soil_5TM_IDA_E=NAN) - Average(1,soil_5TM_IDB_E,IEEE4,soil_5TM_IDB_E=NAN) - Average(1,soil_5TM_IDC_E,IEEE4,soil_5TM_IDC_E=NAN) - Average(1,soil_5TM_ID5_VWC,FP2,soil_5TM_ID5_VWC=NAN) - Average(1,soil_5TM_ID6_VWC,FP2,soil_5TM_ID6_VWC=NAN) - Average(1,soil_5TM_ID7_VWC,FP2,soil_5TM_ID7_VWC=NAN) - Average(1,soil_5TM_ID8_VWC,FP2,soil_5TM_ID8_VWC=NAN) - Average(1,soil_5TM_ID9_VWC,FP2,soil_5TM_ID9_VWC=NAN) - Average(1,soil_5TM_IDA_VWC,FP2,soil_5TM_IDA_VWC=NAN) - Average(1,soil_5TM_IDB_VWC,FP2,soil_5TM_IDB_VWC=NAN) - Average(1,soil_5TM_IDC_VWC,FP2,soil_5TM_IDC_VWC=NAN) + Average(1,tcav_T,IEEE4,tcav_T=NAN) EndTable @@ -1007,41 +627,29 @@ Const Cancel = False Public save_changes As Boolean Dim recompile As Boolean -'HINT define after `save_changes` so these appear below it in Public table -Public test_email As Boolean -Public test_scadabr As Boolean - DisplayMenu("Vineyard DAQ", -1) 'add submenu to main SubMenu("Initial Setup") SubMenu("Soil heat flux plate") MenuItem("Enable?", SHFP_ENABLED) MenuPick(Yes, No) EndSubMenu - SubMenu("Decagon NDVI/PRI") - MenuItem("Enable?", NDVIPRI_ENABLED) - MenuPick(No, Yes) - DisplayLine("SDI Addresses:") - DisplayValue("NDVI up-facing", DEC_NDVI_UP_SDI_ADDR) - DisplayValue("NDVI down-facing", DEC_NDVI_DN_SDI_ADDR) - DisplayValue("PRI up-facing", DEC_PRI_UP_SDI_ADDR) - DisplayValue("PRI down-facing", DEC_PRI_DN_SDI_ADDR) - EndSubMenu - SubMenu("LGR N2O/CO") - MenuItem("Enable?", LGR_N2O_ENABLED) - MenuPick(No, Yes) - EndSubMenu - SubMenu("Picarro CO2/CH4") - MenuItem("Enable?", PIC_CH4_ENABLED) - MenuPick(No, Yes) - EndSubMenu MenuRecompile("Apply now?", recompile) MenuPick(No, Apply) EndSubMenu SubMenu("Settings") - MenuItem("Sonic azimuth", set_sonic_azimuth) - MenuItem("NR sensitivity", set_NRLite2_sens) - MenuItem("PAR multiplier", set_LI190_mult) + SubMenu("Sonic anemometer") + MenuItem("Azmiuth", set_sonic_azimuth) + DisplayLine(" degE of True North") + EndSubMenu + SubMenu("Net radiometer") + MenuItem("Sensitivity", set_NRLite2_sens) + DisplayLine(" uV/W/m^2") + EndSubMenu + SubMenu("PAR sensor") + MenuItem("Sensitivity", set_LI190SB_sens) + DisplayLine(" uA/mmol/m^s/s") + EndSubMenu SubMenu("Cup & vane windset") MenuItem("Enable WS?", set_cup_ws_enabled) MenuPick(Yes, No) @@ -1052,66 +660,18 @@ DisplayMenu("Vineyard DAQ", -1) 'add submenu to main MenuItem("Enable?", set_rain_enabled) MenuPick(Yes, No) EndSubMenu - SubMenu("Soil moisture probes") - MenuItem("Enable 5 ?", set_soil_5_enabled) - MenuPick(Yes, No) - MenuItem("#5 depth", set_soil_5_depth) - MenuItem("Enable 6 ?", set_soil_6_enabled) - MenuPick(Yes, No) - MenuItem("#6 depth", set_soil_6_depth) - MenuItem("Enable 7 ?", set_soil_7_enabled) - MenuPick(Yes, No) - MenuItem("#7 depth", set_soil_7_depth) - MenuItem("Enable 8 ?", set_soil_8_enabled) - MenuPick(Yes, No) - MenuItem("#8 depth", set_soil_8_depth) - MenuItem("Enable 9 ?", set_soil_9_enabled) - MenuPick(Yes, No) - MenuItem("#9 depth", set_soil_9_depth) - MenuItem("Enable A ?", set_soil_A_enabled) - MenuPick(Yes, No) - MenuItem("#A depth", set_soil_A_depth) - MenuItem("Enable B ?", set_soil_B_enabled) - MenuPick(Yes, No) - MenuItem("#B depth", set_soil_B_depth) - MenuItem("Enable C ?", set_soil_C_enabled) - MenuPick(Yes, No) - MenuItem("#C depth", set_soil_C_depth) - EndSubMenu #If (SHFP_ENABLED) Then SubMenu("Soil heat flux plate") DisplayLine("Plate #1 (DF 6):") MenuItem("Sensitivity", set_hfp1_sens) + DisplayLine(" uV/W/m^2") DisplayLine("Plate #2 (DF 7):") MenuItem("Sensitivity", set_hfp2_sens) + DisplayLine(" uV/W/m^2") EndSubMenu #Else DisplayLine("SHFP disabled") #EndIf - #If (LGR_N2O_ENABLED) Then - SubMenu("LGR N2O/CO/H2O") - MenuItem("N2O Mult. (units/mV)", set_lgr_n2o_mult) - MenuItem("N2O Offset (units@0mV)", set_lgr_n2o_offset) - MenuItem("CO Mult. (units/mV)", set_lgr_co_mult) - MenuItem("CO Offset (units@0mV)", set_lgr_co_offset) - MenuItem("H2O Mult. (units/mV)", set_lgr_h2o_mult) - MenuItem("H2O Offset (units@0mV)", set_lgr_h2o_offset) - EndSubMenu - #Else - DisplayLine("N2O/CO disabled") - #EndIf - #If (PIC_CH4_ENABLED) Then - SubMenu("Picarro CO2/CH4/H2O") - MenuItem("CO2 Mult. (units/mV)", set_pic_co2_mult) - MenuItem("CO2 Offset (units@0mV)", set_pic_co2_offset) - MenuItem("CH4 Mult. (units/mV)", set_pic_ch4_mult) - MenuItem("CH4 Offset (units@0mV)", set_pic_ch4_offset) - MenuItem("H2O Mult. (units/mV)", set_pic_h2o_mult) - MenuItem("H2O Offset (units@0mV)", set_pic_h2o_offset) - EndSubMenu - #Else - DisplayLine("CH4/CO2 disabled") - #EndIf SubMenu("Save changes") MenuItem("Save now?", save_changes) MenuPick(Cancel,Yes) @@ -1161,181 +721,24 @@ DisplayMenu("Vineyard DAQ", -1) 'add submenu to main DisplayValue("SHFP 1 sens", soil_hfp1_sensitivity) DisplayValue("SHFP 2 flux", soil_hfp2_heat_flux) DisplayValue("SHFP 2 sens", soil_hfp2_sensitivity) - DisplayValue("109SS 1 tmpr",soil_109SS_1_T) - DisplayValue("109SS 2 tmpr",soil_109SS_2_T) - DisplayValue("5TM #5 e", soil_5TM_ID5_E) - DisplayValue("5TM #5 tmpr", soil_5TM_ID5_T) - DisplayValue("5TM #6 e", soil_5TM_ID6_E) - DisplayValue("5TM #6 tmpr", soil_5TM_ID6_T) - DisplayValue("5TM #7 e", soil_5TM_ID7_E) - DisplayValue("5TM #7 tmpr", soil_5TM_ID7_T) - DisplayValue("5TM #8 e", soil_5TM_ID8_E) - DisplayValue("5TM #8 tmpr", soil_5TM_ID8_T) - DisplayValue("5TM #9 e", soil_5TM_ID9_E) - DisplayValue("5TM #9 tmpr", soil_5TM_ID9_T) - DisplayValue("5TM #A e", soil_5TM_IDA_E) - DisplayValue("5TM #A tmpr", soil_5TM_IDA_T) - DisplayValue("5TM #B e", soil_5TM_IDB_E) - DisplayValue("5TM #B tmpr", soil_5TM_IDB_T) - DisplayValue("5TM #C e", soil_5TM_IDC_E) - DisplayValue("5TM #C tmpr", soil_5TM_IDC_T) - DisplayValue("LGR N2O", lgr_n2o) - DisplayValue("LGR CO", lgr_co) - DisplayValue("LGR H2O", lgr_h2o) - DisplayValue("Pic. CO2", pic_co2) - DisplayValue("Pic. CH4", pic_ch4) - DisplayValue("Pic. H2O", pic_h2o) - DisplayValue("NDVI up 1", dec_ndvi_up1) - DisplayValue("NDVI up 2", dec_ndvi_up2) - DisplayValue("NDVI dn 1", dec_ndvi_dn1) - DisplayValue("NDVI dn 2", dec_ndvi_dn2) - DisplayValue("PRI up 1", dec_pri_up1) - DisplayValue("PRI up 2", dec_pri_up2) - DisplayValue("PRI dn 1", dec_pri_dn1) - DisplayValue("PRI dn 2", dec_pri_dn2) + DisplayValue("TCAV tmpr", tcav_T) EndSubMenu MenuItem("Debug table", debug_on) MenuPick(Disable,Enable) - MenuItem("Test email", test_email) - MenuPick(Cancel,Yes) - MenuItem("Test ScadaBR", test_scadabr) - MenuPick(Cancel,Yes) EndSubMenu EndMenu -'================================= EMAIL ===================================== -Include "CPU:email_Enc.cr3" 'contains non-public settings -Const CRLF = CHR(13) & CHR(10) -Dim smtp_response As String * 80 - -Sub send_startup_email() - Dim subject As String * 40, msg As String * 512 - subject = "Start-up notice from " & self & " CR3000" - msg = ("This is the " & self & " CR3000. Starting up..." & CRLF & CRLF) - 'HINT both CompileResults and CardStatus come with a trailing but - 'CardStatus has a CRLF pair in the middle which must be stripped out - msg &= "Compile results: " & RTrim(Status.CompileResults(1)) - msg &= "Card status: " & RTrim(Replace(Status.CardStatus(1), CRLF, " ")) - msg &= CRLF & "Program error count: " & Status.ProgErrors & CRLF - msg &= "Watchdog error count: " & Status.WatchdogErrors & CRLF - msg &= "Run signature: " & Status.RunSignature & CRLF - msg &= "Program signature: " & Status.ProgSignature & CRLF - msg &= "Power input (Volts): " & Status.Battery & CRLF - EmailSend(SMTP_SERV,EMAIL_TO,EMAIL_FROM,subject,msg,"",SMTP_USER,SMTP_PASS,smtp_response) -EndSub - -Sub send_test_email() - Dim subject As String * 40, msg As String * 512 - subject = "Test email from " & self & " CR3000" - msg = "This is the " & self & " CR3000. Testing 1.. 2.. 3.." & CRLF - EmailSend(SMTP_SERV,EMAIL_TO,EMAIL_FROM,subject,msg,"",SMTP_USER,SMTP_PASS,smtp_response) -EndSub - -Sub send_daily_email() - Dim subject As String * 40, msg As String * 512 - subject = "Daily notice from " & self & " CR3000" - - GetRecord(out_daily(1),site_daily,1) - msg = "Good morning. Yesterday the temperature ranged from " - msg &= FormatFloat(min_tmpr, "%3g") & " to " - msg &= FormatFloat(max_tmpr, "%3g") & " degC. Power input varied from " - msg &= FormatFloat(min_battery, "%3g") & " to " - msg &= FormatFloat(max_battery, "%3g") & " volts." & CRLF - EmailSend(SMTP_SERV,EMAIL_TO,EMAIL_FROM,subject,msg,"",SMTP_USER,SMTP_PASS,smtp_response) -EndSub - - -'============================= SCADABR INTEGRATION ================================== -Include("CPU:scadabr_Enc.cr3") -Dim scadabr_socket As Long -Dim rtime(9) As Long -Dim scadabr_success As Boolean -Dim scadabr_resp As String * 256 - -Sub send_scadabr_data(payload As String * 512) - Dim uri As String * 512 - Dim tstamp As String * 18 - RealTime(rtime) - Sprintf(tstamp,"%04u%02u%02u%02u%02u%02u", rtime(1),rtime(2),rtime(3),rtime(4),rtime(5),rtime(6)) - uri = REPORT_URL & tstamp & payload - scadabr_socket = HTTPGet(uri, scadabr_resp, "") - scadabr_success = NOT (scadabr_socket OR Len(scadabr_resp)) -EndSub - -Sub send_test_ScadaBR() - send_scadabr_data("&testing=0") - test_scadabr = False -EndSub - -Sub send_5min_report() - Dim msg As String * 512 - msg = "&skipped_10hz_scans=" & skipped_10hz_scans - msg &= "&skipped_1hz_scans=" & skipped_1hz_scans - msg &= "&skipped_5s_scans=" & skipped_5s_scans - msg &= "&watchdog_errors=" & watchdog_errors - send_scadabr_data(msg) -EndSub - -Sub send_startup_report() - Dim msg As String * 512 - 'HINT both CompileResults and CardStatus come with a trailing but - 'CardStatus has a CRLF pair in the middle which must be stripped out -' msg &= "&compileresults=" & RTrim(Replace(Status.CompileResults(1), CRLF, " ")) -' msg &= "cardstatus=" & RTrim(Replace(Status.CardStatus(1), CRLF, " ")) - msg &= "&progerrors=" & Status.ProgErrors - msg &= "&watchdogerrors=" & Status.WatchdogErrors - msg &= "&runsignature=" & Status.RunSignature - msg &= "&progsignature=" & Status.ProgSignature - msg &= "&battery=" & Status.Battery - send_scadabr_data(msg) -EndSub - - -'=============================== FUNCTIONS ============================================ -Function Topp_equation( dielectric ) - Return 4.3e-6*dielectric^3 - 5.5e-4*dielectric^2 + 2.92e-2*dielectric - 5.3e-2 -EndFunction - - '=============================== SUBROUTINES ========================================== Sub set_default_choices() set_sonic_azimuth = NAN set_NRLite2_sens = 0 - set_LI190_mult = -0.200 'mnfctr standard for -SMV sensors + set_LI190SB_sens = 0 set_cup_ws_enabled = False set_vane_wd_enabled = False set_rain_enabled = False - set_soil_5_enabled = True - set_soil_6_enabled = True - set_soil_7_enabled = True - set_soil_8_enabled = True - set_soil_9_enabled = True - set_soil_A_enabled = True - set_soil_B_enabled = True - set_soil_C_enabled = True - set_soil_5_depth = 0 - set_soil_6_depth = 0 - set_soil_7_depth = 0 - set_soil_8_depth = 0 - set_soil_9_depth = 0 - set_soil_A_depth = 0 - set_soil_B_depth = 0 - set_soil_C_depth = 0 set_hfp1_sens = 0 set_hfp2_sens = 0 - set_lgr_n2o_mult = 1.0 - set_lgr_n2o_offset = 0 - set_lgr_co_mult = 1.0 - set_lgr_co_offset = 0 - set_lgr_h2o_mult = 1.0 - set_lgr_h2o_offset = 0 - set_pic_co2_mult = 1.0 - set_pic_co2_offset = 0 - set_pic_ch4_mult = 1.0 - set_pic_ch4_offset = 0 - set_pic_h2o_mult = 1.0 - set_pic_h2o_offset = 0 EndSub Sub populate_choices() @@ -1350,19 +753,10 @@ Sub save_current_choices() 'update dependent variables nrlite_mult = 1000/NRLite2_sens - li190_dens_mult = 1000*LI190_mult - li190_tot_mult = LI190_mult*(SLOW_INTV/1) - LI190R_mult = LI190_mult 'XXXX - LI190SB_sens = NAN 'HACK - If (NOT soil_5_enabled) Then Move(fiveTM(1),3,NAN,1) - If (NOT soil_6_enabled) Then Move(fiveTM(4),3,NAN,1) - If (NOT soil_7_enabled) Then Move(fiveTM(7),3,NAN,1) - If (NOT soil_8_enabled) Then Move(fiveTM(10),3,NAN,1) - If (NOT soil_9_enabled) Then Move(fiveTM(13),3,NAN,1) - If (NOT soil_A_enabled) Then Move(fiveTM(16),3,NAN,1) - If (NOT soil_B_enabled) Then Move(fiveTM(19),3,NAN,1) - If (NOT soil_C_enabled) Then Move(fiveTM(22),3,NAN,1) + li190_dens_mult = 1000/(LI190SB_sens*0.604) + li190_tot_mult = (1/(LI190SB_sens*0.604))*(SLOW_INTV/1) + sensor_shfp = SHFP_ENABLED #If (SHFP_ENABLED) Then soil_hfp1_sensitivity = 1000/hfp1_sens soil_hfp2_sensitivity = 1000/hfp2_sens @@ -1372,12 +766,6 @@ Sub save_current_choices() soil_hfp2_heat_flux = NAN soil_hfp2_sensitivity = 0 #EndIf - #If (LGR_N2O_ENABLED) Then - Move(lgrn2oco(1),3,NAN,1) - #EndIf - #If (PIC_CH4_ENABLED) Then - Move(picco2ch4(1),3,NAN,1) - #EndIf EndSub Sub setup() @@ -1392,13 +780,7 @@ Sub setup() save_current_choices() CallTable (site_info) - #If (LGR_N2O_ENABLED OR PIC_CH4_ENABLED OR NDVIPRI_ENABLED) Then - CallTable(extra_info) - #EndIf - Move(lgrn2oco(1),3,NAN,1) - Move(picco2ch4(1),3,NAN,1) - Move(fiveTM(1),24,NAN,1) SDMSpeed (SDM_PER) self = Status.StationName EndSub @@ -1407,8 +789,6 @@ EndSub '================================ PROGRAM ============================================= BeginProg setup() - send_startup_email() - send_startup_report() Scan (FAST_INTV,mSec,FAST_BUFFER_SIZE,0) @@ -1427,11 +807,11 @@ BeginProg EndIf '== TE525 rain gage acquisition - PulseCount(Rain_mm,1,TE525_PULSE,2,0,TE525_MULT,TE525_OFFSET) + PulseCount(Rain_mm,1,TE525_PULSE,2,0,TE525_MULT,0) If (NOT rain_enabled) Then Rain_mm = NAN '== EC100/EC150/CSAT3A irga/sonic acquisition - EC100 (sonic_irga_raw(1),EC100_SDM_ADDR,1) + EC100 (sonic_irga_raw(1),EC100_SDM_ADDR,2) CallTable(work_delay_ec100) CallTable(tsdata) @@ -1439,28 +819,12 @@ BeginProg hor_wind_raw = SQR (sonic_irga_raw(1)*sonic_irga_raw(1)+sonic_irga_raw(2)*sonic_irga_raw(2)) AvgRun (hor_wind,1,hor_wind_raw,NMBR_WND_SAMPLES) '3-sec running mean of horiz. WS - '== optional LGR N2O/CO acquisition - #If (LGR_N2O_ENABLED) Then - VoltDiff(lgr_n2o,1,mv5000,LGR_N2O_DIFF,TRUE,0,INTEG,lgr_n2o_mult,lgr_n2o_offset) - VoltDiff(lgr_co,1,mv5000,LGR_CO_DIFF,TRUE,0,INTEG,lgr_co_mult,lgr_co_offset) - VoltDiff(lgr_h2o,1,mv5000,LGR_H2O_DIFF,TRUE,0,INTEG,lgr_h2o_mult,lgr_h2o_offset) - #EndIf - '== optional Picarro CO2/CH4 acquisition - #If (PIC_CH4_ENABLED) Then - VoltDiff(pic_co2,1,mv5000,PIC_CO2_DIFF,TRUE,0,INTEG,pic_co2_mult,pic_co2_offset) - VoltDiff(pic_ch4,1,mv5000,PIC_CH4_DIFF,TRUE,0,INTEG,pic_ch4_mult,pic_ch4_offset) - VoltDiff(pic_h2o,1,mv5000,PIC_H2O_DIFF,TRUE,0,INTEG,pic_h2o_mult,pic_h2o_offset) - #EndIf - #If (LGR_N2O_ENABLED OR PIC_CH4_ENABLED) Then - CallTable(tsdata_extra) - #EndIf - If ( scan_count >= OFFSET ) Then 'IF HAVE ENUF SCANS TO DO STATS, '== EC100/EC150/CSAT3A lagged data retrieval GetRecord (dly_data_out(1),work_delay_ec100,EC150_REC_BCK) Move (Ux,5,dly_data_out(1),5) 'Ux, Uy, Uz, Ts, diag_sonic - Move (CO2,7,dly_data_out(6),7) '+H2O,diag_irga,amb_tmpr,amb_press,CO2_signal,H2O_signal + Move (CO2,7,dly_data_out(6),8) '+H2O,diag_irga,amb_tmpr,amb_press,CO2_signal,H2O_signal,CO2_hf If ( (diag_sonic <> NAN) AND (diag_sonic <> -1) ) Then sonic_disable_f = diag_sonic AND &h3f '= 0011 1111 Else @@ -1471,18 +835,20 @@ BeginProg If ( (diag_irga <> NAN) AND (diag_irga <> -1) ) Then irga_disable_f = sonic_disable_f OR (diag_irga AND &h1) 'bit 0 always HI for warning Else - Move(CO2,7,NAN,1) + Move(CO2,8,NAN,1) irga_disable_f = TRUE EndIf If ( NOT irga_disable_f ) Then Tc = Ts_absolute/(1+0.32*H2O*R*Ts_absolute/(amb_press*18)) - 273.15'Kaimal and Gaynor (1991) Eq. (3). - divisor = (amb_press/(R*(Tc+273.15)))-(H2O/18) 'mixing ratio (X/dry air) - CO2_ppm=CO2/(0.044*divisor) - Xv=H2O/(0.018*divisor) + divisor = (amb_press/(R*(Tc+273.15)))-(H2O/18) '[divisor] = mol/m^3 + CO2_ppm = CO2/(MW_CO2/1000)/divisor + CO2_hf_ppm = CO2_hf/(MW_CO2/1000)/divisor + Xv = H2O/(MW_H2O/1000)/divisor Else - Tc=NAN - CO2_ppm=NAN - Xv=NAN + Tc = NAN + CO2_ppm = NAN + CO2_hf_ppm = NAN + Xv = NAN EndIf 'sonic cov for stats 1 @@ -1493,58 +859,13 @@ BeginProg cov_array_cs(1,1) = CO2 cov_array_cs(2,1) = H2O cov_array_cs(3,1) = Tc + cov_array_cs(4,1) = CO2_hf Move (cov_array_cs(1,2),3,Ux,3) Move (cov_array_cs(2,2),3,Ux,3) Move (cov_array_cs(3,2),3,Ux,3) - - '+++++ 5 minute statistics ++++++ - - CallTable (work_5min) - If ( work_5min.Output(1,1) ) Then - GetRecord(work_stats_out(1),work_5min,1) - - sonic_uptime = sonic_samples/samples_possible - irga_uptime = irga_samples/samples_possible - - 'add azimuth to calculated wind dir - rslt_wnd_dir = (360 + rslt_wnd_dir + sonic_azimuth) MOD 360 - tau = SQR ((Ux_Uz_cov*Ux_Uz_cov)+(Uy_Uz_cov*Uy_Uz_cov)) - u_star = SQR (tau) - Ts_Std = SQR (Ts_Std) - Ux_Std = SQR (Ux_Std) - Uy_Std = SQR (Uy_Std) - Uz_Std = SQR (Uz_Std) - - L=-u_star^3*(Tc_Avg+273.15)/(0.4*9.8*Ts_Uz_cov) 'obukohov length - rho_d_mean = (amb_press_Avg/((Tc_Avg+273.15)*RD))-(H2O_g_m3_Avg*MU_WPL) - rho_a_mean = (rho_d_mean+H2O_g_m3_Avg)/1000 - Fc_irga = CO2_Uz_cov 'online fluxes - LE_irga = LV*H2O_Uz_cov - CO2_mg_m3_Std = SQR (CO2_mg_m3_Std) 'stdevs - H2O_g_m3_Std = SQR (H2O_g_m3_Std) - Tc_stdev = SQR (Tc_stdev) - sigma_wpl = H2O_g_m3_Avg/rho_d_mean 'WPL term - - 'EC150 Webb et al. (1980) term for carbon dioxide Eq. (24). - CO2_wpl_LE = MU_WPL*CO2_mg_m3_Avg/rho_d_mean*H2O_Uz_cov - CO2_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov - Fc_wpl = Fc_irga+CO2_wpl_LE+CO2_wpl_H - - 'EC150 Webb et al. (1980) term for water vapor Eq. (25). - H2O_wpl_LE = MU_WPL*sigma_wpl*LE_irga - H2O_wpl_H = (1+(MU_WPL*sigma_wpl))*H2O_g_m3_Avg/(Tc_Avg+273.15)*LV*Tc_Uz_cov - LE_wpl = LE_irga+H2O_wpl_LE+H2O_wpl_H - - RH_hmp_Avg = 100*e_hmp_Avg/e_sat_hmp_Avg - - Hs = rho_a_mean*CP*Ts_Uz_cov - tau = rho_a_mean*tau - Hc = rho_a_mean*CP*Tc_Uz_cov - EndIf - CallTable(stats5) + Move(cov_array_cs(4,2),3,Ux,3) '+++++ 30 min statistics +++++ - CallTable (work_30min) If ( work_30min.Output(1,1) ) Then GetRecord(work_stats_out(1),work_30min,1) @@ -1581,6 +902,13 @@ BeginProg H2O_wpl_H = (1+(MU_WPL*sigma_wpl))*H2O_g_m3_Avg/(Tc_Avg+273.15)*LV*Tc_Uz_cov LE_wpl = LE_irga+H2O_wpl_LE+H2O_wpl_H + 'repeat using high-frequency tmpr CO2 value + Fc_hf_irga = CO2_hf_Uz_cov + CO2_hf_mg_m3_Std = SQR(CO2_hf_mg_m3_Std) + CO2_hf_wpl_LE = MU_WPL*CO2_hf_mg_m3_Avg/rho_d_mean*H2O_Uz_cov + CO2_hf_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_hf_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov + Fc_hf_wpl = Fc_hf_irga+CO2_hf_wpl_LE+CO2_hf_wpl_H + RH_hmp_Avg = 100*e_hmp_Avg/e_sat_hmp_Avg Hs = rho_a_mean*CP*Ts_Uz_cov @@ -1619,7 +947,7 @@ BeginProg SatVP (e_sat_hmp,T_hmp) '== NR-Lite2 net radiometer, expected range 0-15mV - VoltDiff (Rn_meas,1,mV20,NRLITE_DIFF,TRUE,0,INTEG,nrlite_mult,NRLITE_OFFSET) + VoltDiff (Rn_meas,1,mV20,NRLITE_DIFF,TRUE,0,INTEG,nrlite_mult,0) If ( sonic_irga_raw(5)=0 AND hor_wind>5 ) Then 'sonic_irga_raw(5) = CSAT3 diag word Rn = Rn_meas*(1+(0.021286*(hor_wind-5))) Else @@ -1627,18 +955,14 @@ BeginProg EndIf '== LI190SB - VoltDiff (PAR_mV,1,mV20,LI190_DIFF,True,0,_60Hz,1,0) 'MULT/OFF applied below - PAR_flxdens = PAR_mV*li190_dens_mult - PAR_totflx = PAR_mV*li190_tot_mult - - #If (NDVIPRI_ENABLED) Then - SDI12Recorder(dec_ndvi_up1,SDI_COM_ADDR,DEC_NDVI_UP_SDI_ADDR,"M!",1.0,0) - SDI12Recorder(dec_ndvi_dn1,SDI_COM_ADDR,DEC_NDVI_DN_SDI_ADDR,"M!",1.0,0) - SDI12Recorder(dec_pri_up1,SDI_COM_ADDR,DEC_PRI_UP_SDI_ADDR,"M!",1.0,0) - SDI12Recorder(dec_pri_dn1,SDI_COM_ADDR,DEC_PRI_DN_SDI_ADDR,"M!",1.0,0) - CallTable(stats5_ui) - CallTable(stats30_ui) - #EndIf + VoltDiff (PAR_mV,1,mV20,LI190_DIFF,True,0,INTEG,1,0) 'MULT/OFF applied below + If (PAR_mV > 0) Then + PAR_flxdens = PAR_mV*li190_dens_mult + PAR_totflx = PAR_mV*li190_tot_mult + Else + PAR_flxdens = NAN + PAR_totflx = NAN + EndIf If (debug_on) Then CallTable debug @@ -1646,38 +970,11 @@ BeginProg save_changes = False 'reset b4 we forget save_current_choices() CallTable(site_info) - #If (LGR_N2O_ENABLED OR PIC_CH4_ENABLED OR NDVIPRI_ENABLED) Then - CallTable(extra_info) - #EndIf EndIf just_had_1hz_scan = TRUE NextScan - '========================== REPORTING THREAD =============================== - SlowSequence - Scan (1,Sec,2,0) - 'HINT: this is the only scan email events should be sent from! - If (test_email) Then - test_email = False - send_test_email() - EndIf - If (test_scadabr) Then - send_test_ScadaBR() - EndIf - If TimeIntoInterval(6,24,hr) Then - send_daily_email() - EndIf - - If TimeIntoInterval(0,5,Min) Then - skipped_10hz_scans = Status.SkippedScan(1,1) - skipped_1hz_scans = Status.SkippedSlowScan(1,1) - skipped_5s_scans = Status.SkippedSlowScan(3,1) - watchdog_errors = Status.WatchdogErrors(1,1) - send_5min_report() - EndIf - - NextScan '====================== SOIL SCAN INTERVAL ================================= SlowSequence @@ -1687,95 +984,12 @@ BeginProg GPS (latitude_a,GPS_COM_ADDR,UTC_OFFSET*3600,0,nmea_sentence(1)) CallTable(site_daily) - '== Decagon soil moisture probes - If (soil_5_enabled) Then - SDI12Recorder(soil_5TM_ID5_E,SDI_COM_ADDR,DEC_5TM_ID5_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_ID5_E < 1 OR soil_5TM_ID5_E > 80) Then - soil_5TM_ID5_E = NAN - soil_5TM_ID5_VWC = NAN - Else - soil_5TM_ID5_VWC = Topp_equation(soil_5TM_ID5_E) - EndIf - If (soil_5TM_ID5_T < -40 OR soil_5TM_ID5_T > 50) Then soil_5TM_ID5_T = NAN - EndIf - If (soil_6_enabled) Then - SDI12Recorder(soil_5TM_ID6_E,SDI_COM_ADDR,DEC_5TM_ID6_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_ID6_E < 1 OR soil_5TM_ID6_E > 80) Then - soil_5TM_ID6_E = NAN - soil_5TM_ID6_VWC = NAN - Else - soil_5TM_ID6_VWC = Topp_equation(soil_5TM_ID6_E) - EndIf - If (soil_5TM_ID6_T < -40 OR soil_5TM_ID6_T > 50) Then soil_5TM_ID6_T = NAN - EndIf - If (soil_7_enabled) Then - SDI12Recorder(soil_5TM_ID7_E,SDI_COM_ADDR,DEC_5TM_ID7_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_ID7_E < 1 OR soil_5TM_ID7_E > 80) Then - soil_5TM_ID7_E = NAN - soil_5TM_ID7_VWC = NAN - Else - soil_5TM_ID7_VWC = Topp_equation(soil_5TM_ID7_E) - EndIf - If (soil_5TM_ID7_T < -40 OR soil_5TM_ID7_T > 50) Then soil_5TM_ID7_T = NAN - EndIf - If (soil_8_enabled) Then - SDI12Recorder(soil_5TM_ID8_E,SDI_COM_ADDR,DEC_5TM_ID8_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_ID8_E < 1 OR soil_5TM_ID8_E > 80) Then - soil_5TM_ID8_E = NAN - soil_5TM_ID8_VWC = NAN - Else - soil_5TM_ID8_VWC = Topp_equation(soil_5TM_ID8_E) - EndIf - If (soil_5TM_ID8_T < -40 OR soil_5TM_ID8_T > 50) Then soil_5TM_ID8_T = NAN - EndIf - If (soil_9_enabled) Then - SDI12Recorder(soil_5TM_ID9_E,SDI_COM_ADDR,DEC_5TM_ID9_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_ID9_E < 1 OR soil_5TM_ID8_E > 80) Then - soil_5TM_ID9_E = NAN - soil_5TM_ID9_VWC = NAN - Else - soil_5TM_ID9_VWC = Topp_equation(soil_5TM_ID9_E) - EndIf - If (soil_5TM_ID9_T < -40 OR soil_5TM_ID9_T > 50) Then soil_5TM_ID9_T = NAN - EndIf - If (soil_A_enabled) Then - SDI12Recorder(soil_5TM_IDA_E,SDI_COM_ADDR,DEC_5TM_IDA_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_IDA_E < 1 OR soil_5TM_IDA_E > 80) Then - soil_5TM_IDA_E = NAN - soil_5TM_IDA_VWC = NAN - Else - soil_5TM_IDA_VWC = Topp_equation(soil_5TM_IDA_E) - EndIf - If (soil_5TM_IDA_T < -40 OR soil_5TM_IDA_T > 50) Then soil_5TM_IDA_T = NAN - EndIf - If (soil_B_enabled) Then - SDI12Recorder(soil_5TM_IDB_E,SDI_COM_ADDR,DEC_5TM_IDB_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_IDB_E < 1 OR soil_5TM_IDB_E > 80) Then - soil_5TM_IDB_E = NAN - soil_5TM_IDB_VWC = NAN - Else - soil_5TM_IDB_VWC = Topp_equation(soil_5TM_IDB_E) - EndIf - If (soil_5TM_IDB_T < -40 OR soil_5TM_IDB_T > 50) Then soil_5TM_IDB_T = NAN - EndIf - If (soil_C_enabled) Then - SDI12Recorder(soil_5TM_IDC_E,SDI_COM_ADDR,DEC_5TM_IDC_SDI_ADDR,"M!",1.0,0) - If (soil_5TM_IDC_E < 1 OR soil_5TM_IDC_E > 80) Then - soil_5TM_IDC_E = NAN - soil_5TM_IDC_VWC = NAN - Else - soil_5TM_IDC_VWC = Topp_equation(soil_5TM_IDC_E) - EndIf - If (soil_5TM_IDC_T < -40 OR soil_5TM_IDC_T > 50) Then soil_5TM_IDC_T = NAN - EndIf - #If (SHFP_ENABLED) Then VoltDiff(soil_hfp1_heat_flux,1,mv200,HFP_1_SGNL_DIFF,TRUE,0,INTEG, _ soil_hfp1_sensitivity,0) VoltDiff(soil_hfp2_heat_flux,1,mv200,HFP_2_SGNL_DIFF,TRUE,0,INTEG, _ soil_hfp2_sensitivity,0) - Therm109(soil_109SS_1_T,1,27,VX3,0,250,1,0) - Therm109(soil_109SS_2_T,1,28,VX4,0,250,1,0) + TCDiff(tcav_T,1,mV50,TCAV_DIFF,TypeE,panel_tmpr,1,0,INTEG,0,1) #EndIf CallTable(soil) diff --git a/src/email-template.cr3 b/src/email-template.cr3 deleted file mode 100644 index 9a7b97d..0000000 --- a/src/email-template.cr3 +++ /dev/null @@ -1,27 +0,0 @@ -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -' Vineyard Pilot Study (2015) -' -' Email settings file -' -' Laboratory for Atmospheric Research -' Department of Civil & Environmental Engineering -' Washington State University -' -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - -' THIS FILE IS A TEMPLATE -' -' File contains dummy values! Update as necessary and save as `email.cr3` -' -' Before compiling `default.cr3`, open `email.cr3` in CRBasic Editor, go -' File > Save and Encrypt... and save with default name `email_Enc.cr3` -' -' Before sending to datalogger, copy `email_Enc.cr3` to its CPU: drive -' - -Const SMTP_SERV = "192.168.1.1:25" 'SMTP server optionally with port# -Const SMTP_USER = "cr3000@example.com" 'SMTP account name -Const SMTP_PASS = "the_email_password" 'SMTP account password -Const EMAIL_TO = "user@example.com" 'message recipient -Const EMAIL_FROM = SMTP_USER 'message sender - diff --git a/src/readme.md b/src/readme.md index 215d989..4fc42c7 100644 --- a/src/readme.md +++ b/src/readme.md @@ -1,12 +1,5 @@ *Datalogger Program Source Code* -Sensors are wired to a CR3000 as specified in `../doc/wiring_details.ods` -([PDF version][1]). - - [1]: https://bitbucket.org/wsular/2015-vineyard-tower-logger/downloads/wiring_details.pdf - -1. Edit values in `email-template.cr3` and save as `email.cr3` then save and - encrypt to `email_Enc.cr3`. Load `email_Enc.cr3` onto the CR3000's `CPU:` - drive. -2. Repeat pattern in step 1 for `scadabr-template.cr3`. -3. Load `default.cr3` onto the CR3000's `CPU:` drive. +1. Push `default.cr3` to logger +2.   +3. Profits diff --git a/src/scadabr-template.cr3 b/src/scadabr-template.cr3 deleted file mode 100644 index a971f53..0000000 --- a/src/scadabr-template.cr3 +++ /dev/null @@ -1,34 +0,0 @@ -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -' Vineyard Pilot Study (2015) -' -' ScadaBR integration settings file -' -' Laboratory for Atmospheric Research -' Department of Civil & Environmental Engineering -' Washington State University -' -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' - -' THIS FILE IS A TEMPLATE -' -' File contains dummy values! Update as necessary and save as `scadabr.cr3` -' -' Before compiling `default.cr3`, open `scadabr.cr3` in CRBasic Editor, go -' File > Save and Encrypt... and save with default name `scadabr_Enc.cr3` -' -' Before sending to datalogger, copy `scadabr_Enc.cr3` to its CPU: drive -' - -' URI to ScadaBR HTTP receiver; just the document, no query punctuation -Const _SERVER_URL = "http://yourserver.tld:8080/ScadaBR/httpds" - -' Set to "Device name" used by HTTP Receiver -Const _DEVICE_KEY = "device-name" - -'Base URI is the same except for timestamp -#If (Len(_DEVICE_KEY)) Then - Const REPORT_URL = (_SERVER_URL & "?__device=" & _DEVICE_KEY & "&__time=") -#Else - Const REPORT_URL = (_SERVER_URL & "&__time=") -#EndIf - From 2916b8f3ede821c7563c7b12f58de842ad5d6ddb Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 15:04:35 -0700 Subject: [PATCH 02/20] Adopt EasyFlux v1.0 as core engine --- CHANGELOG.md | 8 + src/default.cr3 | 6147 ++++++++++++++++++++++++++++++++++++------- src/old_default.cr3 | 998 +++++++ 3 files changed, 6209 insertions(+), 944 deletions(-) create mode 100644 src/old_default.cr3 diff --git a/CHANGELOG.md b/CHANGELOG.md index d2ca895..93a6ae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,17 @@ Next release > This release requires operating system `CR3000.Std.31` or newer. +

+ > Previous telemetry integrations (email, ScadaBR) have been removed in this > version. +

+ +> The data processing core is now built upon [EasyFlux-DL by Campbell +> Scientific](www.campbellsci.com/easyflux-dl). This represents a substantial +> improvement in near real-time evaluation of carbon and energy fluxes. + ### Data Table Changes * Remove 5-min flux/met and soil data tables diff --git a/src/default.cr3 b/src/default.cr3 index f8bf2e0..14d6464 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -1,998 +1,5257 @@ -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -' Vineyard Pilot Study (2015) -' Laboratory for Atmospheric Research at Washington State University -' https://bitbucket.org/wsular/2015-vineyard-tower-logger -' -'========================== SEMI-EDITABLE VALUES ====================================== - -'manually update prior to pushing but do not check-in with other than empty string! -Const GIT_TAG = "" - -'----- TIMEZONE ----- -'This must be set as a constant for use with GPS instruction. It cannot be dynamically -'assigned based on logger's serial # because of this fact. -Const UTC_OFFSET = -8 'offset from UTC as +/- hours; PST = -8 - -'----- PROGRAM TIMING ----- -Const FAST_INTV = 100 'length of primary scan interval, milliseconds -Const SLOW_INTV = 1 'length of secondary scan interval, seconds -Const SOIL_INTV = 30 'length of slowest sensors (soil probes, gps, shfp) -Const STAT_OUT_30 = 30 'stats output interval minutes -Const SDM_PER = 30 'default SDM clock speed -Const INTEG = 250 'analog measurement integration time (250/_50hz/_60hz) - -'----- PROGRAM OPERATION ----- -Const SETTINGS_FILE = "CPU:wine_settings.dat" -Const FAST_BUFFER_SIZE = 600 '= 60sec = 1min buffer -Const SLOW_BUFFER_SIZE = 60 '= 1min buffer -Const SOIL_BUFFER_SIZE = 24 '= 2min buffer -Const DAILY_MEDNUM = 480 '# of values to include in median for daily stats -Const NMBR_WND_SAMPLES = 3000/FAST_INTV '#pts to compute 3sec mean horizontal wind - -'----- BASE SENSORS ANALOG INPUT MAP ------ -Const HMP_T_DIFF = 2 'HMP T diff input chan # -Const HMP_RH_DIFF = 3 'HMP RH diff input chan # -Const NRLITE_DIFF = 4 'NR-Lite2 diff input chan # -Const LI190_DIFF = 5 'LI190SB diff input chan # - -Const oh34B_WD_SE = 1 '034B single ended input chan # = D1H -Const oh34B_WD_VX = 1 '034B voltage excitation chan # -Const oh34B_WS_PULSE = 1 '034B pulse input chan # -Const TE525_PULSE = 2 'TE525 rain gage pulse input chan # - -'----- BASE SENSORS DIGITAL INPUT MAP ----- -Const EC100_SDM_ADDR = 1 'SDM address for EC100/EC150/CSAT3A -Const GPS_COM_ADDR = Com4 'GPS serial input port # -Const SDI_COM_ADDR = 5 'serial port reserved for SDI communications = Com3 - -'------ OPTIONAL SENSORS ANALOG INPUT MAP ----- -Const HFP_1_SGNL_DIFF = 6 'heat flux plate sensor signal diff input chan # -Const HFP_2_SGNL_DIFF = 7 ' plate #2 - -Const TCAV_DIFF = 8 'averaging thermcouple diff input chan # - - -ConstTable - Const SHFP_ENABLED = True -EndConstTable - -'----- FIXED CALIBRATION VALUES ------ -Const HMP_T_MULT = (60 - -80)/1000 '-80 to +60 *C over 1V = 0.14 -Const HMP_T_OFFSET = -80 -Const HMP_RH_MULT = (100 - 0)/1000 '0 - 100% over 1V -Const HMP_RH_OFFSET = 0 -Const oh34B_WD_MULT = 720 '720/0 as specified in CSI manual: -Const oh34B_WD_OFFSET = 0 ' Met One 034B Windset rev3/12, pg 6 -Const oh34B_WS_MULT = 0.7989 '0.7989/0.28 as specified in above CSI manual -Const oh34B_WS_OFFSET = 0.28 -Const TE525_MULT = 0.254 'Table 7-2, CSI manual rev 8/16 - - -'========================== NO USER-SERVICEABLE PARTS BELOW =========================== -'----- PHYSICAL CONSTANTS ----- -Const MW_CO2 = 44.01 'molecular weight of CO2, g/mol -Const MW_H2O = 18.016 'molecular weight of water, g/mol -Const MW_AIR = 28.964 'molecular weight of dry air, g/mol -Const MU_WPL = MW_AIR/MW_H2O 'Ratio of the molecular weight of dry air to water vapor -Const R = .0083143 'Universal gas constant [kPa m^3/(K mol)] -Const RD = R/29 'Gas constant for dry air [kPa m^3/(K g)] -Const LV = 2440 'Estimate of the latent heat of vaporization [J/g] -Const RV = R/18 'Gas constant for water vapor [kPa m^3/(K g)] -Const CP = 1004.67 'Estimate of heat capacity of air [J/(kg K)] - - -'----- PROGRAM OPERATION VARIABLES ----- -Public debug_on As Boolean -Dim self As String * 16 -Dim filehandle As Long -Dim scan_count As Long 'Number scans executed. -Dim just_had_1hz_scan As Boolean 'Flag used to indicate the SlowSequence has finished its scan. -Dim inbetween_1hz_scan As Boolean = {TRUE} 'Flag used to decimate statistics in main scan. -Dim just_had_soil_scan As Boolean -Dim inbetween_5s_scan As Boolean = {TRUE} -Dim i As Long 'Main scan index variable. -Dim ii As Long 'Slow sequence scan index variable. -Dim n = {1} +'Online Corrections Flux Program version 1.x + +'Copyright (c) 2017 Washington State University. Adapted with permission. +'Copyright (c), 2014, 2015 Campbell Scientific, Inc. All rights reserved. +'This program is intended for use with Campbell Scientific open-path eddy-covariance systems manufactured after Fall 2010 that use an EC150 with CSAT3A or an IRGASON. +'The most common or “best practice” corrections are applied to fluxes in this program. Consult the manual for details on these corrections. It is the responsibility +'of the user to determine appropriateness of the corrections used. Campbell Scientific always recommends saving raw time series data +'in case reprocessing of raw data is warranted. Furthermore, it is the responsibility of the user and associated researchers to determine the quality and fitness of +'any and all data for a publication, regardless of whether said data were processed by this program or another tool. + +'Versions numbers less than 1.00 of this program are not fully tested or officially released. Campbell Scientific is not responsible for any errors in data collected +'using program versions prior to 1.00. + +'Abbreviations in comments and variables +'CR3K CR3000 +'CSAT CSAT3A or sonic anemometer in IRGASON +'sonic CSAT3A or sonic anemometer in IRGASON +'CS6XX CS616, CS650, or CS655 +'CS65X CS650 or CS655 +'cumul cumulative +'dia diameter +'diag dignosis +'dir direction +'dist distance +'flg flag +'FP footprint +'Freq frequency +'FW FW05, FW1, or FW3. FW is an abbreviation for fine wire thermocouple +'intrst interest +'IRGA EC150 or IRGASON InfraRed Gas Analyzer +'nmbr number +'pct percent +'Pyran pyranometer +'RH relative humidity +'rng range +'QC quality control or quality classification +'shf soil heat flux +'shfp soil heat flux plate +'sig signal +'strgth strength +'within win +'wnd wind +'wtr water +'hfp01xx HFP01 or HFP01SC soil heat flux plate sensor + +'*** SIGN CONVENTION +' Positive fluxes away from the ground surface and negative towards the ground surface. + +'*** SITE AND CALIBRATION CONSTANTS +' Search for the text string "Unique" in this code to find the lines below in this program where unique site constants and sensor calibration values are entered. + +'*** LAGS +' Instrument scan lag: Before computing online fluxes and writing to the time series data table, an instrument scan lag for each variable is introduced +' to account for the fixed instrument delays so that any pair of variables for covariance are aligned at the time resolution of the scan rate. Scan lags +' depend on instrument settings and/or the datalogger scan interval. In the case of the IRGASON or EC150 with CSAT3A, the instrument delay is determined +' by the bandwidth setting in the EC100 electronics (see appendix A of IRGASON manual, Revision 6/14). For analog measurements such as FW sensors, +' the measurements are assumed to have no scan delay. After instrument scan lags are applied, the data are recorded in the time series output table. + +' Sensing time lag: After the instrument scan lag is applied, an additional lag called the sensing time lag is applied to account for covariance attenuation +' at high frequency due to spatial separation between the scalar sensor (e.g. FW or IRGA) and sonic anemometer. The sensing lag is positive if wind passed the sonic volume first +' followed by the scalar sensor; otherwise, the sensing lag is negative. Sensing time lags depend on the wind speed and sensor separation. An algorithm +' in the program selects a lag that maximizes covariances and is physically possible. The final outputs in the flux output table have sensing time lags applied. + +'*** Unit Definitions *** +'SYMBOL UNIT +'C Celsius +'degrees angle degrees +'frac_v_wtr Fraction volumetric water content +'g grams +'J Joules +'Hz Hertz +'kg kilograms +'kPa kilopascals +'m meters +'mg milligrams +'mmol millimole +'mol mole +'ms millisecond +'s seconds +'umol micromoles +'usecond microsecond +'V volts +'W Watts + +PipeLineMode +AngleDegrees 'Angles are in degrees throughout the program + +'*** SENSORS **** +Const SENSOR_IRGASON = TRUE 'Unique: IRGASON, if TRUE, SENSOR_CSAT3AEC150 must be set to FALSE +Const SENSOR_CSAT3AEC150 = FALSE 'Unique: CSAT3A + EC150, if TRUE, SENSOR_IRGASON must be set to FALSE. +Const SENSOR_FW = FALSE 'Unique: FW05, FW1, FW3, or other fine wire thermocouple +Const SENSOR_TMPR_RH = FALSE 'Unique: HC2S3 or HMP155A: temperature and relative humidity probe +Const SENSOR_NR_LITE = FALSE 'Unique: NR Lite2: net radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_CS300 = FALSE 'Unique: CS300: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_LI200X = FALSE 'Unique: LI200X: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_LI190SB = FALSE 'Unique: LI190SB: Quantum, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_SI111 = FALSE 'Unique: SI111: Infrared radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_NR01 = FALSE 'Unique: NR01: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_CNR4 must be set to FALSE +Const SENSOR_CNR4 = FALSE 'Unique: CNR4: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_NR01 must be set to FALSE +Const SENSOR_TE525mm = FALSE 'Unique: TE525mm rain gauge +Const SENSOR_TCAV = FALSE 'Unique: TCAV: type E thermocouple averaging soil temperature probes +Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X must be set to FALSE +Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 must be set to FALSE +Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE +Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE + +'Composite boolean variables for variables above +Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) +Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) +Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X)) + +'***** Wiring Instruction ****** +'*** Beginning of EC100 (IRGASON or EC150 w/ or w/o CSAT3A sonic head) wiring *** +'SDM-C1 SDM Data (green) +'SDM-C2 SDM Clock (white) +'SDM-C3 SDM Enable (brown) +'G SDM reference (black) +' SDM shield (clear) + +'+12V power (red) +'G power reference (black) +' power shield (clear) +'*** End of EC100 (IRGASON or EC150 w/ or w/o CSAT3A sonic head) wiring *** + +#If (SENSOR_HFP) Then +'Soil heat flux plates +Const SHF_ANALOG_INPUT = 1 'Starting differential analog input channel. +Const NMBR_SHFP = 4 'Unique: number of HFP01 or HFP01SC sensors to measure (Maximum is 4) . + +Data 1000/62 'Unique: multiplier for HFP01xx #1 (1000/sensitivity). +#If (NMBR_SHFP >1) Then 'This conditional statement can avoid the confliction with Data statements for the numerical wTs transfer function from Dijk (2002)) if NMBR_SHFP < 2 + +Data 1000/62 'Unique: multiplier for HFP01xx #2 (1000/sensitivity). +#EndIf +#If (NMBR_SHFP >2) Then 'This conditional statement can avoid the confliction with Data statements for the numerical wTs transfer function from Dijk (2002)) if NMBR_SHFP < 3 + +Data 1000/62 +#EndIf 'Unique: multiplier for HFP01xx #3 (1000/sensitivity). +#If (NMBR_SHFP >3) Then 'This conditional statement can avoid the confliction with Data statements for the numerical wTs transfer function from Dijk (2002)) if NMBR_SHFP < 4 + +Data 1000/62 'Unique: multiplier for HFP01xx #4 (1000/sensitivity). +#EndIf + +#If (SENSOR_HFP01) Then +'*** Beginning of HFP01 wiring *** +'1H Signal #1 (white) +'1L Signal reference #1 (green) +'gnd Shield #1 (clear) + +'2H Signal #2 (white) +'2L Signal reference #2 (green) +'gnd Shield #2 (clear) + +'3H Signal #3 (white) +'3L Signal reference #3 (green) +'gnd Shield #3 (clear) + +'4H Signal #4 (white) +'4L Signal reference #4 (green) +'gnd Shield #4 (clear) +'*** End of HFP01 wiring *** +#EndIf +#If ( SENSOR_HFP01SC = TRUE ) Then + +Const SHF_HEATER_ANALOG_INPUT = 5 'Starting single-ended analog input channel to measure the heater of HFP01SC #1. + +'*** Beginning of HFP01SC wiring *** +'1H Signal #1 (white) +'gnd Signal reference #1 (green) +'gnd Shield #1 (clear) + +'1L Signal #2 (white) +'gnd Signal reference #2 (green) +'gnd Shield #2 (clear) + +'2H Signal #3 (white) +'gnd Signal reference #3 (green) +'gnd Shield #3 (clear) + +'2L Signal #4 (white) +'gnd Signal reference #4 (green) +'gnd Shield #4 (clear) + +'3H Heater resistor signal #1 (yellow) +'gnd Heater resistor signal reference #1 (purple) +' Heater shield #1 (clear) + +'3L Heater resistor signal #2 (yellow) +'gnd Heater resistor signal reference #2 (purple) +' Heater shield #2 (clear) + +'4H Heater resistor signal #3 (yellow) +'gnd Heater resistor signal reference #3 (purple) +' Heater shield #3 (clear) + +'4L Heater resistor signal #4 (yellow) +'gnd Heater resistor signal reference #4 (purple) +' Heater shield #4 (clear) + +'SW12-1 Heater power #1 (red) +' Heater power #2 (red) +' Heater power #3 (red) +' Heater power #4 (red) +'G Heater reference #1 (black) +' Heater reference #2 (black) +' Heater reference #3 (black) +' Heater reference #4 (black) +'*** End of HFP01SC wiring *** +#EndIf +#EndIf + +#If (SENSOR_FW) Then + +Const FW_ANALOG_INPUT = 5 'Differential analog input channel for FW (Input channel 5 or 11 is recommended) + +'*** Beginning of FW wiring *** +'5H FW signal (purple) +'5L FW signal reference (red) +'gnd FW shield (clear) +'*** End of FW wiring *** + +#EndIf +#If (SENSOR_Rn) Then +' Net radiations sensors +Const NR_ANALOG_INPUT = 6 'Starting differential analog input channel for a net radiation sensor. + +#EndIf +#If (SENSOR_NR_LITE) Then + +Const NRLITE_CAL = 1000/16 'Unique: multiplier for NR Lite (1000/sensitivity). +'*** Beginning of NR Lite wiring *** +'6H Signal (white/red) +'6L Signal reference (green/blue) +'gnd short jumper wire to 6L +' Shield (clear) +'*** End of NR Lite wiring *** + +#EndIf +#If (SENSOR_NR01) OR (SENSOR_CNR4) Then + +Const T_NR_ANALOG_INPUT = 10 'Differential analog input channel to measure body temperature of 4-way radiation sensor. For a single-end analog input channel (2*T_NR_ANALOG_INPUT-1) + +#EndIf +#If (SENSOR_NR01) Then + +Const T_NR_CURRENT_EXCITATION = Ix1 'Current excitation channel. +Const NR01_SW_IN_CAL = 1000/15 'Unique: multiplier for NR01 shortwave downwelling radiation (1000/sensitivity). +Const NR01_SW_OUT_CAL = 1000/15 'Unique: multiplier for NR01 shortware upwelling radiation (1000/sensitivity). +Const NR01_LW_IN_CAL = 1000/8 'Unique: multiplier for NR01 longwave downwelling radiation (1000/sensitivity). +Const NR01_LW_OUT_CAL = 1000/8 'Unique: multiplier for NR01 longwave upwelling radiation (1000/sensitivity). + +'*** Beginning of NR01 wiring *** +'6H Downwelling (incoming) shortwave radiation signal (red) +'6L Downwelling (incoming) shortwave radiation signal reference (blue) +'gnd Shield (clear) + +'7H Upwelling (outgoing) shortwave radiation signal (white) +'7L Upwelling (outgoing) shortwave radiation signal reference (green/black) + +'8H Downwelling (incoming) longwave radiation signal (brown/gray or orange) +'8L Downwelling (incoming) longwave radiation signal reference (yellow) + +'9H Upwelling (outgoing) longwave radiation signal (purple or pink/brown) +'9L Upwelling (outgoing) longwave radiation signal reference (gray/green) + +'10H Pt100 signal (white/yellow) +'10L Pt100 signal reference (green) +'gnd Pt100 shield (silver/bare) + +'IX1 Pt100 current excitation (red) +'IXR Pt100 current excitation reference (blue/blue) +'*** End of NR01 wiring *** +#EndIf +#If (SENSOR_CNR4) Then + +Const T_NR_VOLTAGE_EXCITATION = Vx1 'Voltage excitation channel. +Const CNR4_SW_IN_CAL = 1000/15 'Unique: multiplier for CNR4 shortwave downwelling radiation (1000/sensitivity). +Const CNR4_SW_OUT_CAL = 1000/15 'Unique: multiplier for CNR4 shortware upwelling radiation (1000/sensitivity). +Const CNR4_LW_IN_CAL = 1000/8 'Unique: multiplier for CNR4 longwave downwelling radiation (1000/sensitivity). +Const CNR4_LW_OUT_CAL = 1000/8 'Unique: multiplier for CNR4 longwave upwelling radiation (1000/sensitivity). + +'*** Beginning of CNR4 wiring *** +'6H Downwelling shortwave radiation signal (red) +'6L Downwelling shortwave radiation signal reference (blue) +'gnd Shield (clear) +' short jumper wire to 6L + +'7H Upwelling shortwave radiation signal (white) +'7L Upwelling shortwave radiation signal reference (black) +'gnd short jumper wire to 7L + +'8H Downwelling longwave radiation signal (gray) +'8L Downwelling longwave radiation signal reference (yellow) +'gnd short jumper wire to 8L + +'9H Upwelling longwave radiation signal (brown) +'9L Upwelling longwave radiation signal reference (green) +'gnd short jumper wire to 9L + +'10H Thermistor signal (white) +'gnd Thermistor signal reference (black) +' Shield (clear) + +'VX1 Thermistor excitation (red) +'*** End of CNR4 wiring *** + +#EndIf +#If (SENSOR_LI200X) OR (SENSOR_CS300) Then + +Const PYRAN_ANALOG_INPUT = 7 'Differential analog input channel for LI200X or CS300 Pyranometer +Const PYRAN_VOLTAGE_RANG = mV20 'Unique: measurement range of voltage mV20 for LI200 and mV250 for CS300 pyranometer +Const PYRAN_MULT = 200 'Unique: multiplier for LI200X [200 W/(m^2 * mV)] or CS300 [5 W/(m^2 * mV)] pyranometer . +Const PYRAN_OFFSET = 0 'Unique: offset for LI200X [0 W/m^2] or CS300 (0 W/m^2) pyranometer. + +'*** Beginning of Pyranometer wiring *** +'7H Pyranometer signal (red) +'7L Pyranometer signal reference (black) +'gnd Shield (clear) + +#If (SENSOR_LI200X) Then +'gnd Pyranometer current return (white) +#EndIf + +'*** End of pyranometer wiring *** +#EndIf +#If (SENSOR_LI190SB) Then + +Const QUANTUM_ANALOG_INPUT = 8 'Differential analog input channel for quantum PAR sensor +Const QUANTUM_VOLTAGE_RANGE = mV20 'Unique: measurement range of voltage +Const QUANTUM_MULT = 256 'Unique: multiplier (1000 C) for quantum PAR sensor. +Const QUANTUM_OFFSET = 0 'Unique: offset for for quantum PAR sensor. + +'*** Beginning of quantum wiring *** +'8H Quantum signal (red) +'8L Quantum signal reference Jump to gnd (black) +'gnd Shield (clear) +'*** End of quantum wiring *** +#EndIf +#If (SENSOR_SI111) Then +Const SI111_ANALOG_INPUT = 9 'Differential analog input channel for SI-111 sensor +Const SI111_EXCITATION = Vx2 'Voltage excitation channel for SI-111 sensor + +Const m0_SI111 = 1.41970e9 'Unique: calbration m0 +Const m1_SI111 = 7.84100e6 'Unique: calbration m1 +Const m2_SI111 = 82213 'Unique: calbration m2 +Const b0_SI111 = -1.72150e7 'Unique: calbration b0 +Const b1_SI111 = 1.85020e5 'Unique: calbration b1 +Const b2_SI111 = 13114 'Unique: calbration b2 + +'*** Beginning of SI-111 precision infrared radiometer wiring*** +'9H SI111 target signal (red) +'9L SI111 target signal reference. Jump to gnd (black) +'gnd Shield (clear) + +'10H SI111 body temperature signal (green) +'gnd SI111 body temperature signal reference (blue) +'VX2 SI111 voltage excitation (white) +'*** Beginning of SI-111 precision infrared radiometer *** +#EndIf +#If (SENSOR_TCAV) Then + +Const TCAV_ANALOG_INPUT = 11 'Staring differential analog input channel for TCAV. +Const NMBR_TCAV = 2 'Unique: number of TCAV (Maximum is 2) + +'*** Beginning of TCAV wiring *** +'11H Signal #1 (purple) +'11L Signal reference #1 (red) +'gnd Shield #1 (clear) + +'12H Signal #2 (purple) +'12L Signal reference #2 (red) +'gnd Shield #2 (clear) +'*** End of TCAV wiring *** +#EndIf +#If (SENSOR_CS6XX) Then + +Const NMBR_CS6xx = 2 'Unique: number of CS616, CS650, or CS655 sensors (Maximum is 2) + +#If (SENSOR_CS616) Then + +Const CS616_ANALOG_INPUT = 25 'Starting single-ended analog input channel. +Const CS616_POWER_CTRL = 4 'Unique: control port for CS616. +'*** Beginning of CS616 wiring *** +'13H Signal #1 (green) +'13L Signal #2 (green) +'C4 Power control #1 (orange) +' Power control #2 (orange) +'G Shield #1 (clear) +' Shield #2 (clear) + +'12V Power #1 (red) +' Power #2 (red) +'G Signal reference #1 (black) +' Signal reference #2 (black) +'*** End of CS616 wiring *** +#EndIf +#If (SENSOR_CS65X) Then + +Const CS65X_SDI12_PORT = 5 'Control port. +Const CS65X_SDI12_Address_1 = 1 'Unique: SDI address for CS655 #1 +#If (NMBR_CS6xx = 2) Then +Const CS65X_SDI12_Address_2 = 2 'Unique: SDI address for CS655 #2 +#EndIf +'*** Beginning of CS65X wiring *** +'C5 SDI-12 data #1 (green) +' SDI-12 data #2 (green) +'G RS-232 Rx #1 (orange) +' RS-232 Rx #2 (orange) + +'12V SDI-12 power #1 (red) +' SDI-12 power #2 (red) +'G SDI-12 data/power reference #1 (black) +' Shield #1 (clear) +' SDI-12 data/power reference #2 (black) +' Shield #2 (clear) +'*** End of CS65X wiring *** +#EndIf +#EndIf +#If (SENSOR_TMPR_RH) Then + +Const TMPR_RH_ANALOG_INPUT = 27 'Single-end analog input channel for temperature and humidity probe. +Const TMPR_RH_T_MULT = 0.14 'Unique: multiplier for temperature; HC2S3 = 0.1, HMP155A = 0.14, or HMP45C = 0.1. +Const TMPR_RH_T_OFFSET = -80 'Unique: offset for temperature; HC2S3 = -40, HMP155A = -80, or HMP45C = -40. + +'*** Beginning of HC2S3 or HMP wiring *** +'14H Temperature signal (brown/yellow) +'gnd Signal reference (yellow/white) + +'14L Relative humidity signal (white/blue) +'gng jumper wire to 14L +'gnd Shield (clear/clear) + +'12V Power (green/red) +'G Power reference (gray/black) +'*** End of HC2S3 or HMP wiring *** +#EndIf +#If (SENSOR_TE525mm) Then + +Const TE525_PULSE_INPUT = 1 'Pulse input channel rain gauge. +Const TE525_MULT = 0.1 'Unique: multiplier for TE525MM + +'*** Beginning of TE525mm wiring *** +'P1 Precipitation (black) +'gnd Signal reference (white) +'gnd Shield (clear/clear) +'*** End of TE525mm wiring *** +#EndIf + +'POWER IN +'12V datalogger (red) +'G datalogger (black) + +'EXTERNAL POWER SUPPLY +'+12V datalogger (red) +'G datalogger (black) +'***** End Wiring Instruction ***** + + +'*** Beginning station constants and variables ***. +Const SCAN_INTERVAL = 100 'Unique: measurement rate 100 ms (10 Hz), 200 ms (5 Hz), or 1000 ms (1 Hz) (For this CR3K program, the shortest scan interval is 100 ms) +Const SLOWSEQUENCE_SCAN_INTERVAL = 5000 'Unique: slow sequence measurement rate (ms) (For this CR3K program, the shortest scan interval is 2000 ms) +Const OUTPUT_INTERVAL = 30 'Unique: online flux data output interval (minutes). +Const NMBR_DAY_CPU = 7 'Number of days for flux data to store on the CPU. +Const NMBR_DAY_FLUX_CRD = 30 'Unique: number of days of Flux and Flux_Notes table data to store in each file on the card. Number of files stored depends on card size. +Const NMBR_DAY_TIMESERIES_CRD = 1 'Unique: number of days of Time_Series table data to store in each file on the card (days). Number of files stored depends on card size. +Const SDM_PER = 30 'Unique: default SDM clock speed (uS). +Const EC100_SDM_ADDR = 1 'Unique: SDM address for EC100. + +Const ANALOG_INTEGRATION = _60Hz 'Unique: slowsequence analog measurement integration time, _60Hz (e.g. in US, Canada, etc.) or _50Hz (e.g. in Europe, China, etc.) + +Const NMBR_STN_VAR = (16 - 3*SENSOR_FW -3*((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X)))) 'Number of station variables below + +Public stn_conf_array(NMBR_STN_VAR) 'These station parameters are entered using the datalogger keypad after program has compiled and is running. +Alias stn_conf_array(1) = sonic_azimuth 'Azimuth angle (degrees) (see Section 3.2.1 CSAT3A Azimuth in the OPEC manual). +Alias stn_conf_array(2) = latitude 'Latitude (degrees) +Alias stn_conf_array(3) = hemisphere_NS '"1" for north and "-1" for south, following GPS convention +Alias stn_conf_array(4) = longitude 'Longitude (degrees) +Alias stn_conf_array(5) = hemisphere_EW '"1" for east and "-1" for west, following GPS convention +Alias stn_conf_array(6) = height_measurement 'Measurement height (m) +Alias stn_conf_array(7) = displacement_user 'User-entered displacement height (m) [If 0 (default), then auto calculate] +Alias stn_conf_array(8) = height_canopy 'canopy height (m). +Alias stn_conf_array(9) = surface_type 'crop = 1, grass = 2, forest = 3, shrub = 4, bare land = 5, and water = 6 +Alias stn_conf_array(10) = roughness_user 'User-entered roughness length (m) [If 0 (default), then auto calculate and continuously updated by recalculation when netrual stratification] +Alias stn_conf_array(11) = separation_x_irga 'x coordinate of IRGA optical path center along the sonic x-coordinate axis (m) +Alias stn_conf_array(12) = separation_y_irga 'y coordinate of IRGA optical path center along the sonic y-coordinate axis (m) +Alias stn_conf_array(13) = dist_intrst_60_300 'Distance of interest for wind directions 0~60 and 300~360 degrees in sonic coordinate system (m) +Alias stn_conf_array(14) = dist_intrst_60_170 'Distance of interest for wind directions >60 and <=170 degrees in sonic coordinate system (m) +Alias stn_conf_array(15) = dist_intrst_170_190 'Distance of interest for wind directions >170 and <190 degrees in sonic coordinate system (m) +Alias stn_conf_array(16) = dist_intrst_190_300 'Distance of interest for wind directions >=190 and <300 degree in sonic coordinate system (m) + +Units sonic_azimuth = degrees +Units latitude = degrees +Units hemisphere_NS = unitless +Units longitude = degrees +Units hemisphere_EW = unitless +Units height_measurement = m +Units displacement_user = m +Units height_canopy = m +Units surface_type = unitless +Units roughness_user = m +Units separation_x_irga = m +Units separation_y_irga = m +Units dist_intrst_60_300 = m +Units dist_intrst_60_170 = m +Units dist_intrst_170_190 = m +Units dist_intrst_190_300 = m + +#If (SENSOR_FW) Then +Alias stn_conf_array(17) = separation_x_FW 'Coordinate x of FW junction in the sonic coordinate system (m) +Alias stn_conf_array(18) = separation_y_FW 'Coordinate y of FW junction in the sonic coodinate system (m) +Alias stn_conf_array(19) = FW_diameter 'Diameter of fine wire (m) +Units separation_x_FW = m +Units separation_y_FW = m +Units FW_diameter = m +#EndIf + +#If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then +Alias stn_conf_array(17 - 3*SENSOR_FW) = soil_bulk_density 'Soil bulk density (kg/m^3) +Alias stn_conf_array(18 - 3*SENSOR_FW) = Cds 'Specific heat of dry mineral soil [J/(kg K)] [Table 8.2 on page 118 in Campbell & Norman (1998)] +Alias stn_conf_array(19 - 3*SENSOR_FW) = thick_abv_SHFP 'Thickness of soil above soil heat flux plate (m) +Units soil_bulk_density = kg/m^3 +Units Cds = J/(kg k) +Units thick_abv_SHFP = m +#EndIf + +Dim stn_conf_array_prev(NMBR_STN_VAR) 'Hold previous station parameters to check for new user-entered values + +'After user input, used to assign a sign to latitude and longitude +Const Hemisphere_North = 1 +Const Hemisphere_South = -1 +Const Hemisphere_East = 1 +Const Hemisphere_West = -1 + +'Used to assign a value for surface_type +Const CROP = 1 +Const GRASS = 2 +Const FOREST = 3 +Const SHRUB = 4 +Const BARELAND = 5 +Const WATER = 6 + +Dim surface_type_array(6) As String * 9 = {"Crop", "Grass", "Forest", "Shrub", "Bare land", "Water"} +Dim surface_type_text As String * 9 'Used to record the surface type in data table + +#If (SENSOR_FW) Then +Const FW05DIA = 1.27e-5 'Diameter of FW05 fine wire that is selected for FW diameter(m) +Const FW1_DIA = 2.54e-5 'Diameter of FW1 fine wire that is selected for FW diameter(m) +Const FW3_DIA = 7.62e-5 'Diameter of FW3 fine wire that is selected for FW diameter(m) +#EndIf + +Dim stn_var_check_count As Long 'Working variable to count loops to check one of the station variables every slow sequence scan for a change in value, initiated by the user from keypad or loggerNet connection. +'*** End of station constants and variables ***. + +'*** Beginning general constants for CR3K *** +Const OFFSET = 17 'An offset delay (instrument scan lags) that will be introduced to the eddy covariance data used to compute online fluxes. +Const SCAN_BUFFER_SIZE = 290*INT (1000/SCAN_INTERVAL) 'Compute a 290-second scan buffer (The buffer less than 5 minutes is required because of 5-minute interval for data tables used in QC. + +Const FLUX_SIZE_CPU = Ceiling ((NMBR_DAY_CPU*1440)/OUTPUT_INTERVAL) 'Size of flux data table on CPU [(days*1440 minutes/day)/(minutes/record)] = records]. +'*** End of general constants for CR3K *** + +'*** Beginning constants and variables for atmospheric physics [Unless noted, see page 467 in Wallace and Hobbs (2006)] *** +Const Cpd = 1004 'specific heat of dry air at constant pressure [J/(kg K)] +Const Cpw = 1952 'specific heat of water vapor at constant pressure [J/(kg K)] +Const Cw = 4218 'specific heat of liquid water at 0 C [J/(kg K)] +Const epsilon = 18.016/28.97 'molecular mass ratio of water vapor to dry air +Const g0 = 9.81 'acceleration due to gravity at sea level (m/s^2) +Const k = 0.41 'von Karman constant (Dyer & hicker 1970, Webb 1970) +Const MU_WPL = 28.97/18.016 'molecular mass ratio of dry air to water vapor (used in WPL correction) +Const Omega = 7.292e-5 'Angular velocity of the earth for calculation of Coriolis Force (2PI/sidreal_day, where sidereal day = 23 hr 56 min. [rad/s] +Const R = 8.3143e-3 'Universal gas constant [kPa m^3/(K mol)] +Const Rd = R/28.97 'Gas constant for dry air [kPa m^3/(K g)] +Const Rv = R/18.016 'Gas constant for water vapor [kPa m^3/(K g)] +Const PI = 3.1415926 'Pi (just use the seven digits after decimal, commonly used) +Const T_0C_K = 273.15 'Temperature in K when it is zero in C + +Public Cp 'specific heat of moist air at constant pressure, calculated using measurements from EC100 data [J/(kg C)] +Units Cp = J/(kg C) + +Public Lv 'Latent heat of vaporization, calculated using air temperature [J/g]. +Units Lv = J/g +'*** End of constants and variables for atmospheric physics *** + +'*** Beginning program working variables *** +Dim scan_count As Long 'Number scans executed. Working variable used to judge the scan loop, from which data processing starts. + +Dim slowsequence_finished_flg As Boolean 'Flag used to indicate that the slowSequence has finished its scan. +Dim slowsequence_disable_flg As Boolean 'Flag used to decimate statistics in main scan. + +Dim sys_conf_var_file As Long 'Filehandle for the file that contains the system configuration variables in the CPU. + +Dim i, i_slow As Long 'Index variables for the outmost loop. "i" in main scan and "i_slow" in slow scan sequence +Dim ii, ii_slow As Long 'Index variables inside outmost loop. "ii" in main scan and "ii_slow" in slow scan sequence +Dim array_index As Long 'Used for array index that must be calculated using loop index (to simplify expression and reduce computation for array index) + +Dim n = 1 'Used for counting the number of samples Units n = samples -Dim sensor_shfp As Boolean 'set based on site SN - -'----- RETAINED SETTINGS ----- -Const NUM_SETTINGS = {24} 'set to length of settings array -Const WRITEFILE = 0 -Const READFILE = 1 - -Dim settings(NUM_SETTINGS) 'values retained via file written to datalogger CPU -Alias settings(1) = sonic_azimuth -Alias settings(2) = NRLite2_sens -Alias settings(3) = LI190SB_sens -Alias settings(4) = cup_ws_enabled -Alias settings(5) = vane_wd_enabled -Alias settings(6) = rain_enabled -Alias settings(23) = hfp1_sens -Alias settings(24) = hfp2_sens -Units hfp1_sens = uV/W/m^2 -Units hfp2_sens = uV/W/m^2 -Units sonic_azimuth = degEofTN -Units NRLite2_sens = uV/W/m^2 -Units LI190SB_sens = uA/mmol/m^2/s - -Public choice(NUM_SETTINGS) -Alias choice(1) = set_sonic_azimuth -Alias choice(2) = set_NRLite2_sens -Alias choice(3) = set_LI190SB_sens -Alias choice(4) = set_cup_ws_enabled -Alias choice(5) = set_vane_wd_enabled -Alias choice(6) = set_rain_enabled -Alias choice(23) = set_hfp1_sens -Alias choice(24) = set_hfp2_sens - - -'*********** CR3000 ************ -Dim panel_tmpr -Units panel_tmpr = C -Dim batt_volt -Units batt_volt = V - - -'*********** EC100/EC150/CSAT3A ********** -Const OFFSET = 17 'min # recs req'd to compensate for IRGA/CSAT lags on-the-fly -Const BANDWIDTH = 20 '20 = 20 Hz -Const DELAY_EC150 = INT (4000/FAST_INTV/BANDWIDTH) 'Automatically computed lag of the EC150 data. -Const EC150_REC_BCK = OFFSET-DELAY_EC150 'Number of records back to align EC150 data. - -Dim sonic_irga_raw(13) 'unlagged EC150 irga + CSAT3A sonic data - -Dim sonic(5) 'lagged working CSAT3A data -Alias sonic(1) = Ux -Alias sonic(2) = Uy -Alias sonic(3) = Uz -Alias sonic(4) = Ts -Alias sonic(5) = diag_sonic -Units Ux = m/s -Units Uy = m/s -Units Uz = m/s -Units Ts = C -Units diag_sonic = bitmap - -Dim irga(9) -Alias irga(1) = CO2 -Alias irga(2) = H2O -Alias irga(3) = diag_irga -Alias irga(4) = amb_tmpr -Alias irga(5) = amb_press -Alias irga(6) = CO2_signal -Alias irga(7) = H2O_signal -Alias irga(8) = Tc -Alias irga(9) = CO2_hf 'irga(1) calculated using sonic temp instead of thermistor -Units CO2 = mg/m^3 -Units H2O = g/m^3 -Units diag_irga = bitmap -Units amb_tmpr = C -Units amb_press = kPa -Units CO2_signal = unity -Units H2O_signal = unity -Units Tc = C -Units CO2_hf = mg/m^3 - -Dim CO2_hf_ppm -Units CO2_hf_ppm = ppmv - -Dim mask As Long -Dim diag_sonic_tmp As Long 'used to break out the CSAT3A sonic head diagnostic bits. -Dim sonic_disable_f As Boolean 'TRUE if CSAT3A diag warning flag, SDM error or no data -Dim diag_irga_tmp As Long 'used to break out the EC150 diagnostic bits. -Dim irga_disable_f As Boolean 'TRUE when EC150 sends bad data. +Dim dly_data_out(7) 'Array used to temporarily store the lagged record from the raw data table (hidden) + +Dim x_tmp 'Temporary variable used in intermediate calculations + +Dim process_time 'Used to monitor processing time and reported in flux_notes table +Units process_time = ms 'Converted from us to ms that is easy to read + +Dim buff_depth 'Used to monitor buffer depth and reported in flux_notes table +Units buff_depth = scans +'*** End program working variables *** + +'*** Beginning datalogger self-measurement variables *** +Public panel_tmpr +Units panel_tmpr = C + +Public batt_volt +Units batt_volt = V +'*** End of datalogger self-measurement variables *** + +'*** Beginning of correction constants and variables *** +' Rotation angles from the instrument to the natural flow coordinate system. Notation is consistent with Wilczak et al (2001) +Public alpha 'Angle of counterclockwise rotation about y-axis (pich) +Public beta 'Angle of counterclockwise rotation about x-axis (roll) +Public gamma 'Angle of counterclockwise rotation about z-axis (yaw) +Units alpha = degrees +Units beta = degrees +Units gamma = degrees + +Public alpha_5min '5-minute data for data QC. Angle of counterclockwise rotation about y-axis (pich) +Public beta_5min '5-minute data for data QC. Angle of counterclockwise rotation about x-axis (roll) +Public gamma_5min '5-minute data for data QC. Angle of counterclockwise rotation about z-axis (yaw) +Units alpha_5min = degrees +Units beta_5min = degrees +Units gamma_5min = degrees + +' Rotation angles for planar fit rotations +'1) Program chooses planar fit rotation of Wilczak et al. (2001) if one of the following eigtht angles is not zero. +'2) Program chooses conventional rotation of Tanner and Thurtell (1969) if the following eight angles are all zero. + +Dim planar_fit_angle_array_prev(4,2) 'Remembering variable: Hold previous angles for Planar Fit + +Public planar_fit_angle_array(4,2) 'Hold angles for Planar Fit +Units planar_fit_angle_array = degrees + +' Alpha_PF_xxx_xxx angle between instrument and natural flow z-axis in the instrument x-z plane. +Alias planar_fit_angle_array (1,1) = alpha_PF_60_300 'for wind direction of 0~60 and 300~360 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (2,1) = alpha_PF_60_170 'for wind direction of >60 and <=170 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (3,1) = alpha_PF_170_190 'for wind direction of >170 and <190 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (4,1) = alpha_PF_190_300 'for wind direction of >=190 and <300 degree in the sonic coordinate system [degrees] + +' Betal_PF_xxx_xxx angle between instrument and natural flow z-axis in the instrument y-z plane. +Alias planar_fit_angle_array (1,2) = beta_PF_60_300 'for wind direction of 0~60 and 300~360 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (2,2) = beta_PF_60_170 'for wind direction of >60 and <=170 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (3,2) = beta_PF_170_190 'for wind direction of >170 and <190 degrees in the sonic coordinate system [degrees] +Alias planar_fit_angle_array (4,2) = beta_PF_190_300 'for wind direction of >=190 and <300 degree in the sonic coordinate system [degrees] + +Public Planar_Fit_flg As Boolean 'TRUE if Planar Fit is used (e.g. any element of planar_fit_angle_array() is not zero) + +' Atmospheric stability +Public L 'Obukhov length (m) +Public d 'displacement height (m) +Public z0 'roughness length (m) +Public z 'aerodynamic height: z = measurement height - d (m) +Public z_prev 'Used to judge whether or not the distance of interest needs to be re-evaluated after z is recalculated +Public stability_zL 'atmospheric surface-layer stability (dimensionless) +Public stability_zL_prev 'remembering variable: previous atmospheric Surface-layer stability to remember stability_zL (dimensionless) +Units L = m +Units d = m +Units z0 = m +Units z = m +Units stability_zL = unitless + +' Frequency (freq) correction +Public iteration_FreqFactor As Long 'count iterations while correcting wu, wv, and wTs for accurate Obukhov length +Public FreqFactor_uw_vw 'freq correction factor for covariance of vertical with horizontal wind that are measured using sonic +Public FreqFactor_uw_vw_Prev 'Remembering variable: previous freq correction factor for covariance of vertical with horizontal wind that are measured using sonic +Public FreqFactor_wTs 'freq correction factor for covariance of vertical wind with sonic temperature that are measured using sonic +Public FreqFactor_wTs_Prev 'remembeing variable: previous freq correction factor for covariance of vertical wind with sonic temperature that are measured using sonic +Public FreqFactor_wCO2_wH2O 'freq correction factor for covariance of vertical wind with IRGA h2o or co2 that are measured using CSI sonic +Units FreqFactor_uw_vw = unitless +Units FreqFactor_wTs = unitless +Units FreqFactor_wCO2_wH2O = unitless + +#If (SENSOR_FW) Then +Public FreqFactor_wFW 'freq correction factor for covariance of vertical wind with temperature that are measured using sonic and FW +Units FreqFactor_wFW = unitless +#EndIf + +' Constants used for numerical integration in calculating the freq correction factors +Const START_FREQ = 10e-6 'Starting cyclic freq for numerical integration of cospectrum times transfer function +Const END_FREQ = 10000 'Ending cyclic freq for numerical integration of cospectrum times transfer function +Const FREQ_BIN = 100 'The number of bins for cyclic freq +Const STEP_BASE_FREQ = EXP((LN(END_FREQ)- LN(START_FREQ))/FREQ_BIN) 'freq interval base for numerical integration of cospectra and transfer functions (e.g. 100 bins from 0.000001 to 10000 Hz). +Const ACCURACY_FREQ_FACTOR = 0.0001 'The accuracy target of freq factor to approach the "true" value (|current freq factor - previous freq factor|) [page 106: Foken et al. (2012)] +Const MAX_LAG = 2 'Maximum number of lags in scans that is used to maximizing the covariance. This number of 2 is believed to be adequate for sonic with EC150 and/or FW + +' ------ Numerical wTs transfer function Dijk (2002): alternatively kl and transfer function value where k is wavenumber and l is path length ------ +Dim tran_func_LA_data_Dijk(2,35) 'Hold following numerical values of transfer function of line averaging for wTs of CSAT3 measurements from Table 1 in Dijk (2012) +Data 0.00, 1.00000, 0.01, 1.00000, 0.10, 0.99920, 0.20, 0.99760, 0.50, 0.99000, 1.00, 0.96700, 1.20, 0.95500, 1.40, 0.94170, 1.60, 0.92740 +Data 1.80, 0.91220, 2.00, 0.89620, 2.20, 0.87970, 2.40, 0.86260, 2.60, 0.84520, 2.80, 0.82740, 3.00, 0.80960, 4.00, 0.72010, 5.00, 0.63530 +Data 6.00, 0.55880, 7.00, 0.49220, 8.00, 0.43550, 9.00, 0.38790, 10.0, 0.34810, 14.0, 0.24450, 20.0, 0.17000, 30.0, 0.11340, 40.0, 0.08503 +Data 50.0, 0.06802, 60.0, 0.05668, 70.0, 0.04859, 80.0, 0.04251, 90.0, 0.03779, 100, 0.03401 +Data 300, 1.16e-4, 10000, 1.16e-4 ' The data points were extended to kl= 300 and 10000 according to the numerical derivative of transfer function with respect to kl from kl= 70 to 100. +' ----------------------------------------- End of numerical wTs transfer function values from Dijk (2002) ------------------------------------------ +'*** End of correction constants and variables *** + +'*** Beginning of EC100 configure, zero, and span constants and variables, and subroutine *** +Const BANDWIDTH = 20 'Unique: in Hz. For spectral analysis, set to 1/2 sampling freq. Options: 5, 10, 12.5, 20, or 25 Hz. For flux only, set 20 Hz (default) +Const DIFFERENTIAL_PRESSURE = 0 'Unique: 0 = disabled. Not applicable to an OPEC system. Should be disabled +Const TEMPERATURE_SOURCE = 0 'Unique: 0 = defaut EC100 temperature probe +Const BB = 0 'Unique: BB = 0 for EC100 built-in basic pressure transducer +Const EB = 2 'Unique: EB = 2 for EC100 added enhanced pressure transducer +Const HEATER = -2 'Unique: -1--> heater off, -2--> heater auto +Public press_source = BB 'Unique: Defaut pressure transducer (EC100 built-in basic pressure transducer) + +Public CO2_span_gas 'CO2 standard gas for CO2 span (umol/mol, read from the CO2 gas cilinder bottle) +Public Td_span_gas 'Dew point temperaure for H2O span (C, read from the Dew Point generator) + +Dim config_array (4, 2) = {0, BANDWIDTH, 3, DIFFERENTIAL_PRESSURE, 7, TEMPERATURE_SOURCE, 18, HEATER} +Dim press_source_array (1, 2) = {2, BB} '1st col 2--> barometer set commend, 2nd col pressure source, BB=0--> EC100 built-in basic pressure transducer, EB=2 enhanced pressure transducer. +Dim zero_array (1, 2) = {11, 1} 'Used for zeroing operation: 1st col 11--> Zero/Span command, 2nd col 0--> Inactive, 1--> Zero, 2--> SpanCO2, 3--> SpanH2O . +Dim span_CO2_array (2, 2) = {12, 0, 11, 2} 'Used for CO2 span operation: 1st col 12->CO2 span concentration, 2nd col CO2 span value (0 as default). 3rd and 4th cols are zero_array above. +Dim span_H2O_array (2, 2) = {13, 0, 11, 3} 'Used for H2O span operation: 1st col 13->H2O span dew point temperature,2nd col dew point temperature (0 as default). 3rd and 4th cols are zero_array above. +Dim heater_option_array(1, 2) = {18, HEATER} '1st col 18 control heaters for lenses of gas analyzer, 2nd col HEATER = -1 off, HEATER = -2 auto to set 0 ~ 4.5375 V +Dim EC150_power_array (1, 2) = {21, 0} 'Used for power off IRGA (not for EC100): 1st col 21 control power commend and 2nd col 0 --> power off IRGA + +Dim configure_ec100_flg As Boolean = TRUE 'Default: Configure EC100 as soon as this program starts +Public set_press_source_flg As Boolean +Public do_zero_flg As Boolean +Public do_CO2_span_flg As Boolean +Public do_H2O_span_flg As Boolean +Public set_heater_flg As Boolean +Dim EC150_power_flg As Boolean +Dim NAN_cnt As Long + +Sub Config (cmd_array(4, 2), num_cmd As Long, retry_config_flg As Boolean) + Dim kk As Long + Dim config_result As Long + Dim save_flash_flg As Boolean + + For kk = 1 To num_cmd + EC100Configure (config_result, EC100_SDM_ADDR, cmd_array(kk,1), cmd_array(kk,2)) + If (config_result = NAN) Then ExitFor + If (cmd_array(kk,1) = 2) OR (cmd_array(kk,1) = 11) Then save_flash_flg = TRUE ' Save the setting for pressure transducer, zero/span + Next kk + + If (kk = num_cmd + 1) Then + If (save_flash_flg) Then EC100Configure (config_result, EC100_SDM_ADDR, 99, 2718) + If (config_result <> NAN) Then retry_config_flg = FALSE + EndIf + + SetStatus ("SkippedScan", 0) + save_flash_flg = FALSE +EndSub +'*** End of EC100 configure, zero, and span constants and variables, and subroutine *** + +'*** Beginning of sonic head constants, variables, and working data table *** +Const PATH_LENGTH_CSAT = 0.1154701 'sonic path length = 10 cm/sin(2pi/3) (m) + +Public sonic(5) 'Hold sonic data aligned in scan with data from IRGA and/or +Alias sonic(1) = Ts +Alias sonic(2) = Ux +Alias sonic(3) = Uy +Alias sonic(4) = Uz +Alias sonic(5) = diag_sonic +Units Ts = C +Units Ux = m/s +Units Uy = m/s +Units Uz = m/s +Units diag_sonic = unitless + +Dim diag_bits_sonic(6) As Boolean 'Sonic warning flags +Alias diag_bits_sonic(1) = sonic_amp_l_f 'Amplitude low warning flag +Alias diag_bits_sonic(2) = sonic_amp_h_f 'Amplitude high warning flag +Alias diag_bits_sonic(3) = sonic_sig_lck_f 'Poor signal lock warning flag +Alias diag_bits_sonic(4) = sonic_del_T_f 'Delta temperature warning flag +Alias diag_bits_sonic(5) = sonic_aq_sig_f 'Sonic acquiring signals warning flag +Alias diag_bits_sonic(6) = sonic_cal_err_f 'Signature error in reading sonic head calibration data +Units diag_bits_sonic = unitless + +Dim sonic_irga_raw(12) 'Hold the first 12 data of EC100 from sonic, IRGA, temperature sensor, and barometer (raw data before applying instrument scan lag). + +Dim diag_sonic_tmp As Long 'Working variable used to break out the sonic head diagnostic bits. +Dim sonic_disable_f As Boolean 'TRUE when any sonic diagnostic warning flag is on, sonic has not sent data, or an SDM signature error is reported. +Dim mask As Long 'Masking the diagnosis code. +Dim Ts_K 'Sonic temperature in K. + +Dim cov_out_sonic(19) 'sonic statistics. +Alias cov_out_sonic(1) = Ux_Avg +Alias cov_out_sonic(2) = Ux_Std +Alias cov_out_sonic(3) = UxUy_Cov +Alias cov_out_sonic(4) = UxUz_Cov +Alias cov_out_sonic(5) = Uy_Avg +Alias cov_out_sonic(6) = Uy_Std +Alias cov_out_sonic(7) = UyUz_Cov +Alias cov_out_sonic(8) = Uz_Avg +Alias cov_out_sonic(9) = Uz_Std +Alias cov_out_sonic(10) = Ts_Avg +Alias cov_out_sonic(11) = Ts_Std 'Ts standard deviation is stored here. Unlike standard deviation of momentum variable, it is not related to coordinate rotation +Alias cov_out_sonic(12) = TsUx_Cov +Alias cov_out_sonic(13) = TsUy_Cov +Alias cov_out_sonic(14) = TsUz_Cov +Alias cov_out_sonic(15) = wnd_spd +Alias cov_out_sonic(16) = rslt_wnd_spd +Alias cov_out_sonic(17) = wnd_dir_sonic 'wind direction of 0 to 360 degree in the sonic coordinate system, equal to Gamma in coordination rotation. +Alias cov_out_sonic(18) = std_wnd_dir +Alias cov_out_sonic(19) = wnd_dir_compass 'wind direction in compass convention +Units Ux_Avg = m/s +Units Ux_Std = m/s +Units UxUy_Cov = (m/s)^2 +Units UxUz_Cov = (m/s)^2 +Units Uy_Avg = m/s +Units Uy_Std = m/s +Units UyUz_Cov = (m/s)^2 +Units Uz_Avg = m/s +Units Uz_Std = m/s +Units Ts_Avg = C +Units Ts_Std = C +Units TsUx_Cov = C m/s +Units TsUy_Cov = C m/s +Units TsUz_Cov = C m/s +Units wnd_spd = m/s +Units rslt_wnd_spd = m/s +Units wnd_dir_sonic = degrees +Units std_wnd_dir = degrees +Units wnd_dir_compass = degrees + +' Variables after coordinate rotations as indicated by the last letter of "R" +' 3D wind components before coordinate roations are Ux, Uy, and Uz, and afterwards they are referred to as u, v, and w, respectively. + +Dim u_star_R 'Friction velocity after coordinate rotations +Dim u_Avg_R +Dim u_Std_R +Dim uv_Cov_R +Dim uw_Cov_R +Dim v_Avg_R +Dim v_Std_R +Dim vw_Cov_R +Dim w_Avg_R +Dim w_Std_R +Dim uTs_Cov_R +Dim vTs_Cov_R +Dim wTs_Cov_R + +Units u_star_R = m/s +Units u_Avg_R = m/s +Units u_Std_R = m/s +Units uv_Cov_R = (m/s)^2 +Units uw_Cov_R = (m/s)^2 +Units v_Avg_R = m/s +Units v_Std_R = m/s +Units vw_Cov_R = (m/s)^2 +Units w_Avg_R = m/s +Units w_Std_R = m/s +Units uTs_Cov_R = C m/s +Units vTs_Cov_R = C m/s +Units wTs_Cov_R = C m/s + +Public TKE 'specific turbulence kinetic energy +Units TKE = m^2/s^2 '[kg (m/s)^2]/kg + +' Variables after coordinate rotations (R) and freq corrections (F) as indicated by last two letters of "R_F" +Dim tau 'Drag force (stress) at surface (momentum flux) after coordinate rotations and freq corrections. +Dim u_star 'Friction velocity after coordinate rotations and freq corrections. +Dim wTs_Cov_R_F +Dim uw_Cov_R_F +Dim vw_Cov_R_F + +Units tau = (kg m/s)/(m^2 s) 'Equivalent to kg m^-3/(m/s)^2 +Units u_star = m/s +Units wTs_Cov_R_F = C m/s +Units uw_Cov_R_F = (m/s)^2 +Units vw_Cov_R_F = (m/s)^2 + +Public wTs_Cov_R_F_SND 'Covariance of sonic temperature with vertical velocity after rotation, freq, and SND corrections +Public T_star 'Scaling temperature +Public H 'Sensible heat flux: Derived from covariance of sonic temperatur after rotation, freq, and SND corrections +Units wTs_Cov_R_F_SND = C m/s +Units T_star = C +Units H = W/m^2 + +'*** Data quality classification: Constant and variables +Const OUTPUT_INTERVAL_SST = 5 'Sub-interval to calculate the statistics for Steady State Test (SST) [minutes] + +' Steady State Test (SST) +Public RN_uw_vw_cov_R 'Relative Non-Stationarity (RN) for momentum covariance (uw_cov_R and vw_cov_R) +Public RN_uw_cov_R 'Relative non-Stationarity for uw_cov_R. It is also used for the sum of uw_cov_SST from 5-min sub-intervals +Public RN_vw_cov_R 'Relative non-Stationarity for vw_cov_R. It is also used for the sum of vw_cov_SST from 5-min sub-intervals +Public RN_wTs_cov_R 'Relative non-Stationarity for wTs_cov_R. It is also used for the sum of wTs_cov_SST from 5-min sub-intervals +Public nmbr_interval_qc_csat 'Number of sub-intervals = (OUTPUT_INTERVAL in min)/(5 min) if not a 1st interval or CR3K starts before 5 min after an individual interval + +Dim cov_out_sonic_SST(17) 'sonic head statistics for Steady State Test (SST) +Alias cov_out_sonic_SST(1) = u_Avg_SST +Alias cov_out_sonic_SST(2) = uu_Cov_SST +Alias cov_out_sonic_SST(3) = uv_Cov_SST +Alias cov_out_sonic_SST(4) = uw_Cov_SST +Alias cov_out_sonic_SST(5) = v_Avg_SST +Alias cov_out_sonic_SST(6) = vv_Cov_SST +Alias cov_out_sonic_SST(7) = vw_Cov_SST +Alias cov_out_sonic_SST(8) = w_Avg_SST +Alias cov_out_sonic_SST(9) = ww_Cov_SST +Alias cov_out_sonic_SST(10) = TsTs_Cov_SST +Alias cov_out_sonic_SST(11) = uTs_Cov_SST +Alias cov_out_sonic_SST(12) = vTs_Cov_SST +Alias cov_out_sonic_SST(13) = wTs_Cov_SST +Alias cov_out_sonic_SST(14) = wnd_spd_SST +Alias cov_out_sonic_SST(15) = rslt_wnd_spd_SST +Alias cov_out_sonic_SST(16) = wnd_dir_sonic_SST 'wind direction in sonic coordinate system (0 to 360 degree) +Alias cov_out_sonic_SST(17) = std_wnd_dir_SST + +' Steady State Test after coordinate rotations +Dim u_Avg_SST_R +Dim uu_Cov_SST_R +Dim uv_Cov_SST_R +Dim uw_Cov_SST_R +Dim v_Avg_SST_R +Dim vv_Cov_SST_R +Dim vw_Cov_SST_R +Dim w_Avg_SST_R +Dim ww_Cov_SST_R +Dim uTs_Cov_SST_R +Dim vTs_Cov_SST_R +Dim wTs_Cov_SST_R + +' Data quality grading +Public tau_qc_grade 'Overall grade of data QC for momentum flux (i.e. for variable: tau) [1 (highest) to 9 (lowest)] +Public H_qc_grade 'Overall grade of data QC for sensible heat flux (i.e. for variable: H) [1 (highest) to 9 (lowest)] +Units tau_qc_grade = Grade +Units H_qc_grade = Grade + +'*** Footprint characteristics: Constant and variables *** +' Footprint characteristics +Const NMBR_INT_INTERV_SEGMENT = 20 'Unique: Base number of numerical integration intervals for footprint characteristics in each integration segment + +Public upwnd_dist_intrst 'Upwind distant of interest +Public FP_dist_intrst 'Cumulative footprint of measured scalar flux within upwind range of interest +Public FP_max 'Upwind location of source/sink that contributes most to the measured flux +Public FP_40 'Upwind range within which the source/sink contributes 40% to the measured flux +Public FP_55 'Upwind range within which the source/sink contributes 55% to the measured flux +Public FP_90 'Upwind range within which the source/sink contributes 90% to the measured flux +Units upwnd_dist_intrst = m +Units FP_dist_intrst = % +Units FP_max = m +Units FP_40 = m +Units FP_55 = m +Units FP_90 = m + +Public FP_Equation As String * 14 '"Kljun et al" or "KormannMeixner" +Units FP_Equation = authors + +'Raw data table +DataTable (delay_3d, TRUE, OFFSET) + TableHide + Sample (5, sonic_irga_raw(1), IEEE4) +EndTable + +' 5-minute covariance of sonic data for steady state tests +DataTable (comp_cov_3d_5min, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL_SST, Min, 1) + + 'Compute Ux mean and covariance of Ux with Ux, Uy, and Uz from sonic data. + Average (1, Ux, IEEE4, sonic_disable_f) 'Using sonic(2) + Covariance (3, Ux, IEEE4, sonic_disable_f, 3) 'Using sonic(2), sonic(3), and sonic(4) + + 'Compute Uy mean and covariance of Uy with, Uy, Uz from sonic data. + Average (1, Uy, IEEE4, sonic_disable_f) 'Using sonic(3) + Covariance (2, Uy, IEEE4, sonic_disable_f, 2) 'Using sonic(3) and sonic(4) + + 'Compute Uz mean and covariance of Uz with Uz from sonic data. + Average (1,Uz, IEEE4, sonic_disable_f) 'Using sonic(4) + Covariance (1,Uz, IEEE4, sonic_disable_f, 1) 'Using sonic(4) + + 'Compute covariance of Ts with Ts, Ux, Uy, and Uz from sonic data. + Covariance (4, Ts, IEEE4, sonic_disable_f, 4) 'Using sonic(1), sonic(2), sonic(3), sonic(4) + + WindVector (1, Uy, Ux, IEEE4, sonic_disable_f, 0, 1, 2) + +EndTable + +' 30-minute covariance of sonic data +DataTable (comp_cov_3d, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + 'Compute Ux mean and covariance of Ux with Ux, Uy, and Uz from sonic data. + Average (1, Ux, IEEE4,sonic_disable_f) 'Using sonic(2) + Covariance (3, Ux, IEEE4,sonic_disable_f, 3) 'Using sonic(2), sonic(3), and sonic(4) + + 'Compute Uy mean and covariance of Uy with, Uy, Uz from sonic data. + Average (1, Uy, IEEE4,sonic_disable_f) 'Using sonic(3) + Covariance (2, Uy, IEEE4,sonic_disable_f, 2) 'Using sonic(3) and sonic(4) + + 'Compute Uz mean and covariance of Uz with Uz from sonic data. + Average (1, Uz, IEEE4,sonic_disable_f) 'Using sonic(4) + Covariance (1, Uz, IEEE4,sonic_disable_f, 1) 'Using sonic(4) + + 'Compute Ts mean and covariance of Ts with Ts, Ux, Uy, and Uz from sonic data. + Average (1, Ts, IEEE4,sonic_disable_f) 'Using sonic(1) + Covariance (4, Ts, IEEE4,sonic_disable_f, 4) 'Using sonic(1), sonic(2), sonic(3), sonic(4) + + WindVector (1, Uy, Ux, IEEE4, sonic_disable_f, 0, 1, 2) + +EndTable +'*** End of sonic head constants, variables, and working data tables *** + +'*** Beginning of IRGA constants, variables, and working data table *** +Const DELAY_EC100 = INT ((4000/BANDWIDTH)/SCAN_INTERVAL) 'Automatically compute the electronic instrument lag of EC100 data in scan number +Const EC100_REC_BCK = OFFSET - DELAY_EC100 'Number of records back for aligning EC100 data with other sensor data in scan +Const PATH_LENGTH_IRGA = 0.1531 'IRGA path length (m). +Const CO2_SIG_STRGTH_THRESHOULD = 0.7 'Unique: CO2 signal strength threshold below which the CO2 data are not used in instructions of AVERAGE and COVARIANCE, but kept in time series data table +Const H2O_SIG_STRGTH_THRESHOULD = 0.7 'Unique: H2O signal strength threshold below which the CO2 data are not used in instructions of AVERAGE and COVARIANCE, but kept in time series data table +Const CO2_RNG_TOP_LIMIT = 1527 'Unique: Maximum CO2 density (mg/m^3) to which the analyzer was calibrated (factory calibration range of 0 ~ 1000 ppm CO2 in dry air at lab T = 25 C and in Logan P = 86 kPa) +Const H2O_RNG_TOP_LIMIT = 45.8 'Unique: Maximum H2O density (g/m^3) to which the analyzer was calibrated (factory calibration range 0f dew point temperature: 0 to 37 C at lab T = 25 C and in Logan P = 86 kPa) + +' Variables for separation corrections +Public separation_lat_dist_irga 'Effective separation distance (m) in direction normal to wind direction. Used for separation correction +Public separation_lag_dist_irga 'Effective separation distance (m) along wind direction. Used for lag maximization of covariance +Public separation_lag_scan_irga 'Lag of wind passing over IRGA (scans) after (+ lag) or before (- lag) passing sonic volume. Its unit is a scan number, but not necessary to use an integer. + +Units separation_lat_dist_irga = m +Units separation_lag_dist_irga = m +Units separation_lag_scan_irga = scans + +'Data from IRGA +Public irga(14) 'Hold IRGA data +Alias irga(1) = CO2 +Alias irga(2) = H2O +Alias irga(3) = diag_irga +Alias irga(4) = amb_tmpr 'Temperature measured by temperature probe connected to EC100 +Alias irga(5) = amb_press 'Pressure measured by a barometer connected to EC100 +Alias irga(6) = CO2_sig_strgth +Alias irga(7) = H2O_sig_strgth + +Alias irga(8) = Tc 'Air temperature (C), found from IRGASON' sonic temperature, water vapor density, or in case of the EC150/CSAT3A Tc=amb_tmpr from EC100 T probe +Alias irga(9) = RH 'Relative humidity (%): derived from Tc, H2O, and amb_press +Alias irga(10) = e_sat 'Saturation vapor pressure (kPa): derived from Tc, H2O, and amb_press +Alias irga(11) = e 'Vapor pressure (kPa): derived from Tc, H2O. and amb_press +Alias irga(12) = Td 'Dew point temperature (C): derived from Tc, H2O, and amb_press + +Alias irga(13) = CO2_mixratio 'CO2 mixing ratio +Alias irga(14) = H2O_mixratio 'H2O mixing ratio + +Units CO2 = mg/m^3 +Units H2O = g/m^3 +Units diag_irga = unitless +Units amb_tmpr = C +Units amb_press = kPa +Units CO2_sig_strgth = fraction +Units H2O_sig_strgth = fraction +Units Tc = C +Units RH = % +Units e_sat = kPa +Units e = kPa +Units Td = C +Units CO2_mixratio = umol/mol +Units H2O_mixratio = mmol/mol + +Dim diag_bits_irga(22) As Boolean 'Gas analyzer warning flags +Alias diag_bits_irga(1) = irga_bad_data_f 'EC150 bad data warning flag +Alias diag_bits_irga(2) = irga_gen_fault_f 'General fault warning flag +Alias diag_bits_irga(3) = irga_startup_f 'Gas analyzer starting up warning flag +Alias diag_bits_irga(4) = irga_motor_spd_f 'EC150 motor speed out of bounds warning flag +Alias diag_bits_irga(5) = irga_tec_tmpr_f 'Thermoelectric cooler temperature out of bounds warning flag +Alias diag_bits_irga(6) = irga_src_pwr_f 'Gas analyzer source power out of bounds warning flag +Alias diag_bits_irga(7) = irga_src_tmpr_f 'Gas analyzer source temperature out of bounds warning flag +Alias diag_bits_irga(8) = irga_src_curr_f 'Gas analyzer source current out of bounds warning flag +Alias diag_bits_irga(9) = irga_off_f 'Gas analyzer head is powered down +Alias diag_bits_irga(10) = irga_sync_f 'Gas analyzer not synchronized with home pulse warning flag +Alias diag_bits_irga(11) = irga_amb_tmpr_f 'Invalid ambient temperature warning flag +Alias diag_bits_irga(12) = irga_amb_press_f 'Invalid ambient pressure warning flag +Alias diag_bits_irga(13) = irga_CO2_I_f 'CO2 I out of bounds warning flag +Alias diag_bits_irga(14) = irga_CO2_Io_f 'CO2 Io out of bounds warning flag +Alias diag_bits_irga(15) = irga_H2O_I_f 'H2O I out of bounds warning flag +Alias diag_bits_irga(16) = irga_H2O_Io_f 'H2O Io out of bounds warning flag +Alias diag_bits_irga(17) = irga_CO2_Io_var_f 'CO2 Io moving variation out of bounds warning flag +Alias diag_bits_irga(18) = irga_H2O_Io_var_f 'H2O Io moving variation out of bounds warning flag +Alias diag_bits_irga(19) = irga_CO2_sig_strgth_f 'CO2 signal strength warning flag +Alias diag_bits_irga(20) = irga_H2O_sig_strgth_f 'H2O signal strength warning flag +Alias diag_bits_irga(21) = irga_cal_err_f 'Gas analyzer calibration data signature error +Alias diag_bits_irga(22) = irga_htr_ctrl_off_f 'Gas analyzer heater control disabled by EC100 +Units diag_bits_irga = unitless + +'Working variables +Dim divisor 'Temporary variable used to find molar mixing ratio. +Dim diag_irga_tmp As Long 'Temporary variable used to break out the EC150 diagnostic bits. +Dim irga_disable_f As Boolean 'TRUE when EC150 sends bad data. + +Dim sigma_wpl 'Webb et al. sigma = density of water vapor/density of dry air. +Dim Td_gu, Tc_K 'Working variables: Dew point temperature for general use (gu) and Tc in K. +Dim Enhance_Factor1, Enhance_Factor2 'Enhancement factors, both used for calculations of dew point temperature +Dim rho_d, rho_a 'Dry air density and moist air density + +' CO2: Lag maximization +Dim cov_array_CO2(2* MAX_LAG+1, 4) 'Arrays used to hold the CO2 data with -2, -1, 0, 1, or 2 scan lags relative to sonic data in order to find +'the lag that maximizes the covariance of CO2 with w. Once the optimum lag is found, it is also applied to +'H2O to find the maximum covariance of H2O with w because CO2 and H2O are measured using the same IRGA. +'Data are held in an array for more convenient calculation of covariances. +'Row used for lag of -2, -1, 0, 1, 2 scans. Columns used for CO2, u, v, and w. + +Dim irga_bad_data_flg_array (2* MAX_LAG + 1) As Boolean +Dim CO2_bad_rng_sig_array (2* MAX_LAG + 1) As Boolean 'Set high if CO2 out of range or CO2 signal strength below the CO2 signal strength threshould +Dim H2O_bad_rng_sig_array (2* MAX_LAG + 1) As Boolean 'Set high if H2O out of range or H2O signal strength below the H2O signal strength threshould + +Dim Cov_out_CO2(5*(2*MAX_LAG + 1)) 'CO2 variable and CO2-related covariance variables +Alias Cov_out_CO2(1) = CO2_Avg_b2 'b2 indicates backward 2 scans +Alias Cov_out_CO2(2) = CO2CO2_Cov_lag_b2 +Alias Cov_out_CO2(3) = uCO2_Cov_lag_b2 +Alias Cov_out_CO2(4) = vCO2_Cov_lag_b2 +Alias Cov_out_CO2(5) = wCO2_Cov_lag_b2 +Alias Cov_out_CO2(6) = CO2_Avg_b1 'b1 indicates backward 1 scan +Alias Cov_out_CO2(7) = CO2CO2_Cov_lag_b1 +Alias Cov_out_CO2(8) = uCO2_Cov_lag_b1 +Alias Cov_out_CO2(9) = vCO2_Cov_lag_b1 +Alias Cov_out_CO2(10) = wCO2_Cov_lag_b1 +Alias Cov_out_CO2(11) = CO2_Avg_0 '0 indicates neither backward nor forward +Alias Cov_out_CO2(12) = CO2CO2_Cov_lag_0 +Alias Cov_out_CO2(13) = uCO2_Cov_lag_0 +Alias Cov_out_CO2(14) = vCO2_Cov_lag_0 +Alias Cov_out_CO2(15) = wCO2_Cov_lag_0 +Alias Cov_out_CO2(16) = CO2_Avg_f1 'f1 indicates forward 1 scan +Alias Cov_out_CO2(17) = CO2CO2_Cov_lag_f1 +Alias Cov_out_CO2(18) = uCO2_Cov_lag_f1 +Alias Cov_out_CO2(19) = vCO2_Cov_lag_f1 +Alias Cov_out_CO2(20) = wCO2_Cov_lag_f1 +Alias Cov_out_CO2(21) = CO2_Avg_f2 'f2 indicates forward 2 scans +Alias Cov_out_CO2(22) = CO2CO2_Cov_lag_f2 +Alias Cov_out_CO2(23) = uCO2_Cov_lag_f2 +Alias Cov_out_CO2(24) = vCO2_Cov_lag_f2 +Alias Cov_out_CO2(25) = wCO2_Cov_lag_f2 + +' Variables after coordinate rotations as indicated by last letter "R" +Dim wCO2_Cov_lag_R (2*MAX_LAG + 1) 'Hold covariance of scan-lagged CO2 with w after coordinate rotation. Used for MaxSpa instruction +Alias wCO2_Cov_lag_R (1) = wCO2_Cov_lag_b2R 'b2R indicates backward 2 scans and after rotation +Alias wCO2_Cov_lag_R (2) = wCO2_Cov_lag_b1R 'b1R indicates backward 1 scans and after rotation +Alias wCO2_Cov_lag_R (3) = wCO2_Cov_lag_0R '0R indicates 0 lag in scans and after rotation +Alias wCO2_Cov_lag_R (4) = wCO2_Cov_lag_f1R 'f1R indicates forward 1 scans and after rotation +Alias wCO2_Cov_lag_R (5) = wCO2_Cov_lag_f2R 'f2R indicates forward 2 scans and after rotation + +Dim wCO2_Cov_major_sign 'Summarize the direction of CO2 flux (positive: up and negative: down) + +Dim uCO2_vCO2_Cov_lag_R(2*MAX_LAG + 1, 2) 'Hold the covariance of scan-lagged CO2 with u or v after coordinate rotation +Alias uCO2_vCO2_Cov_lag_R(1, 1) = uCO2_Cov_lag_b2R 'b2R indicates backward 2 scans and after-rotation +Alias uCO2_vCO2_Cov_lag_R(1, 2) = vCO2_Cov_lag_b2R +Alias uCO2_vCO2_Cov_lag_R(2, 1) = uCO2_Cov_lag_b1R 'b1R indicates backward 1 scans and after-rotation +Alias uCO2_vCO2_Cov_lag_R(2, 2) = vCO2_Cov_lag_b1R +Alias uCO2_vCO2_Cov_lag_R(3, 1) = uCO2_Cov_lag_0R '0R indicates 0 lag in scans and after-rotation +Alias uCO2_vCO2_Cov_lag_R(3, 2) = vCO2_Cov_lag_0R +Alias uCO2_vCO2_Cov_lag_R(4, 1) = uCO2_Cov_lag_f1R 'f1R indicates forward 1 scans and after-rotation +Alias uCO2_vCO2_Cov_lag_R(4, 2) = vCO2_Cov_lag_f1R +Alias uCO2_vCO2_Cov_lag_R(5, 1) = uCO2_Cov_lag_f2R 'f2R indicates forward 2 scans and after-rotation +Alias uCO2_vCO2_Cov_lag_R(5, 2) = vCO2_Cov_lag_f2R +Units uCO2_vCO2_Cov_lag_R = mg /(m^2 s) + +Dim wCO2_Cov_lag_max (2) 'Array used in MaxSpa instruction to hold the max covariance and the location of the max covariance in array: wCO2_Cov_lag_R() +Alias wCO2_Cov_lag_max (1) = wCO2_Cov_R 'Max covariance found from lagged covariance array [.i.e. wCO2_cov_lag_R()] and will be used for CO2 flux after freq correction +Alias wCO2_Cov_lag_max (2) = lag_irga 'Lag in number of scans, also used for sequential number in array index of lag wCO2_Cov_lag_R() and uCO2_vCO2_Cov_lag_R() +Units wCO2_Cov_R = mg/(m^2 s) +Units lag_irga = scans + +' H2O: Lag maximization +Dim cov_array_H2O(2* MAX_LAG+1, 4) 'Arrays used to hold the H2O data with -2, -1, 0, 1, or 2 scan lags relative to sonic data. The optimum lag_irga found during maximization +'of covariance of CO2 with w is assumed to also be the optimum lag for H2O data since the same IRGA measures both CO2 and H2O. +'Data are held in an array for more convenient calculation of covariances. +'Row used for lag of -2, -1, 0, 1, 2 scans. Columns used for H2O, u, v, and w. + +Dim Cov_out_H2O(5*(2*MAX_LAG + 1)) 'H2O variables and H2O-related covariances +Alias Cov_out_H2O(1) = H2O_Avg_b2 'b2 indicates backward 2 scans +Alias Cov_out_H2O(2) = H2OH2O_Cov_lag_b2 +Alias Cov_out_H2O(3) = uH2O_Cov_lag_b2 +Alias Cov_out_H2O(4) = vH2O_Cov_lag_b2 +Alias Cov_out_H2O(5) = wH2O_Cov_lag_b2 +Alias Cov_out_H2O(6) = H2O_Avg_b1 'b1 indicates backward 1 scan +Alias Cov_out_H2O(7) = H2OH2O_Cov_lag_b1 +Alias Cov_out_H2O(8) = uH2O_Cov_lag_b1 +Alias Cov_out_H2O(9) = vH2O_Cov_lag_b1 +Alias Cov_out_H2O(10) = wH2O_Cov_lag_b1 +Alias Cov_out_H2O(11) = H2O_Avg_b0 '0 indicates neither backward nor forward +Alias Cov_out_H2O(12) = H2OH2O_Cov_lag_0 +Alias Cov_out_H2O(13) = uH2O_Cov_lag_0 +Alias Cov_out_H2O(14) = vH2O_Cov_lag_0 +Alias Cov_out_H2O(15) = wH2O_Cov_lag_0 +Alias Cov_out_H2O(16) = H2O_Avg_f1 'f1 indicates forward 1 scan +Alias Cov_out_H2O(17) = H2OH2O_Cov_lag_f1 +Alias Cov_out_H2O(18) = uH2O_Cov_lag_f1 +Alias Cov_out_H2O(19) = vH2O_Cov_lag_f1 +Alias Cov_out_H2O(20) = wH2O_Cov_lag_f1 +Alias Cov_out_H2O(21) = H2O_Avg_f2 'f2 indicates forward 2 scans +Alias Cov_out_H2O(22) = H2OH2O_Cov_lag_f2 +Alias Cov_out_H2O(23) = uH2O_Cov_lag_f2 +Alias Cov_out_H2O(24) = vH2O_Cov_lag_f2 +Alias Cov_out_H2O(25) = wH2O_Cov_lag_f2 + +' Before coordinate rotations. Lag due to separation was applied if measured by EC150 +CSAT3A +Dim Cov_out_cs(18) 'IRGA statistics. +Alias Cov_out_cs(1) = CO2_Avg +Alias Cov_out_cs(2) = CO2_Std +Alias Cov_out_cs(3) = UxCO2_Cov +Alias Cov_out_cs(4) = UyCO2_Cov +Alias Cov_out_cs(5) = UzCO2_Cov +Alias Cov_out_cs(6) = H2O_Avg +Alias Cov_out_cs(7) = H2O_Std +Alias Cov_out_cs(8) = UxH2O_Cov +Alias Cov_out_cs(9) = UyH2O_Cov +Alias Cov_out_cs(10) = UzH2O_Cov +Alias Cov_out_cs(11) = amb_tmpr_Avg 'from 107 temperature probe connected to EC100 +Alias Cov_out_cs(12) = RH_Avg 'relative humidity (%): derived from Tc, H2O, and amb_press +Alias Cov_out_cs(13) = e_sat_Avg 'saturation vapor pressure (kPa): derived from Tc, H2O. and amb_press +Alias Cov_out_cs(14) = e_Avg 'vapor pressure (kPa): derived from Tc, H2O. and amb_press +Alias Cov_out_cs(15) = amb_press_Avg +Alias Cov_out_cs(16) = rho_d_Avg 'density of dry air (kg/m^3). calculated using Tc, H2O, and amb_press +Alias Cov_out_cs(17) = rho_a_Avg 'density of moist air (kg/m^3). calculated using Tc, H2O, and amb_press +Alias Cov_out_cs(18) = Tc_Avg 'air temperature (C), found from IRGASON' sonic temperature, H2O, and amb+press or in case of the EC150/CSAT3A Tc=amb_tmpr (temperature probe connected to EC100) +Units CO2_Avg = mg/m^3 +Units CO2_Std = mg/m^3 +Units UxCO2_Cov = mg/(m^2 s) +Units UyCO2_Cov = mg/(m^2 s) +Units UzCO2_Cov = mg/(m^2 s) +Units H2O_Avg = g/m^3 +Units H2O_Std = g/m^3 +Units UxH2O_Cov = g/(m^2 s) +Units UyH2O_Cov = g/(m^2 s) +Units UzH2O_Cov = g/(m^2 s) +Units amb_tmpr_Avg = C +Units RH_Avg = % +Units e_sat_Avg = kPa +Units e_Avg = kPa +Units amb_press_Avg = kPa +Units rho_d_Avg = kg/m^3 +Units rho_a_Avg = kg/m^3 +Units Tc_Avg = C + +Public CO2_molfrac_Avg +Units CO2_molfrac_Avg = umol/mol + +Public H2O_molfrac_Avg +Units H2O_molfrac_Avg = mmol/mol + +Public VPD_air 'ambient water vapor pressure deficit +Units VPD_air = kpa + +'After coordinate rotations as indicated by R +Dim uCO2_Cov_R +Dim vCO2_Cov_R +'For wCO2_Cov_R, see wCO2_Cov_lag_max (1) +Units uCO2_Cov_R = mg/(m^2 s) +Units vCO2_Cov_R = mg/(m^2 s) + +Dim uH2O_Cov_R +Dim vH2O_Cov_R +Dim wH2O_Cov_R 'found using lag_irga that was found while wCO2_cov_R was found +Units uH2O_Cov_R = g/(m^2 s) +Units vH2O_Cov_R = g/(m^2 s) +Units wH2O_Cov_R = g/(m^2 s) + +' After coordinate rotations and freq corrections as indicated by R_F +Dim wCO2_Cov_R_F +Dim wH2O_Cov_R_F +Units wCO2_Cov_R_F = mg/(m^2 s) +Units wH2O_Cov_R_F = g/(m^2 s) + +' WPL correction terms after coordinate rotations and freq corrections as indicated R_F +Dim CO2_E_WPL_R_F 'Carbon dioxide flux, WPL term due to water vapor flux (covariance of water vapor with vertical velocity) +Dim CO2_T_WPL_R_F 'Carbon dioxide flux, WPL term due to temperature flux (covariance of temperature with vertical velocity) +Dim H2O_E_WPL_R_F 'Water vapor flux, WPL term due to water vapor flux (covariance of water vapor with vertical velocity) +Dim H2O_T_WPL_R_F 'Water vapor flux, WPL term due to temperature flux (covariance of temperature with vertical velocity) +Units CO2_E_WPL_R_F = mg/(m^2 s) +Units CO2_T_WPL_R_F = mg/(m^2 s) +Units H2O_E_WPL_R_F = g/(m^2 s) +Units H2O_T_WPL_R_F = g/(m^2 s) + +' After coordinate rotations, freq corrections, and WPL correction +Public Fc_molar 'Carbon dioxide flux after coordinate rotation, freq, and WPL corrections in umol/m^2 s +Public Fc_mass 'Carbon dioxide flux after coordinate rotation, freq, and WPL corrections in mg/m^2 s +Public LE 'Latent heat flux after coordinate rotation, freq, and WPL corrections +Units Fc_molar = umol/(m^2 s) +Units Fc_mass = mg/(m^2 s) +Units LE = W/m^2 + +Public Bowen_ratio +Units Bowen_ratio = fraction + +'*** Variables for data QC +' Steady State Test +Public RN_wCO2_Cov_R 'Relative Non-stationarity (RN) for wCO2_cov_R. +Public RN_wH2O_Cov_R 'Relative non-stationarity for wH2O_cov_R. +Public nmbr_interval_qc_irga 'Number of sub-intervals = (OUTPUT_INTERVAL in min)/(5 min) if not a 1st interval or CR3K starts before 5 min after an individual interval + +Dim cov_out_irga_SST(8) 'IRGA statistics for Steady State Test (SST) +Alias cov_out_irga_SST(1) = CO2CO2_Cov_SST +Alias cov_out_irga_SST(2) = uCO2_Cov_SST +Alias cov_out_irga_SST(3) = vCO2_Cov_SST +Alias cov_out_irga_SST(4) = wCO2_Cov_SST +Alias cov_out_irga_SST(5) = H2OH2O_Cov_SST +Alias cov_out_irga_SST(6) = uH2O_Cov_SST +Alias cov_out_irga_SST(7) = vH2O_Cov_SST +Alias cov_out_irga_SST(8) = wH2O_Cov_SST + +' After coordinate rotations +Dim uCO2_Cov_SST_R +Dim vCO2_Cov_SST_R +Dim wCO2_Cov_SST_R +Dim uH2O_Cov_SST_R +Dim vH2O_Cov_SST_R +Dim wH2O_Cov_SST_R + +' Overall grade of data quality for CO2 and H2O fluxes +Public Fc_qc_grade 'Overall grade of data quality for CO2 flux (i.e. for variable: Fc_molar and Fc_mass) [1 (highest) to 9 (lowest)] +Public LE_qc_grade 'Overall grade of data quality for latent heat flux (i.e. for variable: LE) [1 (highest) to 9 (lowest)] +Units Fc_qc_grade = Grade +Units LE_qc_grade = Grade + +'Data table for delayed data from IRGA +DataTable (delay_cs, TRUE, (OFFSET + MAX_LAG)) + TableHide + Sample (7,sonic_irga_raw(6),IEEE4) +EndTable + +' 5-minute statistics +DataTable (comp_cov_cs_5min, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL_SST, Min, 1) + + Covariance (4, cov_array_CO2((MAX_LAG + 1), 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(MAX_LAG + 1) OR CO2_bad_rng_sig_array(MAX_LAG+1)),4) + Covariance (4, cov_array_H2O((MAX_LAG + 1), 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(MAX_LAG + 1) OR H2O_bad_rng_sig_array(MAX_LAG+1)),4) + +EndTable + +'Compute covariance of CO2 against sonic wind data. +DataTable (comp_cov_CO2, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + Average (1, cov_array_CO2(1, 1), IEEE4, (irga_bad_data_flg_array(1) OR CO2_bad_rng_sig_array(1))) + Covariance (4, cov_array_CO2(1, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(1) OR CO2_bad_rng_sig_array(1)),4) + + Average (1, cov_array_CO2(2, 1), IEEE4, (irga_bad_data_flg_array(2) OR CO2_bad_rng_sig_array(2))) + Covariance (4, cov_array_CO2(2, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(2) OR CO2_bad_rng_sig_array(2)),4) + + Average (1, cov_array_CO2(3, 1), IEEE4, (irga_bad_data_flg_array(3) OR CO2_bad_rng_sig_array(3))) + Covariance (4, cov_array_CO2(3, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(3) OR CO2_bad_rng_sig_array(3)),4) + + Average (1, cov_array_CO2(4, 1), IEEE4, (irga_bad_data_flg_array(4) OR CO2_bad_rng_sig_array(4))) + Covariance (4, cov_array_CO2(4, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(4) OR CO2_bad_rng_sig_array(4)),4) + + Average (1, cov_array_CO2(5, 1), IEEE4, (irga_bad_data_flg_array(5) OR CO2_bad_rng_sig_array(5))) + Covariance (4, cov_array_CO2(5, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(5) OR CO2_bad_rng_sig_array(5)),4) +EndTable + +'Compute covariance of H2O against sonic wind data. +DataTable (comp_cov_H2O, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + Average (1, cov_array_H2O(1, 1), IEEE4, (irga_bad_data_flg_array(1) OR H2O_bad_rng_sig_array(1))) + Covariance (4, cov_array_H2O(1, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(1) OR H2O_bad_rng_sig_array(1)),4) + + Average (1, cov_array_H2O(2, 1), IEEE4, (irga_bad_data_flg_array(2) OR H2O_bad_rng_sig_array(2))) + Covariance (4, cov_array_H2O(2, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(2) OR H2O_bad_rng_sig_array(2)),4) + + Average (1, cov_array_H2O(3, 1), IEEE4, (irga_bad_data_flg_array(3) OR H2O_bad_rng_sig_array(3))) + Covariance (4, cov_array_H2O(3, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(3) OR H2O_bad_rng_sig_array(3)),4) + + Average (1, cov_array_H2O(4, 1), IEEE4, (irga_bad_data_flg_array(4) OR H2O_bad_rng_sig_array(4))) + Covariance (4, cov_array_H2O(4, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(4) OR H2O_bad_rng_sig_array(4)),4) + + Average (1, cov_array_H2O(5, 1), IEEE4, (irga_bad_data_flg_array(5) OR H2O_bad_rng_sig_array(5))) + Covariance (4, cov_array_H2O(5, 1), IEEE4, (sonic_disable_f OR irga_bad_data_flg_array(5) OR H2O_bad_rng_sig_array(5)),4) +EndTable + +'Compute Tc-related data. +DataTable (comp_mean, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + Average (1, amb_tmpr, IEEE4, irga_amb_tmpr_f) + + #If (SENSOR_IRGASON) Then + Average (1, RH, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + Average (1, e_sat, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + Average (1, e, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + #If (NOT SENSOR_IRGASON) Then + Average (1, RH, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + Average (1, e_sat, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + Average (1, e, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + + Average (1, amb_press, IEEE4, irga_amb_press_f) + + #If (NOT SENSOR_IRGASON) Then + Average (1, rho_d, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'g/m^3 + Average (1, rho_a, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'kg/m^3 + Average (1, Tc, IEEE4, irga_amb_tmpr_f) + #EndIf + #If (SENSOR_IRGASON) Then + Average (1, rho_d, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'g/m^3 + Average (1, rho_a, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'kg/m^3 + Average (1, Tc, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + +EndTable +'*** End of IRGA constants, variables, and working data table *** + +#If (SENSOR_FW) Then +'*** Beginning of FW constants, variables, and working data table *** +Public time_const_FW = 0.001 'default value (seconds). It will be recalculated inside the program +Units time_const_FW = s + +Public FW +Units FW = C + +'Raw and not lagged FW data. +Dim FW_raw +Dim diag_FW_raw 'Boolean type is not used because this variable is an element of numerical array: dly_data_out() + +Public separation_lat_dist_FW 'effective separation distance in direction normal to wind direction. Used for separation correction. +Public separation_lag_dist_FW 'effective separation distance along wind direction. Used for time lag maximization. +Public separation_lag_scan_FW 'lag in scan number. Wind passing FW after (+) or before (-) passing sonic volume. Not necessary to use an integer. +Units separation_lat_dist_FW = m +Units separation_lag_dist_FW = m +Units separation_lag_scan_FW = scans + +Dim Cov_array_fw(2* MAX_LAG+1, 4) 'Arrays used to hold the FW data with -2, -1, 0, 1, 2 in sacn lags relative to sonic data in order +'to find the max covariance of FW with w using lag_FW found in maximuzation for covariance of FW with w +'In form of array for use in the COVARIANCE instructions. +'Row for lag -2, -1, 0, 1, 2 scans, column: FW, u, v, and w. + +Dim FW_bad_data_flg (2* MAX_LAG + 1) As Boolean + +Dim Cov_out_fw(5*(2*MAX_LAG + 1)) 'FW statistics and FW-related covariance +Alias Cov_out_fw(1) = FW_Avg_b2 'b2 indicates backward 2 scans +Alias Cov_out_fw(2) = FWFW_Cov_lag_b2 +Alias Cov_out_fw(3) = uFW_Cov_lag_b2 +Alias Cov_out_fw(4) = vFW_Cov_lag_b2 +Alias Cov_out_fw(5) = wFW_Cov_lag_b2 +Alias Cov_out_fw(6) = FW_Avg_b1 'b1 indicates backward 1 scan +Alias Cov_out_fw(7) = FWFW_Cov_lag_b1 +Alias Cov_out_fw(8) = uFW_Cov_lag_b1 +Alias Cov_out_fw(9) = vFW_Cov_lag_b1 +Alias Cov_out_fw(10) = wFW_Cov_lag_b1 +Alias Cov_out_fw(11) = FW_Avg_0 '0 indicates neither backward nor forward +Alias Cov_out_fw(12) = FWFW_Cov_lag_0 +Alias Cov_out_fw(13) = uFW_Cov_lag_0 +Alias Cov_out_fw(14) = vFW_Cov_lag_0 +Alias Cov_out_fw(15) = wFW_Cov_lag_0 +Alias Cov_out_fw(16) = FW_Avg_f1 'f1 indicates forward 1 scan +Alias Cov_out_fw(17) = FWFW_Cov_lag_f1 +Alias Cov_out_fw(18) = uFW_Cov_lag_f1 +Alias Cov_out_fw(19) = vFW_Cov_lag_f1 +Alias Cov_out_fw(20) = wFW_cov_lag_f1 +Alias Cov_out_fw(21) = FW_Avg_f2 'f2 indicates forward 2 scans +Alias Cov_out_fw(22) = FWFW_Cov_lag_f2 +Alias Cov_out_fw(23) = uFW_Cov_lag_f2 +Alias Cov_out_fw(24) = vFW_Cov_lag_f2 +Alias Cov_out_fw(25) = wFW_Cov_lag_f2 + +'Variables after coordinate rotations as indicated by "R" +Dim wFW_Cov_lag_R (2*MAX_LAG + 1) 'Used for instruction of MaxSpa +Alias wFW_Cov_lag_R (1) = wFW_Cov_lag_b2R 'b2R indicates backward 2 scans and after-rotation +Alias wFW_Cov_lag_R (2) = wFW_Cov_lag_b1R 'b1R indicates backward 1 scan and after-rotation +Alias wFW_Cov_lag_R (3) = wFW_Cov_lag_0R '0R indicates neither backward nor forward and after-rotation +Alias wFW_Cov_lag_R (4) = wFW_Cov_lag_f1R 'f1R indicates forward 1 scan and after-rotation +Alias wFW_Cov_lag_R (5) = wFW_Cov_lag_f2R 'f2R indicates forward 2 scans and after-rotation +Units wFW_Cov_lag_R = C m/s + +Dim wFW_cov_major_sign 'Summarize the sign of wFW_cov: From above array, chose max if positive (up) and min if negative (down) + +Dim uFW_vFW_Cov_lag_R(2*MAX_LAG + 1, 2) 'Hold the covariance of lagged FW with u or v after coordinate rotation +Alias uFW_vFW_Cov_lag_R(1, 1) = uFW_Cov_lag_b2R 'b2R indicates backward 2 scans and after-rotation +Alias uFW_vFW_Cov_lag_R(1, 2) = vFW_Cov_lag_b2R +Alias uFW_vFW_Cov_lag_R(2, 1) = uFW_Cov_lag_b1R 'b1R indicates backward 1 scan and after-rotation +Alias uFW_vFW_Cov_lag_R(2, 2) = vFW_Cov_lag_b1R +Alias uFW_vFW_Cov_lag_R(3, 1) = uFW_Cov_lag_0R '0R indicates neither backward nor forward and after-rotation +Alias uFW_vFW_Cov_lag_R(3, 2) = vFW_Cov_lag_0R +Alias uFW_vFW_Cov_lag_R(4, 1) = uFw_Cov_lag_f1R 'f1R indicates forward 1 scan and after-rotation +Alias uFW_vFW_Cov_lag_R(4, 2) = vFW_Cov_lag_f1R +Alias uFW_vFW_Cov_lag_R(5, 1) = uFw_Cov_lag_f2R 'f2R indicates forward 2 scans and after-rotation +Alias uFW_vFW_Cov_lag_R(5, 2) = vFW_Cov_lag_f2R +Units uFW_vFW_Cov_lag_R = C m/s + +Dim wFW_Cov_lag_max (2) +Alias wFW_Cov_lag_max (1) = wFW_Cov_R 'Max covariance among lagged covariance values in array of wFW_Cov_lag_R() and will be used for sensible heat flux after freq correction +Alias wFW_Cov_lag_max (2) = lag_FW 'Lag in number of scans, also used for sequential number in an array index for lag wFW_Cov_lag_R() and uFW_vFW_cov_lag_R() +Units wFW_Cov_R = C m/s +Units lag_FW = scans + +Dim FW_Avg 'Selected from cov_out_FW() according to lag maximization using lag_FW +Dim FW_Std 'Selected from cov_out_FW() according to lag maximization using lag_FW +Dim UxFW_Cov 'Selected from cov_out_FW() according to lag maximization using lag_FW +Dim UyFW_Cov 'Selected from cov_out_FW() according to lag maximization using lag_FW +Dim UzFW_Cov 'Selected from cov_out_FW() according to lag maximization using lag_FW +Units FW_Avg = C +Units FW_Std = C +Units UxFW_Cov = C m/s +Units UyFW_Cov = C m/s +Units UzFW_Cov = C m/s + +Dim uFW_Cov_R 'Selected from uFW_vFW_cov_lag_R() according to lag maximization using lag_FW +Dim vFW_Cov_R 'Selected from uFW_vFW_cov_lag_R() according to lag maximization using lag_FW +'For "wFW_cov_R", see "wFW_Cov_lag_max (1)" +Units uFW_Cov_R = C m/s +Units vFW_Cov_R = C m/s + +' Variables after coordinate rotations and freq corrections as indicated by "R_F" +Dim wFW_Cov_R_F +Units wFW_Cov_R_F = C m/s + +' Sensible heat flux +Public H_FW 'After coordinate rotations and freq corrections +Units H_FW = W/m^2 + +DataTable (delay_fw, TRUE, (OFFSET + MAX_LAG)) ' + MAX_LAG. Add more records of MAX_LAG for use in finding a lag for FW + TableHide + Sample (1, FW_raw, IEEE4) + Sample (1, diag_FW_raw, IEEE4) +EndTable + +DataTable (comp_cov_fw, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + 'Compute covariance of FW against sonic wind data. + Average (1, Cov_array_fw(1, 1), IEEE4, FW_bad_data_flg(1)) + Covariance (4, Cov_array_fw(1, 1), IEEE4,(sonic_disable_f OR FW_bad_data_flg(1)),4) + Average (1, Cov_array_fw(2, 1), IEEE4, FW_bad_data_flg(2)) + Covariance (4, Cov_array_fw(2, 1), IEEE4,(sonic_disable_f OR FW_bad_data_flg(2)),4) + Average (1, Cov_array_fw(3, 1), IEEE4, FW_bad_data_flg(3)) + Covariance (4, Cov_array_fw(3, 1), IEEE4,(sonic_disable_f OR FW_bad_data_flg(3)),4) + Average (1, Cov_array_fw(4, 1), IEEE4, FW_bad_data_flg(4)) + Covariance (4, Cov_array_fw(4, 1), IEEE4,(sonic_disable_f OR FW_bad_data_flg(4)),4) + Average (1, Cov_array_fw(5, 1), IEEE4, FW_bad_data_flg(5)) + Covariance (4, Cov_array_fw(5, 1), IEEE4,(sonic_disable_f OR FW_bad_data_flg(5)),4) +EndTable +#EndIf +#If (SENSOR_TMPR_RH) Then + +'*** Beginning of temperature and humidity probe constants, variables, and working data table. *** +Public tmpr_rh(3) +Alias tmpr_rh(1) = T_probe 'Temperature/humidity probe: temperature +Alias tmpr_rh(2) = RH_probe 'Temperature/humidity probe: relative humidity +Alias tmpr_rh(3) = e_probe 'Temperature/humidity probe: vapor pressure +Units T_probe = C +Units RH_probe = percent +Units e_probe = kPa + +Dim e_sat_probe 'Temperature/humidity probe: saturation vapor pressure +Public Td_probe +Units Td_probe = C +Dim Enhance_factor1_probe 'Temperature/humidity probe: Intermediate variable for calculation of dew point temperature +Dim Enhance_factor2_probe 'Temperature/humidity probe: Intermediate variable for calculation of dew point temperature +Dim x_tmp_probe 'Temperature/humidity probe: Intermediate variable for calculation of dew point temperature +Dim Td_gu_probe 'Temperature/humidity probe: Intermediate variable for calculation of dew point temperature + +Dim rho_d_probe_Avg 'Density of dry air calculated using the data from temperature and humidity probe +Units rho_d_probe_Avg = kg/m^3 + +Dim stats_out_tmpr_rh(6) 'Temperature/humidity probe: statistics +Alias stats_out_tmpr_rh(1) = T_probe_Avg 'Average temperature from temperature/humidity probe +Alias stats_out_tmpr_rh(2) = e_probe_Avg 'Average vapor pressure from temperature/humidity probe +Alias stats_out_tmpr_rh(3) = e_sat_probe_Avg 'Average saturation vapor pressure from temperature/humidity probe +Alias stats_out_tmpr_rh(4) = H2O_probe_Avg 'Average vapor density temperature/humidity probe +Alias stats_out_tmpr_rh(5) = RH_probe_Avg 'Average relative humidity temperature/humidity probe +Alias stats_out_tmpr_rh(6) = rho_a_probe_Avg 'Average air density measured using Temperature/humidity probe +Units T_probe_Avg = C +Units e_probe_Avg = kPa +Units e_sat_probe_Avg = kPa +Units H2O_probe_Avg = g/m^3 +Units RH_probe_Avg = % +Units rho_a_probe_Avg = kg/m^3 + +DataTable (stats_tmpr_rh,TRUE,1) + TableHide + DataInterval (0,OUTPUT_INTERVAL,Min,1) + + Average (1, T_probe, IEEE4, slowsequence_disable_flg) + Average (1, e_probe, IEEE4, slowsequence_disable_flg) + Average (1, e_sat_probe, IEEE4, slowsequence_disable_flg) +EndTable +'*** End of temperature and humidity probe constants, variables, and working data table *** +#EndIf +#If (SENSOR_TE525mm) Then + +'*** Beginning of TE525mm constants and variables *** +Public Precipitation +Units Precipitation = mm +'*** End of TE525mm constants and variables *** +#EndIf +#If (SENSOR_Rn) Then + +'*** Beginning of net radiometer constants and variables *** +Public Rn_raw 'Net radiation: Measured time series data + +Public Rn 'Net radation: mean over an averaging interval +Units Rn = W/m^2 + +#If (SENSOR_NR_LITE) Then + +'*** Beginning of NR Lite constants and variables *** +Const NMBR_WND_SAMPLES = 3000/SCAN_INTERVAL 'Number of measurements to compute a three second mean of horizontal wind to correct measured Rn_meas as Rn +Public Rn_meas 'Measured Rn that is not corrected by horizontal wind speed +Units Rn_meas = W/m^2 + +Dim hor_wind_raw 'Used for running average for hor_wind +Dim hor_wind 'Running average of hor_wind_raw over three seconds of hor_wind_raw +Dim hor_wind_diag 'Diagnosis code: non-zero if any of recent sonic_irga_raw(5) last 30 second +'*** End of NR Lite constants and variables *** +#EndIf +#If ((SENSOR_NR01) OR (SENSOR_CNR4)) Then + +'*** Beginning of 4-way net radiometer constants and variables **** +Public nr(8) 'Radiation components measured from a 4-way net radiometer. +Alias nr(1) = albedo +Alias nr(2) = R_SW_in 'Incoming (downwelling) short wave radiation +Alias nr(3) = R_SW_out 'Outgoing (upwelling) short wave radiation +Alias nr(4) = R_LW_in 'Incoming (downwelling) long wave radiation +Alias nr(5) = R_LW_out 'Outgoing (upwelling) long wave radiation +Alias nr(6) = T_nr 'Sensor body temperature +Alias nr(7) = R_LW_in_meas 'Measured signal of incoming (downwelling) long wave radiation +Alias nr(8) = R_LW_out_meas 'Measured signal of outgoing (upwelling) long wave radiation +Units albedo = unitless +Units R_SW_in = W/m^2 +Units R_SW_out = W/m^2 +Units R_LW_in = W/m^2 +Units R_LW_out = W/m^2 +Units T_nr = Klvin +Units R_LW_in_meas = W/m^2 +Units R_LW_out_meas = W/m^2 +'*** End of NR01/CNR4 constants and variables *** + +#If (SENSOR_CNR4) Then + +'YSI 44031 Steinhart-Hart coefficients fit through -40 degrees C (239800 ohms), 20 degrees C (12260 ohms), and 80 degrees C (1458 ohms). +Const A_SHH = 1.0295e-3 'Steinhart-Hart A coefficient (from Kipp & Znen through email April 16 2015). +Const B_SHH = 2.3910e-4 'Steinhart-Hart B coefficient (from Kipp & Znen through email April 16 2015). +Const C_SHH = 1.5680e-7 'Steinhart-Hart C coefficient (from Kipp & Znen through email April 16 2015). +Dim X_cnr4 +Dim ln_R +#EndIf + +'*** End of 4-way net radiometer constants and variables **** +#EndIf + +DataTable (stats_net_radiation, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + Average (1, Rn_raw, IEEE4, slowsequence_disable_flg) +EndTable +'*** End of net radiometer constants and variables *** +#EndIf +#If (SENSOR_HFP) Then + +' *** Beginning of HFP01 or HFP01SC constants and variables *** +Dim shf_plate_cal(NMBR_SHFP) 'Hold calibiration of soil heat flux plates + +Public shf_plate(NMBR_SHFP) 'Soil heat flux through soil heat flux plates +Units shf_plate = W/m^2 + +Public shf_plate_avg(NMBR_SHFP) 'Mean soil heat flux through soil heat flux plates +Units shf_plate_avg = W/m^2 + +#If (SENSOR_HFP01SC) Then +'*** Beginning of HFP01SC constants and variables *** +Const CAL_INTERVAL = 1440 'Unique: HFP01SC insitu calibration interval (minutes). +Const END_CAL = OUTPUT_INTERVAL - 1 'End HFP01SC insitu calibration one minute before the next output. +Dim shf_mV(NMBR_SHFP) 'Voltage measured from soil heat flux plates +Dim shf_mV_run(NMBR_SHFP) 'Running mean of shf_mV +Dim shf_mV_0(NMBR_SHFP) 'Running mean of shf_mV at the beginning of calibration +Dim shf_mV_180(NMBR_SHFP) 'Running mean of shf_mV after 180 seconds since the beginning of calibration +Dim shf_mV_end(NMBR_SHFP) 'Running mean of shf_mV at the end of calibration +Dim V_Rf(NMBR_SHFP) 'Reference voltage +Dim V_Rf_run(NMBR_SHFP) 'Running mean of reference voltage +Dim V_Rf_180(NMBR_SHFP) 'Running mean of reference voltage after 180 seconds since the beginning of calibration +Dim shf_cal_on_f As Boolean +Dim sw12_1_state As Boolean 'State of the switched 12Vdc port 1. +'*** End of HFP01SC constants and variables *** +#EndIf + +DataTable (stats_SHF, TRUE, 1) + TableHide + DataInterval (0, OUTPUT_INTERVAL, Min, 1) + + #If (SENSOR_HFP01) Then + Average (NMBR_SHFP, shf_plate(1), IEEE4, slowsequence_disable_flg) + + #EndIf + #If (SENSOR_HFP01SC) Then + + Average (NMBR_SHFP, shf_plate(1), IEEE4, (shf_cal_on_f OR slowsequence_disable_flg)) + #EndIf + +EndTable +' *** End of HFP01 or HFP01SC constants and variables *** +#EndIf + +#If (SENSOR_TCAV) Then + +'*** Beginning of TCAV constants and variables *** +Public Tsoil(NMBR_TCAV) 'TCAV soil temperature. +Units Tsoil = C +'*** End of TCAV constants and variables *** +#EndIf +#If (SENSOR_CS616) Then + +'*** Beginning of CS616 constants and variables *** +Public cs616_wcr(NMBR_CS6xx) 'Water content reflectometer period. +Units cs616_wcr = uSeconds + +#If ((SENSOR_CS616) AND (NOT SENSOR_TCAV)) Then +Public soil_wtr(NMBR_CS6xx) 'Volumetric soil water content without temperature correction. +Units soil_wtr = frac_v_wtr +#EndIf + +#If ((SENSOR_CS616) AND (SENSOR_TCAV)) Then +Dim Tsoil_for_CS616_correct(NMBR_CS6xx) 'Soil temperature used for CS616 temperature correction. This variable is defined in case: NMBR_TCAV <> NMBR_CS6xx +Dim cs616_T(NMBR_CS6xx) 'Water content reflectometer period with temperature correction. + +Public soil_wtr_T(NMBR_CS6xx) 'Volumetric soil water content with temperature correction. +Units soil_wtr_T = frac_v_wtr +#EndIf +'*** End of CS616 constants and variables *** +#EndIf +#If (SENSOR_CS65X) Then + +'*** Beginning of CS65X constants and variables *** +Public cs65x_wc(NMBR_CS6xx) 'Volumetric soil water content. +Public cs65x_ec(NMBR_CS6xx) 'Electrical conductivity. +Public cs65x_tmpr(NMBR_CS6xx) 'CS65X probe temperature. +Dim cs65x_raw(3) 'Hold CS65X raw variables +Units cs65x_wc = frac_v_wtr +Units cs65x_ec = dS/m +Units cs65x_tmpr = C +'*** End of CS65X constants and variables *** +#EndIf +#If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + +'*** Beginning of variables for calculation of soil heat flux at soil surface *** +Const NMBR_SOIL_T_WTR_DEL_SAMPLES = (60*1000)/SLOWSEQUENCE_SCAN_INTERVAL 'Unique: Number of measurements to compute a one-minute mean of soil temperature and water + +Public G_surface 'Soil heat flux at the ground surface +Units G_surface = W/m^2 + +'Use to calculate the change in heat storage in soil +Public Tsoil_prev_Avg = NaN 'Tsoil mean of last one-minute measurements in the previous averaging interval + +Dim Tsoil_current (2) 'Indididual Tsoil means of last one-minute measurements in the current averaging interval +Public Tsoil_current_Avg + +Public soil_wtr_prev_Avg = NaN 'soil_wtr_T mean of last one-minute measurements in the previous averaging interval +Dim soil_wtr_current (NMBR_CS6xx) 'soil_wtr_T mean of last one-minute measurements in the current averaging interval +Public soil_wtr_current_Avg +' Notes for NaN : After compiling, Tsoil_prev_avg and soil_wtr_prev_Avg will be NaN but will be replaced with the current measured +' values. On subsequent averaging intervals, *_prev_Avg will be taken from the mean of the last minute of the previous averaging interval. + +Public Delta_soil_ht_storage 'Increment in heat storage above soil heat flux plates over an averaging interval +Units Delta_soil_ht_storage = W/m^2 + +' Variables used to calculate the number of seconds from the beginning of the program to the end of the first averaging interval (time interval offset) +Dim realtime_array(9) 'Hold real time data +Dim Offset_intv_Delta_ht_storage 'time interval offset +'*** End of variables for calculation of soil heat flux at soil surface *** +#EndIf +#If ((SENSOR_Rn) AND (SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + +'*** Beginning of energy balance constants and variables *** +Public energy_closure '(LE + H)/(Rn-G_surface) +Units energy_closure = Fraction +'*** End of energy balance constants and variables *** + +#EndIf +#If (SENSOR_LI200X) OR (SENSOR_CS300) Then + +'*** Beginning of Pyranometer constants and variables *** +Public R_pyran +Units R_pyran = W/m^2 +'*** End of pyranometer constants and variables *** +#EndIf +#If (SENSOR_LI190SB) Then + +'*** Beginning of quntum constants and variables *** +Public PAR_density +Units PAR_density = umol/(s m^2) +'*** End of quantum constants and variables *** +#EndIf +#If (SENSOR_SI111) Then + +'*** Beginning of infrared radiometer constants and variables *** +Public T_SI111_targeted 'Temperature of surface that SI111 targets +Public T_SI111_body 'Temperature of SI111 sensor body +Units T_SI111_targeted = C +Units T_SI111_body = C + +Dim m_SI111, b_SI111 'Multipler and offset in equation to calculate temperature of targeted surface using measured voltage and SI111 body temperature +'*** End of infrared radiometer constants and variables *** +#EndIf + +'*** Beginning display menu *** +DisplayMenu ("System Control", TRUE) + SubMenu ("Station variables") + MenuItem ("Surf type", surface_type) + MenuPick (CROP, GRASS, FOREST, SHRUB, BARELAND, WATER) + MenuItem ("d, 0 = auto", displacement_user) 'if 0, zero displacement is automatically calculated in the program + MenuItem ("z0,0 = auto", roughness_user) 'if 0, roughness length is automatically calculated in the program + MenuItem ("Meas height", height_measurement) + MenuItem ("Canopy height", height_canopy) + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + MenuItem ("Bulk density", soil_bulk_density) + MenuItem ("C_dry_soil", Cds) + MenuItem ("HFP depth", thick_abv_SHFP) + #EndIf + + MenuItem ("IRGA Coord x", separation_x_irga) + MenuItem ("IRGA Coord y", separation_y_irga) + + #If (SENSOR_FW) Then + MenuItem ("FW Coord x", separation_x_FW) + MenuItem ("FW Coord y", separation_y_FW) + MenuItem ("FW Dim", FW_diameter) + MenuPick (FW05DIA, FW1_DIA, FW3_DIA) + #EndIf + + MenuItem ("Sonic Azmth", sonic_azimuth) + MenuItem ("Latitude", latitude) + MenuItem ("Hemisph_Eq", hemisphere_NS) + MenuPick (Hemisphere_North, Hemisphere_South) + MenuItem ("Longitude", longitude) + MenuItem ("Hemisph_Me", hemisphere_EW) + MenuPick (Hemisphere_East, Hemisphere_West) + + SubMenu ("Planar Fit Alpha") + MenuItem ("<=60 or >=300", alpha_PF_60_300) 'Angle in sonic coordinate system + MenuItem (">60 & <=170", alpha_PF_60_170) + MenuItem (">170 & <190", alpha_PF_170_190) + MenuItem (">=190 & <300", alpha_PF_190_300) + EndSubMenu + + SubMenu ("Planar Fit Beta") + MenuItem ("<=60 or >=300", beta_PF_60_300) + MenuItem (">60 & <=170", beta_PF_60_170) + MenuItem (">170 & <190", beta_PF_170_190) + MenuItem (">=190 & <300", beta_PF_190_300) + EndSubMenu + + SubMenu ("Footprint Dis Intrst") + MenuItem ("<=60 or >=300", dist_intrst_60_300) + MenuItem (">60 & <=170", dist_intrst_60_170) + MenuItem (">170 & <190", dist_intrst_170_190) + MenuItem (">=190 & <300", dist_intrst_190_300) + EndSubMenu + + SubMenu ("Change Press Source") + MenuItem ("Select Srce", press_source) + MenuPick (BB, EB) + MenuItem ("Set Source", set_press_source_flg) + MenuPick (TRUE, FALSE) + EndSubMenu + EndSubMenu + + SubMenu ("On-Site Zero & Span") + SubMenu ("Span Concentrations") + MenuItem ("CO2",CO2_span_gas) + MenuItem ("Td", Td_span_gas) + EndSubMenu + + MenuItem ("Do Zero", do_zero_flg) + MenuPick (TRUE, FALSE) + MenuItem ("Do CO2 Span", do_CO2_span_flg) + MenuPick (TRUE, FALSE) + MenuItem ("Do H2O Span", do_H2O_span_flg) + MenuPick (TRUE, FALSE) + DisplayValue ("CO2_mixratio", CO2_mixratio) + DisplayValue ("H2O_mixratio", H2O_mixratio) + DisplayValue ("Td deg C", Td) + #If (SENSOR_TMPR_RH) Then + DisplayValue ("Td_probe deg C", Td_probe) + #EndIf + + EndSubMenu +EndMenu +'*** End of display menu *** + +'**************************' +'*** OUTPUT DATA TABLES ***' +'**************************' + +Const ONE_FULL_TABLE = FALSE 'Unique: TRUE if all hourly or half-hourly data are stored in one table +' FALSE if hourly or half-hourly variables for direct use are stored in Flux table and the variables for later reference are stored in Flux_Notes + +DataTable (Flux, TRUE, FLUX_SIZE_CPU) + DataInterval (0, OUTPUT_INTERVAL, Min, 10) + TableFile ("CRD:"&Status.SerialNumber(1,1)&".Flux_", 64, -1, 0, NMBR_DAY_FLUX_CRD, Day, 0, 0) + + '**** Beginning of flux and quality classification data *** + Sample (1, Fc_molar, IEEE4) 'Carbon dioxide flux in umol/(m^2 s) after coordinate rotations, freq corrections, and WPL correction + Sample (1, Fc_mass, IEEE4) 'Carbon dioxide flux in mg/(m^2 s) after coordinate rotations, freq corrections, and WPL correction + Sample (1, Fc_qc_grade, UINT2) 'Overall grade of data quality for carbon dioxide flux (i.e. for variables: Fc_molar and Fc_mass) + Totalize (1, n, IEEE4, (sonic_disable_f OR irga_disable_f OR CO2_bad_rng_sig_array(MAX_LAG +1))) 'Totalize the number of samples for CO2 flux + FieldNames ("Fc_samples_Tot") + Sample (1, LE, IEEE4) 'Latent heat flux after coordinate rotations, freq corrections, and WPL correction + Sample (1, LE_qc_grade, UINT2) 'Overall grade of data quality for latent heat flux (i.e. for variable: LE) + Totalize (1, n, IEEE4, (sonic_disable_f OR irga_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'Totalize the number of samples for latent heat flux + FieldNames ("LE_samples_Tot") + Sample (1, H, IEEE4) 'Sensible heat flux (derived from sonic heat flux with SND correction after coordinate rotations and freq corrections) + Sample (1, H_qc_grade, UINT2) 'Overall grade of data quality for for sensible heat flux (i.e. for variable: H) + Totalize (1, n, IEEE4, (sonic_disable_f OR irga_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) 'Totalize the number of samples for sensible heat flux + FieldNames ("H_samples_Tot") + + #If (SENSOR_FW) Then + Sample (1, H_FW, IEEE4) 'Sensible heat flux measured using fine wire thermocouple (FW) after coordinate rotations and freq corrections + Totalize (1, n, IEEE4, (sonic_disable_f OR FW_bad_data_flg)) 'Totalize the number of samples for FW-measured sensible heat flux + FieldNames ("H_FW_samples_Tot") + #EndIf + + #If (SENSOR_Rn) Then + + '*** Beginning of net radiometer output data *** + Sample (1, Rn, IEEE4) + '*** End of net radiomete output data *** + #EndIf + #If ((SENSOR_HFP) AND (SENSOR_CS6XX)) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + + Sample (1, G_surface, IEEE4) 'Soil heat flux at the ground surface + #EndIf + #If ((SENSOR_Rn) AND (SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + + Sample (1, energy_closure,IEEE4) 'Energy closure + #EndIf + + Sample (1, Bowen_ratio, IEEE4) + Sample (1, tau, IEEE4) 'Momentum flux after coordinate rotations and freq corrections, + Sample (1, tau_qc_grade, UINT2) 'Overall grade of data quality for momentum flux (i.e. for variable: tau) + + '*** Turbulence characteristic variables **** + Sample (1, u_star, IEEE4) 'Friction velocity after coordinate rotations and freq corrections + Sample (1, T_star, IEEE4) 'Scaling temperature after coordinate rotations and freq corrections + Sample (1, TKE, IEEE4) 'Specific turbulence kinetic enegrgy after coordinate rotations + Sample (1, amb_tmpr_Avg, IEEE4) 'Air temperature from EC100 temperature probe + #If (SENSOR_IRGASON) Then + Sample (1, Tc_Avg, IEEE4) 'air temperature calculated from IRASON measurements of sonic temperature, water vapor density, and pressure + Average(1, Td, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + + #If (NOT SENSOR_IRGASON) Then + Average (1, Td, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + + Sample (1, RH_Avg, IEEE4) 'Calculated from Tc and H2O if IRGASON and from amb_tmpr_Avg and H2O if CSAT3A + EC150. + Sample (3, e_sat_Avg, IEEE4) 'e_sat_Avg, e_Avg, and amb_press_Avg + Sample (1, VPD_air, IEEE4) 'Air vapor pressure deficit + + '*** Beginning of sonic head output data *** + '** Before coordinate rotation + Sample (2, Ux_Avg, IEEE4) 'Ux_avg and Ux_Std + Sample (2, Uy_Avg, IEEE4) 'Uy_avg and Uy_Std + Sample (2, Uz_Avg, IEEE4) 'Uz_avg and Uz_Std + Sample (2, Ts_Avg, IEEE4) 'Ts_avg and Ts_Std + Sample (1, sonic_azimuth, IEEE4) 'Sonic_azimuth, (see Section 3.2.1 CSAT3A Azimuth in the OPEC manual). + Sample (5, wnd_spd, IEEE4) 'The last 5 elements in array of cov_out_sonic. + Sample (1, CO2_molfrac_Avg, IEEE4) 'CO2 mole fraction + + #If (SENSOR_IRGASON) Then + Average(1, CO2_mixratio, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + + #If (NOT SENSOR_IRGASON) Then + Average(1, CO2_mixratio, IEEE4, (irga_disable_f)) + #EndIf + Sample (2, CO2_Avg, IEEE4) 'CO2 mass density, CO2_Avg and CO2_Std + Sample (1, H2O_molfrac_Avg, IEEE4) 'H2O mole fraction + + #If (SENSOR_IRGASON) Then + Average(1, H2O_mixratio, IEEE4, (irga_disable_f OR sonic_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + + #If (NOT SENSOR_IRGASON) Then + Average(1, H2O_mixratio, IEEE4, (irga_disable_f OR irga_amb_tmpr_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + #EndIf + Sample (2, H2O_Avg, IEEE4) 'H2O mass density: H2O_Avg and H2O_Std + + Minimum (1, CO2_sig_strgth, IEEE4, irga_disable_f, FALSE) + FieldNames ("CO2_sig_strgth_Min") + + Minimum (1, H2O_sig_strgth, IEEE4, irga_disable_f, FALSE) + FieldNames ("H2O_sig_strgth_Min") + + #If (SENSOR_FW) Then + '*** Beginning of FW output data *** + '** Before coordinate rotation + Sample (1, FW_Avg, IEEE4) + Sample (1, FW_Std, IEEE4) + #EndIf + #If (SENSOR_TMPR_RH) Then + + '*** Beginning of temperature and humidity probe output data *** + Sample (3, T_probe_Avg, IEEE4) 'Measured from temperaure and humidity probe: T_probe_Avg, e_probe_Avg, and e_sat_probe_Avg + Average (1, Td_probe, IEEE4, slowsequence_disable_flg) 'Measured from temperaure and humidity probe: dew point temperaure + Sample (3, H2O_probe_Avg, IEEE4) 'Measured from temperaure and humidity probe: H2O_probe_Avg, RH_probe_Avg, and rho_a_probe_Avg + Sample (1, rho_d_probe_Avg, IEEE4) 'Measured from temperaure and humidity probe: dry air density in kg/m^3 + '*** End of temperature and humidity probe output data *** + #EndIf + #If (SENSOR_TE525mm) Then + + '*** Beginning of rain gauge output data *** + Totalize (1, Precipitation, FP2, 0) + '*** End of rain gauge output data *** + #EndIf + #If (SENSOR_NR_LITE) Then + + Average (1, Rn_meas, IEEE4, slowsequence_disable_flg) + #EndIf + #If ((SENSOR_NR01) OR (SENSOR_CNR4)) Then + + '*** Beginning of 4-way radiometer output data *** + Average (8, albedo, IEEE4, slowsequence_disable_flg) 'albedo, R_SW_in, R_SW_out, R_SW_in, R_SW_out, T_nr, R_LW_in_meas, and R_LW_out_meas + '*** End of 4-way radiometer output data *** + + #EndIf + #If (SENSOR_LI200X) OR (SENSOR_CS300) Then + + '*** Beginning of LI200X output data *** + Average (1, R_pyran, IEEE4, slowsequence_disable_flg) + '*** End of LI200X output data *** + #EndIf + #If (SENSOR_LI190SB) Then + + '*** Beginning of LI190SB output data *** + Average (1, PAR_density, IEEE4, slowsequence_disable_flg) + '*** End of LI190SB output data *** + #EndIf + #If (SENSOR_SI111) Then + + '*** Beginning of LI190SB output data *** + Average (1, T_SI111_targeted, IEEE4, slowsequence_disable_flg) + Average (1, T_SI111_body, IEEE4, slowsequence_disable_flg) + '*** End of LI190SB output data *** + #EndIf + #If (SENSOR_TCAV) Then + + '*** Beginning of TCAV output data *** + Average (NMBR_TCAV, Tsoil(1), IEEE4, slowsequence_disable_flg) + '*** End of TCAV output data *** + + #EndIf + #If (SENSOR_CS616) Then + + '*** Beginning of CS616 output data *** + #If ((SENSOR_CS616) AND (SENSOR_TCAV)) Then + Average (NMBR_CS6xx, soil_wtr_T(1), IEEE4, slowsequence_disable_flg) 'Volumetric soil water w/ temperature correction + #EndIf + + #If ((SENSOR_CS616)) AND (NOT SENSOR_TCAV) Then + Average (NMBR_CS6xx, soil_wtr(1), IEEE4, slowsequence_disable_flg) 'Volumetric soil water w/o temperature correction + #EndIf + + Average (NMBR_CS6xx, cs616_wcr(1), IEEE4, slowsequence_disable_flg) 'CS616 period. + '*** End of CS616 output data *** + + #EndIf + #If (SENSOR_CS65X) Then + + '*** Beginning of CS65X output data *** + Average (NMBR_CS6xx, cs65x_wc(1), IEEE4, slowsequence_disable_flg) 'Volumetric soil water content. + Average (NMBR_CS6xx, cs65x_ec(1), IEEE4, slowsequence_disable_flg) 'Electrical conductivity. + Average (NMBR_CS6xx, cs65x_tmpr(1),IEEE4, slowsequence_disable_flg) 'CS65X probe temperature. + '*** End of CS65X output data *** + #EndIf + #If (SENSOR_HFP) Then + + '*** Beginning of HFP01 output data *** + Sample (NMBR_SHFP, shf_plate_avg(1), IEEE4) 'Heat flux through a soil heat flux plate + '*** End of HFP01 output data *** + #EndIf + #If (SENSOR_HFP01SC) Then + + '*** Beginning of HFP01SC output data *** + Sample (NMBR_SHFP, shf_plate_cal(1), IEEE4) 'Calibrations of self-calibrated soil heat flux plate + '*** End of HFP01SC output data *** + #EndIf + + '*** Footprint characteristics **** + Sample (1, upwnd_dist_intrst, IEEE4) 'User-entered upwind distance of interest for the average upwind direction in this averaging interval + Sample (1, FP_dist_intrst, IEEE4) 'Percentage of measured scalar flux from upwind range of interest + Sample (1, FP_max, IEEE4) 'Upwind location of source/sink that contributes most to the measured flux + Sample (1, FP_40, IEEE4) 'Upwind range within which sources/sinks contributes 40% the measured flux + Sample (1, FP_55, IEEE4) 'Upwind range within which sources/sinks contributes 55% the measured flux + Sample (1, FP_90, IEEE4) 'Upwind range within which sources/sinks contributes 90% the measured flux + Sample (1, FP_Equation, String) 'Type of footprint equation: Kljun et al or KormannMeixner + + #If (NOT (ONE_FULL_TABLE)) Then +EndTable +'*** End of FLUX Table **** + +'*** Beginning of FLUX_NOTES Table ***** +DataTable (Flux_Notes, TRUE, FLUX_SIZE_CPU) + DataInterval (0, OUTPUT_INTERVAL, Min, 10) + TableFile ("CRD:"&Status.SerialNumber(1,1)&".Flux_NOTES_", 64, -1, 0,NMBR_DAY_FLUX_CRD, Day, 0, 0) + #EndIf + + '*** Beginning of sonic head output data *** + '** Before coordinate rotation + Sample (2, UxUy_Cov, IEEE4) 'UxUy_Cov and UxUz_Cov. + Sample (1, UyUz_Cov, IEEE4) + Sample (3, TsUx_Cov, IEEE4) 'TsUx_Cov, TsUy_Cov, and TsUz_Cov + + '** _R indicates after coordinate rotations + Sample (1, u_star_R, IEEE4) 'Friction velocity after coordinate rotations. + Sample (1, u_Avg_R, IEEE4) + Sample (1, u_Std_R, IEEE4) + Sample (1, v_Avg_R, IEEE4) + Sample (1, v_Std_R, IEEE4) + Sample (1, w_Avg_R, IEEE4) + Sample (1, w_Std_R, IEEE4) + Sample (1, uv_Cov_R, IEEE4) + Sample (1, uw_Cov_R, IEEE4) + Sample (1, vw_Cov_R, IEEE4) + Sample (1, uTs_Cov_R, IEEE4) + Sample (1, vTs_Cov_R, IEEE4) + Sample (1, wTs_Cov_R, IEEE4) + + '*** _F indicates after frequency corrections + Sample (1, uw_Cov_R_F, IEEE4) + Sample (1, vw_Cov_R_F, IEEE4) + Sample (1, wTs_Cov_R_F, IEEE4) + + '** After coordinate rotations, freq corrections, and SND correction as indicated by R_F_SND. + Sample (1, wTs_Cov_R_F_SND, IEEE4) + + '** Summary of diagnosis flags of sonic + Totalize (1, n, IEEE4, sonic_disable_f) 'Totalize the number of sonic samples without diagnostic flags + FieldNames ("sonic_samples_Tot") + Totalize (1, n, IEEE4, diag_sonic <> -1) + FieldNames ("no_sonic_head_Tot") + Totalize (1, n, IEEE4, diag_sonic <> NAN) + FieldNames ("no_new_sonic_data_Tot") + Totalize (1, n, IEEE4, sonic_amp_l_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_amp_l_f_Tot") + Totalize (1, n, IEEE4, sonic_amp_h_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_amp_h_f_Tot") + Totalize (1, n, IEEE4, sonic_sig_lck_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_sig_lck_f_Tot") + Totalize (1, n, IEEE4, sonic_del_T_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_del_T_f_Tot") + Totalize (1, n, IEEE4, sonic_aq_sig_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_aq_sig_f_Tot") + Totalize (1, n, IEEE4, sonic_cal_err_f IMP (diag_sonic = NAN)) + FieldNames ("sonic_cal_err_f_Tot") + '*** End of sonic head output data *** + + '*** Beginning of IRGA output data *** + '** Before coordinate rotation + Sample (3, UxCO2_Cov, IEEE4) 'UxCO2_Cov, UyCO2_Cov, UzCO2_Cov + Sample (3, UxH2O_Cov, IEEE4) 'UxH2O_Cov, UyH2O_Cov, UzH2O_Cov + + '** _R indicates after coordinate rotations + Sample (1, uCO2_Cov_R, IEEE4) + Sample (1, vCO2_Cov_R, IEEE4) + Sample (1, wCO2_Cov_R, IEEE4) + + Sample (1, uH2O_Cov_R, IEEE4) + Sample (1, vH2O_Cov_R, IEEE4) + Sample (1, wH2O_Cov_R, IEEE4) + + '*** _R_F indicates after coordinate rotations and frequency corrections + Sample (1, wCO2_Cov_R_F, IEEE4) + Sample (1, wH2O_Cov_R_F, IEEE4) + Sample (1, CO2_E_WPL_R_F, IEEE4) 'CO2 flux, WPL term due to water vapor flux (WPL here denots "WPL term for WPL correction" instead of WPL correction) + Sample (1, CO2_T_WPL_R_F, IEEE4) 'CO2 flux, WPL term due to temperature flux (WPL here denots "WPL term for WPL correction" instead of WPL correction) + Sample (1, H2O_E_WPL_R_F, IEEE4) 'H2O flux, WPL term due to water vapor flux (WPL here denots "WPL term for WPL correction" instead of WPL correction) + Sample (1, H2O_T_WPL_R_F, IEEE4) 'H2O flux, WPL term due to temperature flux (WPL here denots "WPL term for WPL correction" instead of WPL correction) + + '** Summary of diagnosis flags of IRGA + Totalize (1, n, IEEE4, (irga_disable_f OR CO2_bad_rng_sig_array(MAX_LAG +1))) + FieldNames ("CO2_samples_Tot") + Totalize (1, n, IEEE4, (irga_disable_f OR H2O_bad_rng_sig_array(MAX_LAG +1))) + FieldNames ("H2O_samples_Tot") + + Totalize (1, n, IEEE4, diag_irga <> -1) + FieldNames ("no_irga_head_Tot") + Totalize (1, n, IEEE4, diag_irga <> NAN) + FieldNames ("no_new_irga_data_Tot") + Totalize (1, n, IEEE4, irga_bad_data_f IMP (diag_irga = NAN)) + FieldNames ("irga_bad_data_f_Tot") + Totalize (1, n, IEEE4, irga_gen_fault_f IMP (diag_irga = NAN)) + FieldNames ("irga_gen_fault_f_Tot") + Totalize (1, n, IEEE4, irga_startup_f IMP (diag_irga = NAN)) + FieldNames ("irga_startup_f_Tot") + Totalize (1, n, IEEE4, irga_motor_spd_f IMP (diag_irga = NAN)) + FieldNames ("irga_motor_spd_f_Tot") + Totalize (1, n, IEEE4, irga_tec_tmpr_f IMP (diag_irga = NAN)) + FieldNames ("irga_tec_tmpr_f_Tot") + Totalize (1, n, IEEE4, irga_src_pwr_f IMP (diag_irga = NAN)) + FieldNames ("irga_src_pwr_f_Tot") + Totalize (1, n, IEEE4, irga_src_tmpr_f IMP (diag_irga = NAN)) + FieldNames ("irga_src_tmpr_f_Tot") + Totalize (1, n, IEEE4, irga_src_curr_f IMP (diag_irga = NAN)) + FieldNames ("irga_src_curr_f_Tot") + Totalize (1, n, IEEE4, irga_off_f IMP (diag_irga = NAN)) + FieldNames ("irga_off_f_Tot") + Totalize (1, n, IEEE4, irga_sync_f IMP (diag_irga = NAN)) + FieldNames ("irga_sync_f_Tot") + Totalize (1, n, IEEE4, irga_amb_tmpr_f IMP (diag_irga = NAN)) + FieldNames ("irga_amb_tmpr_f_Tot") + Totalize (1, n, IEEE4, irga_amb_press_f IMP (diag_irga = NAN)) + FieldNames ("irga_amb_press_f_Tot") + Totalize (1, n, IEEE4, irga_CO2_I_f IMP (diag_irga = NAN)) + FieldNames ("irga_CO2_I_f_Tot") + Totalize (1, n, IEEE4, irga_CO2_Io_f IMP (diag_irga = NAN)) + FieldNames ("irga_CO2_Io_f_Tot") + Totalize (1, n, IEEE4, irga_H2O_I_f IMP (diag_irga = NAN)) + FieldNames ("irga_H2O_I_f_Tot") + Totalize (1, n, IEEE4, irga_H2O_Io_f IMP (diag_irga = NAN)) + FieldNames ("irga_H2O_Io_f_Tot") + Totalize (1, n, IEEE4, irga_CO2_Io_var_f IMP (diag_irga = NAN)) + FieldNames ("irga_CO2_Io_var_f_Tot") + Totalize (1, n, IEEE4, irga_H2O_Io_var_f IMP (diag_irga = NAN)) + FieldNames ("irga_H2O_Io_var_f_Tot") + Totalize (1, n, IEEE4, irga_CO2_sig_strgth_f IMP (diag_irga = NAN)) + FieldNames ("irga_CO2_sig_strgth_f_Tot") + Totalize (1, n, IEEE4, irga_H2O_sig_strgth_f IMP (diag_irga = NAN)) + FieldNames ("irga_H2O_sig_strgth_f_Tot") + Totalize (1, n, IEEE4, irga_cal_err_f IMP (diag_irga = NAN)) + FieldNames ("irga_cal_err_f_Tot") + Totalize (1, n, IEEE4, irga_htr_ctrl_off_f IMP (diag_irga = NAN)) + FieldNames ("irga_htr_ctrl_off_f_Tot") + + '*** End of IRGA output data *** + + #If (SENSOR_FW) Then + '*** Beginning of FW output data *** + '** Before coordinate rotation + Sample (1, UxFW_Cov, IEEE4) + Sample (1, UyFW_Cov, IEEE4) + Sample (1, UzFW_Cov, IEEE4) + + '** _R indocates after coordinate rotations + Sample (1, uFW_Cov_R, IEEE4) + Sample (1, vFW_Cov_R, IEEE4) + Sample (1, wFW_Cov_R, IEEE4) + + ' ** _R_F indicates after coordinate rotations and freq corrections + Sample (1, wFW_Cov_R_F, IEEE4) + + Totalize (1, n, IEEE4, FW_bad_data_flg) + FieldNames ("FW_samples_Tot") + '*** End of FW output data *** + #EndIf + + ' *** Variables used for correction *** + '** Rotation-related variables + Sample (1, alpha, IEEE4) 'Pitch angle + Sample (1, beta, IEEE4) 'Roll angle + Sample (1, gamma, IEEE4) 'Yaw angle + + '** Stability-related variables + Sample (1, height_measurement, IEEE4) 'Measurement height (m) + Sample (1, height_canopy, IEEE4) 'Canopy height (m). + Sample (1, surface_type_text, String) 'Crop, Grass, Forest, Shrub, Bare Land, Water + Sample (1, displacement_user, IEEE4) 'Displacement height input by a user (0 is fefault and d is auto calculated and is used) + Sample (1, d, IEEE4) 'Displacement height used by program d = displacement_user if displacement_user <> 0; otherwise, it is auto calculated + Sample (1, roughness_user, IEEE4) 'Roughness length input by a user (0 is fefault and z0 is auto calculated and is used) + Sample (1, z0, IEEE4) 'Roughness length used by program z0 = displacement_user if roughness_user <> 0; otherwise, it is auto calculated + Sample (1, z, IEEE4) 'Aerodynamic height + Sample (1, L, IEEE4) 'Obukhov length + Sample (1, stability_zL, IEEE4) 'Atmospheric boundary-layer stability. + Sample (1, iteration_FreqFactor, UINT2) 'Iteration number in calculation of freq correction factor for u'w', v'w', and Ts'w' + Sample (1, latitude, IEEE4) + Sample (1, longitude, IEEE4) + + '** Freq correction related variables + ' IRGA separation variables + Sample (2, separation_x_irga, IEEE4) 'The 11st to 12nd elements of stn_conf_array: separation_x_irga, separation_y_irga + Sample (1, separation_lat_dist_irga, IEEE4) 'Separation distance in direction normal to wind direction. Used for separation correction + Sample (1, separation_lag_dist_irga, IEEE4) 'Separation distance along wind direction. Used for lag maximization + Sample (1, separation_lag_scan_irga, IEEE4) 'Lag in scan number as the wind passes IRGA after passing the sonic volume. Not neccessary to use integer. + + #If (SENSOR_FW) Then + Sample (3, separation_x_FW, IEEE4) 'The 17th, 18th, and 19th elements of stn_conf_array: separation_x_FW, separation_y_FW, and FW_diameter + Sample (1, separation_lat_dist_FW, IEEE4) 'Separation distance in direction normal to wind direction. Used for separation correction + Sample (1, separation_lag_dist_FW, IEEE4) 'Separation distance along wind direction. Used for lag maximization + Sample (1, separation_lag_scan_FW, IEEE4) 'Lag in scan number the wind passes FW after passing the sonic volume. Not neccessary to use integer. + Sample (1, time_const_FW, IEEE4) + #EndIf + + Sample (1, MAX_LAG, UINT2) + FieldNames ("MAX_LAG") + Sample (1, lag_irga, IEEE4) + + #If (SENSOR_FW) Then + Sample (1, lag_FW, IEEE4) + #EndIf + + Sample (1, FreqFactor_uw_vw, IEEE4) 'Frequency correction factor for wu and wv + Sample (1, FreqFactor_wTs, IEEE4) 'Frequency correction factor for wTs + Sample (1, FreqFactor_wCO2_wH2O, IEEE4) 'Frequency correction factor for covariance of CSI (CS) open-path (OPEC) vertical wind with h2o and co2 + + #If (SENSOR_FW) Then + Sample (1, FreqFactor_wFW, IEEE4) 'Frequency correction factor for covariance of vertical wind with fine thermocouple (FW) Temperature + #EndIf + ' *** End of correction related variables *** + + ' *** Output air properties calculated using measurements *** + Sample (2, rho_d_Avg, IEEE4) 'density of dry air (kg/m^3) and density of moist air (kg/m^3). Both are calculated using Tc if IRGASON or 107 temperature if CSAT3A+EC150 + Sample (1, Cp, IEEE4) 'specific heat of moist air at constant pressure, calculated using measurements from IRGASON [J/(kg K)] + Sample (1, Lv, IEEE4) 'latent heat of vaporization [J/g]. + ' *** End of output atmospheric constants *** + + '*** Beginning of other output data *** + Average (1, panel_tmpr, IEEE4, FALSE) + Average (1, batt_volt, IEEE4, slowsequence_disable_flg) + Totalize (1, n, IEEE4, slowsequence_disable_flg) + FieldNames ("slowsequence_Tot") + '*** End of other output data *** + + Average (1, process_time, IEEE4, FALSE) + Maximum (1, process_time, IEEE4, FALSE, FALSE) + FieldNames ("process_time_Max") + Maximum (1, buff_depth, IEEE4, FALSE, FALSE) + FieldNames ("buff_depth_Max") + +EndTable + +'Diagnostic data. +DataTable (diagnostic, TRUE, 1) + Sample (6, sonic_amp_l_f, Boolean) + Sample (22, irga_bad_data_f, Boolean) +EndTable + +'Time series data. +DataTable (Time_Series, TRUE, -1) + DataInterval (0, SCAN_INTERVAL, mSec, 100) + TableFile ("CRD:"&Status.SerialNumber(1,1)&".Time_Series_", 64, -1, 0, NMBR_DAY_TIMESERIES_CRD, Day, 0, 0) + + '*** Beginning of sonic time series output *** + Sample (3, Ux, IEEE4) + FieldNames ("Ux,Uy,Uz") + Sample (1, Ts, IEEE4) + FieldNames ("Ts") + Sample (1, diag_sonic, IEEE4) + FieldNames ("diag_sonic") + '*** End of sonic time series output *** + + '*** Beginning of IRGA time series output *** + Sample (3, irga(1),IEEE4) + FieldNames ("CO2,H2O,diag_irga") + + #If (SENSOR_IRGASON) Then + Sample (1, Tc, IEEE4) + FieldNames ("Tc") + #EndIf + + Sample (4, amb_tmpr,IEEE4) + FieldNames ("amb_tmpr,amb_press, CO2_sig_strgth, H2O_sig_strgth") + '*** End of IRGA time series output *** + + #If (SENSOR_FW) Then + '*** Beginning of FW time series output *** + Sample (1, FW, IEEE4) + FieldNames ("FW") + '*** End of FW time series output *** + #EndIf + +EndTable + +'*******************' +'*** SUBROUTINEs ***' +'*******************' + +'*** Sub-programs for coordinate rotation corrections *** +' 1. Two sub-programs for Double Rotations +' a. Rotations for momentum covariance +' b. Rotations for covariance of momentum variable with scalar variables + +' Definition of double rotation: the 1st AND 2nd rotations in Tanner & Thurtell (1969) +' a. Counterclockwise about the instrument z-axis for Gamma degrees +' b. Counterclockwise about the intermediate y-axis for Alpha degrees +' [Originally clockwise. Following Wilczak et al. (2001), counterclockwise rotation is used] + +' Sub: Rotation12_Momentum (where "12" indicates the 1st and 2nd rotations) +' Transform the expression of momentum variables in the instrument coordinate system to the natural wind coordinate system. +Sub Rotation12_Momentum(alph, gamm, _ + U_mean, V_mean, W_mean, UU_cov, VV_cov, WW_cov, UV_cov, UW_cov, VW_cov, _ + Umean_R, Vmean_R, Wmean_R, UUcov_R, VVcov_R, WWcov_R, UVcov_R, UWcov_R, VWcov_R ) + + ' For effiecient calculations, effiecient use of memory, and shorter expressions in the following equations, the variables of "UWcov_R" and + ' "VWcov_R" are used first as intermediate variables before both variables are needed for their own roles. + UWcov_R = UU_cov*COS(gamm)*COS(gamm) + VV_cov*SIN(gamm)*SIN(gamm) + VWcov_R = UW_cov*COS(gamm) + VW_cov*SIN(gamm) + + ' a. ROTATIONS FOR MEAN TERMS + Umean_R = COS(alph)*(U_mean*COS(gamm) + V_mean*SIN(gamm)) - W_mean*SIN(alph) + Vmean_R = 0 + Wmean_R = SIN(alph)*(U_mean*COS(gamm) + V_mean*SIN(gamm)) + W_mean*COS(alph) + + ' b. ROTATIONS FOR VARIANCE TERMS + UUcov_R = COS(alph)*COS(alph)*UWcov_R + _ + WW_cov*SIN(alph)*SIN(alph) + UV_cov*COS(alph)*COS(alph)*SIN(2*gamm) - _ + SIN(2*alph)*VWcov_R + + VVcov_R = UU_cov*SIN(gamm)*SIN(gamm) + VV_cov*COS(gamm)*COS(gamm) - UV_cov*SIN(2*gamm) + + WWcov_R = SIN(alph)*SIN(alph)*UWcov_R + _ + WW_cov*COS(alph)*COS(alph) + UV_cov*SIN(alph)*SIN(alph)*SIN(2*gamm) + _ + SIN(2*alph)*VWcov_R + + 'b. ROTATIONS FOR COVARIANCE TERMS + UVcov_R = -0.5*(UU_cov - VV_cov)*COS(alph)*SIN(2*gamm) + _ + UV_cov*COS(alph)*COS(2*gamm) + _ + SIN(alph)*(UW_cov*SIN(gamm) - VW_cov*COS(gamm)) + + UWcov_R = 0.5*SIN(2*alph)*(UWcov_R - WW_cov + UV_cov*SIN(2*gamm)) + COS(2*alph)*VWcov_R + + VWcov_R = -SIN(alph)*(0.5*(UU_cov - VV_cov)*SIN(2*gamm)-UV_cov*COS(2*gamm))- _ + COS(alph)*(UW_cov*SIN(gamm) - VW_cov*COS(gamm)) + +EndSub + +' Sub: Rotation12_Scalar_Covariance [where "12" indicates the 1st and 2nd rotations in Tanner & Thurtell (1969)] +' Transform the expression of variance of scalar with momentum variables in the instrument coordinate system +' to the natural wind coordinate system in x and y. + +Sub Rotation12_Scalar_Covariance(alph, gamm, SU_cov, SV_cov, SW_cov, SUcov_R, SVcov_R, SWcov_R) + + SUcov_R = COS(alph)*(SU_cov*COS(gamm) + SV_cov*SIN(gamm)) - SW_cov*SIN(alph) + + SVcov_R = -SU_cov*SIN(gamm) + SV_cov*COS(gamm) + + SWcov_R = SIN(alph)*(SU_cov*COS(gamm) + SV_cov*SIN(gamm)) + SW_cov*COS(alph) + +EndSub + +' 2. Sub-programs for Planar Fit Rotations [Wilczak et al. (2001)] +' a. Rotations for momentum covariance +' b. Rotations for covariance of momentum variable with scalar variables + +' Planar Fit Rotations +' a. Counterclockwise rotation about the instrument y-axis for Alph degrees [2nd rotation in Tanner and Thurtell (1969), clockwise] +' b. Counterclockwise rotation about the intermediate x-axis for Beta degrees [3rd rotation in Tanner and Thurtell (1969)] + +' Sub: Rotation23_Momentum [where "23" indicates the 2nd and 3rd rotations in Tanner & Thurtell (1969)] +Sub Rotation23_Momentum(alph, bet, _ + U_mean, V_mean, W_mean, UU_cov, VV_cov, WW_cov, UV_cov, UW_cov, VW_cov, _ + Umean_R, Vmean_R, Wmean_R, UUcov_R, VVcov_R, WWcov_R, UVcov_R, UWcov_R, VWcov_R ) + + ' For efficient calculations, efficient use of memory, and shorter expressions in the following equations, the four variables of Wmean_R, UVcov_R, + ' UWcov_R, and VWcov_R are used first as intermediate variables for repeated terms before the four variables are needed for their own roles. + Wmean_R = V_mean*SIN(bet) - W_mean*COS(bet) + UVcov_R = VV_cov*SIN(bet)*SIN(bet) - VW_cov*SIN(2*bet) + WW_cov*COS(bet)*COS(bet) + UWcov_R = UV_cov*SIN(bet) - UW_cov*COS(bet) + VWcov_R = UV_cov*COS(bet) + UW_cov*SIN(bet) + + ' a. ROTATIONS FOR MEAN TERMS + Umean_R = U_mean*COS(alph) + Wmean_R*SIN(alph) + Vmean_R = V_mean*COS(bet) + W_mean *SIN(bet) + Wmean_R = U_mean*SIN(alph) - Wmean_R*COS(alph) + + ' b. ROTATIONS FOR VARIANCE TERMS + UUcov_R = UU_cov*COS(alph)*COS(alph) + UVcov_R*SIN(alph)*SIN(alph) + UWcov_R*SIN(2*alph) + + VVcov_R = VV_cov*COS(bet)*COS(bet) + VW_cov*SIN(2*bet) + WW_cov*SIN(bet)*SIN(bet) + + WWcov_R = UU_cov*SIN(alph)*SIN(alph) + UVcov_R*COS(alph)*COS(alph) - UWcov_R*SIN(2*alph) + + 'b. ROTATIONS FOR COVARIANCE TERMS + UVcov_R = SIN(alph)*(0.5*(VV_cov - WW_cov)*SIN(2*bet)- VW_cov*COS(2*bet)) + COS(alph)*VWcov_R + + UWcov_R = 0.5*SIN(2*alph)*(UU_cov - VV_cov*SIN(bet)*SIN(bet) -WW_cov*COS(bet)*COS(bet)+ VW_cov*SIN(2*bet))- COS(2*alph)*UWcov_R + + VWcov_R = -COS(alph)*(0.5*(VV_cov - WW_cov)*SIN(2*bet)-VW_cov*COS(2*bet))+SIN(alph)*VWcov_R + +EndSub + +' Sub: Rotation23_Scalar_Covariance [where "23" indicates the 2nd and 3rd rotations in Tanner & Thurtell (1969)] +' Transform the expression of covariance of scalar with momentum variables in the instrument coordinate system +' to the natural wind coordinate system in z. + +Sub Rotation23_Scalar_Covariance(alph, bet, _ + SU_cov, SV_cov, SW_cov, _ + SU_cov_R, SV_cov_R, SW_cov_R) + + SU_cov_R = SU_cov*COS(alph) + SIN(alph)*(SV_cov*SIN(bet) - SW_cov*COS(bet)) + + SV_cov_R = SV_cov*COS(bet) + SW_cov*SIN(bet) + + SW_cov_R = SU_cov*SIN(alph) - COS(alph)*(SV_cov*SIN(bet) - SW_cov*COS(bet)) + +EndSub + +'*** Sub: calculate displacement height and aerodynamic height + +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' S_type Surface_type +' d_user displacement_user +' z0_user Roughness_user +' h_canopy height_canopy +' h_measurement height_measurement +' displacement d +' Roughness z0 +' h_aerodynamic z (sensing height above the ground - d) + +'*** Beginning the calculations of displacement height, roughness length, and aerodynamic height *** +Sub Displacement_roughness_heights (S_type, d_user, z0_user, h_canopy, h_measurement, displacement, roughness, h_aerodynamic) + ' Calculate displacement height, roughness length, and aerodynamic height + If ((S_type = CROP) OR (S_type = GRASS)) Then 'Crop and grass + + Select Case h_canopy + Case Is = 0 + displacement = 0 'Default w/o canopy + roughness = 0.01 'Default w/o canopy + Case Is >0 + displacement = 10^(0.979*LOG10(h_canopy)-0.154) 'Crop or grass canopy, Eq. 4.5, page 138 in Rosenberg et al. (1983) + roughness = 10^(0.977*LOG10(h_canopy)-0.883) 'Crop or grass canopy, Eq. 4.4, page 137 in Rosenberg et al. (1983) + EndSelect + + EndIf + + If ((S_type = FOREST) OR (S_type = SHRUB)) Then 'Forest and Shrub + displacement = 2*h_canopy/3 'Forest canopy, 2/3 rule, page 116, Oke, 1987 + roughness = 0.06*h_canopy 'Forest canopy, Jarvis et al. (1976) ans Raupach et al. (1991) + EndIf + + If ((S_type = BARELAND) OR (S_type = WATER)) Then 'Bare land and water + displacement = 0 'Default w/o canopy + roughness = 0.01 'Default w/o canopy + EndIf + + If (d_user <> 0) Then displacement = d_user 'User preferred has a priority + If (z0_user <> 0) Then roughness = z0_user 'User preferred has a priority + + h_aerodynamic = h_measurement - displacement +EndSub +'*** End the calculations of displacement height, roughness length, and aerodynamic height *** + +'*** Beginning subroutines for freq correction factors *** +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' height_aerodynamic z +' Stability Stability_zL +' U rslt_wnd_spd +' Freq_factor FreqFactor_uw_vw + +' Freq factor for uw and vw +Sub FreqFactorCSAT_uw_vw_BA_LA (height_aerodynamic, Stability, U, Freq_factor) + 'Variables used inside subrotine + Dim cosp_uw 'Cospectrum of u or v with w + Dim tran_func_BA 'Transfer function of block averaging for covariance + Dim tran_func_LA_ww 'Transfer function of line averaging for ww + Dim tran_func_LA_uu 'Transfer function of line averaging for uu or vv + + Dim freq 'Cyclic frequency + Dim freq_factor_numerator 'Numerator to calculate the freq correction factor for covariance of u or v with w + Dim freq_factor_denominator 'Denominator to calculate the freq correction factor for covariance of u or v with w + Dim weight 'Weight factor in numerical integration of Composite Simpson's Rule + Dim J As Long 'Iteration index. The uppercase letter J is used to keep the editor's auto-correct feature + 'from changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + + 'Define intermediate variables to reduce the repeat computation inside iteration loops + Dim zu 'z/U, ratio of aerodynamic height to total horizontal velocity + Dim pu_csat 'PATH_LENGTH_CSAT/U + Dim PI2_pu_freq_csat 'Intermediate variable 2*PI*pu_csat*freq + Dim A_uw, B_uw 'Parameters in the cospectrum of u with w for stable condition + + If ((Stability <> NaN) AND (U <> NaN)) Then + 'Reset variables + freq_factor_numerator = 0 + freq_factor_denominator = 0 + + 'Prepare calculations + zu = height_aerodynamic/U + pu_csat = PATH_LENGTH_CSAT/U + + 'Calculate parameters in the cospectrum of u with w for stable condition + Select Case Stability + Case Is > 0 AND Is <= 4 + A_uw = 0.124*((1 + 7.9*Stability)^0.75) 'a parameter in eq. 21 in Moore (1986), eq. 2.80 & Table 2.1 in Dijk (2002) + B_uw = 23.252*((1 + 7.9*Stability)^(-0.825)) 'a parameter in eq. 21 in Moore (1986), eq. 2.80 & Table 2.1 in Dijk (2002) + + Case Is > 4 'Similarity functions are defined in a range of z/L from -2 to 2 (pages17, 28, 41~43, Kaimal & Finnigan 1994). Extened to 4 as shown in Fig 5.23 in Stull (1988) + A_uw = 0.124*((1 + 7.9*4.0)^0.75) 'a parameter in eq. 21 in Moore (1986), eq. 2.80 & Table 2.1 in Dijk (2002) + B_uw = 23.252*((1 + 7.9*4.0)^(-0.825)) 'a parameter in eq. 21 in Moore (1986), eq. 2.80 & Table 2.1 in Dijk (2002) + EndSelect + + ' Calculate correction factor + For J = 0 To FREQ_BIN + freq = START_FREQ*(STEP_BASE_FREQ^J) + + PI2_pu_freq_csat = 2*PI*pu_csat*freq + + '**Cospectrum + If Stability > 0 Then + cosp_uw = freq*zu/(A_uw + B_uw*(freq*zu)^2.1) 'Eq. 21 in Moore (1986), eq. 2.80 & Table 2.1 in Dijk (2002) + Else + Select Case (freq*zu) 'Eq. 26 in Moore (1986), eqs. 17 & 18 in Moncrieff et al (1997), eq. 2.85 in Dijk (2002) + Case Is < 0.24 + cosp_uw = 20.78*freq*zu/((1 + 31*freq*zu)^1.575) + Case Is >= 0.24 + cosp_uw = 12.66*freq*zu/((1 + 9.6*freq*zu)^2.4) + EndSelect + EndIf + + '** Transfer function + tran_func_BA = 1 - (SIN (10800*OUTPUT_INTERVAL*freq)/(PI*60*OUTPUT_INTERVAL*freq))^2 'Eq. 4 in Kaimal et al. (1989), Eq. 3 in Massman (2000). Inside SIN(), angle degrees must be used. + tran_func_LA_uu = (SIN (180*pu_csat*freq)/(PI*pu_csat*freq))^2 'Eq. 2.70 in DijK (2002) + + If PI2_pu_freq_csat >= 0.01 Then + tran_func_LA_ww = (4/PI2_pu_freq_csat)*(1+ (PI2_pu_freq_csat+3)/(2*PI2_pu_freq_csat*EXP(PI2_pu_freq_csat)) -3/(2*PI2_pu_freq_csat)) 'Eq. 9 in Moore (1986), page 610 in Moncrieff et al. (1997) + Else + tran_func_LA_ww = 1 'Due to single precision in CR3K, this term cannot be calculated when the 2*Pi*dimensiless freq < 0.01. This is an approximation. The error in the approximation < 0.001 + EndIf + + ' Composite Simpson's Rule + weight = 2 + 2*(J MOD 2) + (J = 0) + (J = FREQ_BIN) 'In Composite Simpson's Rule, weight factor "1" for 1st and last terms, "2" for even, and "4" for odd terms in a sequential order. + + freq_factor_numerator += weight*cosp_uw + + freq_factor_denominator += weight*cosp_uw*tran_func_BA*SQR(tran_func_LA_uu*tran_func_LA_ww) + + Next J + + '** correction factor + Freq_factor = freq_factor_numerator/freq_factor_denominator + Else + Freq_factor = 1 + EndIf +EndSub + +' Frequency factor for wTs +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' height_aerodynamic z +' Stability Stability_zL +' U rslt_wnd_spd +' tran_func_LA_Dijk() tran_func_LA_data_Dijk() +' Freq_factor FreqFactor_wTs + +Sub FreqFactorCSAT_wTs_BA_LA (height_aerodynamic, Stability, U, tran_func_LA_Dijk(2,35), Freq_factor) + 'Variables used inside subrotine + Dim cosp_wTs 'Copectrum of Ts with w + Dim tran_func_BA 'Transfer function of block averaging for covariance + Dim Tran_func_LA_wTs 'Transfer function of line averaging for wTs + + Dim freq 'Cyclic frequency + Dim freq_factor_numerator 'Numerator to calculate the freq correction factor for covariance of Ts with w + Dim freq_factor_denominator 'Denominator to calculate the freq correction factor for covariance of Ts with w + Dim weight 'Weight factor in numerical integration of Composite Simpson's Rule + Dim J As Long 'Index for the outmost iteration. The upcase letter J is used to keep the editor's auto-correct feature + 'from changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + Dim jj As Long 'Index for the iteration inside the outmost iteration + Dim Prev_jj As Long + + 'Define following variables for saving computation time by calculating these once outside iteration loops or reduce the repeat computations + Dim zu 'z/U, ratio of aerodynamic height to total horizontal velocity + Dim pu_csat 'PATH_LENGTH_CSAT/U + Dim PI2_pu_freq_csat 'Intermediate variable 2*PI*pu_csat*freq + Dim A_wTs, B_wTs 'Parameters in the cospectrum of Ts with w in a stable condition + + If ((Stability <> NaN) AND (U <> NaN)) Then + + 'Reset variables + freq_factor_numerator = 0 + freq_factor_denominator = 0 + Prev_jj = 1 + + 'Prepair calculations + zu = height_aerodynamic/U + pu_csat = PATH_LENGTH_CSAT/U + + 'Calculate parameters in the cospectrum of u with w for stable condition + Select Case Stability + Case Is > 0 AND Is <= 4 + A_wTs = 0.2840*((1 + 6.4*Stability)^0.75) 'a parameter in Eq.21 in Moore (1986), eqs.12 & 13 in Moncrieff et al. (1997), eq.2.80 & Table 2.1 in Dijk (2002) + B_wTs = 9.3447*((1 + 6.4*Stability)^(-0.825)) 'a parameter in Eq.21 in Moore (1986), eqs.12 & 13 in Moncrieff et al. (1997), eq.2.80 & Table 2.1 in Dijk (2002) + + Case Is > 4 'Similarity functions are defined in a range of z/L from -2 to 2 (pages 28, 41~43, Kaimal & Finnigan 1994). Extened to 4 as shown in Fig 5.23 in Stull (1988) + A_wTs = 0.2840*((1 + 6.4*4.0)^0.75) 'a parameter in Eq.21 in Moore (1986), eqs.12 & 13 in Moncrieff et al. (1997), eq.2.80 & Table 2.1 in Dijk (2002) + B_wTs = 9.3447*((1 + 6.4*4.0)^(-0.825)) 'a parameter in Eq.21 in Moore (1986), eqs.12 & 13 in Moncrieff et al. (1997), eq.2.80 & Table 2.1 in Dijk (2002) + EndSelect + + 'Start calculations for correction factor + For J = 0 To FREQ_BIN + freq = START_FREQ*(STEP_BASE_FREQ^J) + + PI2_pu_freq_csat = 2*PI*pu_csat*freq + + '**Cospectrum + If Stability > 0 Then + cosp_wTs = zu*freq/(A_wTs + B_wTs*(zu*freq)^2.1) 'Eq.21 in Moore (1986), eqs.12 & 13 in Moncrieff et al. (1997), eq.2.80 & Table 2.1 in Dijk (2002) + Else + Select Case (zu*freq) 'Eq.25 in Moore (1986), eqs.15 & 16 in Moncrieff et al. (1997), eq.2.84 in Dijk (2002) + Case Is < 0.54 + cosp_wTs = 12.92*zu*freq/((1 + 26.7*zu*freq)^1.375) + Case Is >= 0.54 + cosp_wTs = 4.378*zu*freq/((1 + 3.8*zu*freq)^2.4) '4.378 from original source Eq.25 in Moore (1986) + EndSelect + EndIf + + '**Transfer function + tran_func_BA = 1 - (SIN (10800*OUTPUT_INTERVAL*freq)/(PI*60*OUTPUT_INTERVAL*freq))^2 'Eq.4 in Kaimal et al (1989), Eq.3 in Massman (2000) + + For jj = Prev_jj To 34 + If (PI2_pu_freq_csat >= tran_func_LA_Dijk(1,jj)) AND (PI2_pu_freq_csat < tran_func_LA_Dijk(1, jj+1)) Then + + Tran_func_LA_wTs = tran_func_LA_Dijk(2,jj) + (PI2_pu_freq_csat-tran_func_LA_Dijk(1,jj))*(tran_func_LA_Dijk(2,jj+1) - tran_func_LA_Dijk(2,jj))/(tran_func_LA_Dijk(1,jj+1) - tran_func_LA_Dijk(1,jj)) + + Prev_jj = jj + + ExitFor + EndIf + Next jj + + If PI2_pu_freq_csat >= tran_func_LA_Dijk(1, 35) Then Tran_func_LA_wTs = tran_func_LA_Dijk(2, 35) + + 'Composite Simpson's Rule + weight = 2 + 2*(J MOD 2) + (J = 0) + (J = FREQ_BIN) 'In Composite Simpson's Rule, weight factor "1" for 1st and last terms, "2" for even, and "4" for odd terms in sequential order. + + freq_factor_numerator += weight*cosp_wTs + freq_factor_denominator += weight*cosp_wTs*tran_func_BA*Tran_func_LA_wTs + + Next J + + '**Correction factor + Freq_factor = freq_factor_numerator/freq_factor_denominator + Else + Freq_factor = 1 + EndIf +EndSub + +' Freq factor of CSAT + CSI IRGA for wco2 and wh2o +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' height_aerodynamic z +' Stability Stability_zL +' U rslt_wnd_spd +' separation_lat_dis separation_lat_dist_IRGA +' Freq_factor FreqFactor_wco2_wh2o + +Sub FreqFactorCSOPEC_wco2_wh2o_BA_LA_SP (height_aerodynamic, Stability, U, separation_lat_dis, Freq_factor) + 'Variables used inside subrotine + Dim cosp_wco2_wh2o 'Cospectrum of co2 or h2o with w + Dim tran_func_BA 'Transfer function of block averaging for covariance + Dim tran_func_LA_ww 'Transfer function of line averaging for ww + Dim tran_func_LA_co2_h2o 'Transfer function of line averaging for variance of co2 or h2o + Dim Tran_func_SP_wco2_wh2o 'Transfer function of lateral separation (normal to the wind direction) between sonic for w and IRGA for co2 or h2o + + Dim freq 'Cyclic frequency + Dim freq_factor_numerator 'Numerator to calculate the freq correction factor for covariance of co2 or h2o with w + Dim freq_factor_denominator 'Denominator to calculate the freq correction factor for covariance of co2 or h2o with w + Dim weight 'Weight factor in the numerical integration of Composite Simpson's Rule + Dim J As Long 'Iteration index. The upcase letter J is used to keep the editor's auto-correct feature + 'from changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + + 'Define following variables for saving computation time by calculating these once outside iteration loops or by reducing repeat computations + Dim zu 'z/U, ratio of aerodynamic height to total horizontal velocity + Dim pu_csat 'path_length_CSAT/U + Dim pu_IRGA 'path_length_IRGA/U + Dim du_IRGA 'Ratio of effective lateral separation distance (normal to wind) to total wind speed + Dim PI2_pu_csat 'Intermediate variable 2*Pi*pu_csat + Dim PI2_pu_IRGA 'Intermediate variable 2*Pi*pu_IRGA + Dim PI2_pu_freq_csat 'Intermediate variable 2*Pi*pu_csat*freq + Dim PI2_pu_freq_IRGA 'Intermediate variable 2*Pi*pu_IRGA*freq + Dim A_wco2_wh2o, B_wco2_wh2o 'Parameters in the cospectrum of scalar (e.g. co2 or h2o) with w + + If ((Stability <> NaN) AND (U <> NaN) AND (separation_lat_dis <> NaN)) Then + + 'Reset variables + freq_factor_numerator = 0 + freq_factor_denominator = 0 + + 'Prepair calculations + zu = height_aerodynamic/U + pu_csat = PATH_LENGTH_CSAT/U + pu_IRGA = PATH_LENGTH_IRGA/U + du_IRGA = ABS(separation_lat_dis)/U + PI2_pu_csat = 2*PI*pu_csat + PI2_pu_IRGA = 2*PI*pu_IRGA + + 'Calculate parameters in the cospectrum of u with w for stable condition + Select Case Stability + Case Is > 0 AND Is <= 4 + A_wco2_wh2o = 0.2840*((1 + 6.4*Stability)^0.75) 'Parameter in Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + B_wco2_wh2o = 9.3447*((1 + 6.4*Stability)^(-0.825)) 'Parameter in Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + + Case Is > 4 'Similarity functions are defined in a range of z/L from -2 to 2 (pages 28, 41~43, Kaimal & Finnigan 1994). Extened to 4 as shown in Fig 5.23 in Stull (1988) + A_wco2_wh2o = 0.2840*((1 + 6.4*4.0)^0.75) 'Parameter in Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + B_wco2_wh2o = 9.3447*((1 + 6.4*4.0)^(-0.825)) 'Parameter in Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + EndSelect + + 'Start calculations for correction factors + For J = 0 To FREQ_BIN + freq = START_FREQ*(STEP_BASE_FREQ^J) + + PI2_pu_freq_csat = PI2_pu_csat*freq + PI2_pu_freq_IRGA = PI2_pu_IRGA*freq + + '**Cospectrum + If Stability > 0 Then + cosp_wco2_wh2o = zu*freq/(A_wco2_wh2o + B_wco2_wh2o*(zu*freq)^2.1) 'Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + Else + Select Case (freq*zu) 'Eq. 25 in Moore (1986), eqs. 15 & 16 in Moncrieff et al (1997), eq. 2.84 in Dijk (2002) + Case Is < 0.54 + cosp_wco2_wh2o = 12.92*zu*freq/((1 + 26.7*zu*freq)^1.375) + Case Is >= 0.54 + cosp_wco2_wh2o = 4.378*zu*freq/((1 + 3.8*zu*freq)^2.4) '4.378 from original source of Eq.25 in Moore (1986) + EndSelect + EndIf + + '** Transfer functions + tran_func_BA = 1 - (SIN (10800*OUTPUT_INTERVAL*freq)/(PI*60*OUTPUT_INTERVAL*freq))^2 'Block averaging: Eq. 4 in Kaimal et al. (1989), Eq. 3 in Massman (2000). Angle degree must be used insoide SIN(). + + Tran_func_SP_wco2_wh2o = EXP(-9.9*(du_IRGA*freq)^1.5) 'Spatial separation: Eq. 4.8 in Foken et al. (2012) + + If PI2_pu_freq_csat >= 0.01 Then 'Line averaging + tran_func_LA_ww = (4/PI2_pu_freq_csat)*(1+ (PI2_pu_freq_csat+3)/(2*PI2_pu_freq_csat*EXP(PI2_pu_freq_csat)) -3/(2*PI2_pu_freq_csat)) 'Eq. 9 in Moore (1986), page 610 in Moncrieff et al (1997) + Else + tran_func_LA_ww = 1 'Due to sigle precision in CR3K, this term cannot be calculated when the 2PI*dimensionless frequency < 0.01. This is an approximation with an error < 0.001. + EndIf + + If PI2_pu_freq_IRGA >= 0.01 Then + tran_func_LA_co2_h2o = (1/PI2_pu_freq_IRGA)*(3+ (PI2_pu_freq_IRGA+4)/(PI2_pu_freq_IRGA*EXP(PI2_pu_freq_IRGA)) -4/PI2_pu_freq_IRGA) 'Eq. 9 in Moore (1986), page 610 in Moncrieff et al (1997) + Else + tran_func_LA_co2_h2o = 1 'Due to sigle precision in CR3K, this term cannot be calculated when the normalized frequency < 0.01 Hz. This is an approximation with an error < 0.001 + EndIf + + 'Composite Simpson's Rule + weight = 2 + 2*(J MOD 2) + (J = 0) + (J = FREQ_BIN) 'In Composite Simpson's Rule, weight factor "1" for 1st and last terms, "2" for even, and "4" for odd terms in a sequential order. + + freq_factor_numerator += weight*cosp_wco2_wh2o + + freq_factor_denominator += weight*cosp_wco2_wh2o*tran_func_BA*SQR(tran_func_LA_ww*tran_func_LA_co2_h2o)*Tran_func_SP_wco2_wh2o + + Next J + + '** Correction factor + Freq_factor = freq_factor_numerator/freq_factor_denominator + Else + Freq_factor = 1 + EndIf + +EndSub + +#If (SENSOR_FW) Then +' Frequency factor of CSAT + FW for wT +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' height_aerodynamic z +' Stability Stability_zL +' U rslt_wnd_spd +' separation_lat_dis separation_lat_dist_FW +' time_const time_const_FW +' Freq_factor FreqFactor_wFW + +Sub FreqFactorCSATFW_wT_BA_LA_TC_SP (height_aerodynamic, Stability, U, separation_lat_dis, time_const, Freq_factor) + 'Variables used inside subroutine + Dim cosp_wT 'Cospectrum of T with w + Dim tran_func_BA 'Transfer function of block averaging for covariance + Dim tran_func_LA_ww 'Transfer function of line averaging for ww + Dim tran_func_TC_TT 'Transfer function of time constant for TT + Dim Tran_func_SP_wT 'Transfer function of lateral separation between CSAT3 w and FW T + Dim A_wT, B_wT 'Parameters in the cospectrum of scalar (e.g. co2 or h2o) with w in the stable condition + + Dim freq 'Cyclic frequency + Dim freq_factor_numerator 'Numerator to calculate the freq correction factor for covariance of T with w + Dim freq_factor_denominator 'Denominator to calculate the freq correction factor for covariance of T with w + Dim weight 'Weight factor in the numerical integration of Composite Simpson's Rule. + Dim J As Long 'Iteration index. The upcase letter J is used to keep the editor's auto-correct feature + 'from changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + + 'Define following variables for saving computation time by calculating these once outside iteration loops or by reducing repeat computation + Dim zu 'z/U, ratio of aerodynamic height to total horizontal velocity + Dim du_FW 'The ratio of effective lateral separation distance to total wind speed + Dim PI2_pu_csat 'Intermediate variable 2*Pi*path_length_csat/U + Dim PI2_pu_freq_csat 'Intermediate variable 2*Pi*(path_length_csat/U)*freq + + If ((Stability <> NaN) AND (U <> NaN) AND (separation_lat_dis <> NaN)) Then + 'Reset variables + freq_factor_numerator = 0 + freq_factor_denominator = 0 + + 'Prepair calculations + zu = height_aerodynamic/U + PI2_pu_csat = 2*PI*PATH_LENGTH_CSAT/U + du_FW = ABS(separation_lat_dis)/U + + 'Calculate the parameters in the cospectrum of scalar with w for a stable surface-layer condition + Select Case Stability + Case Is > 0 AND Is <= 4.0 + A_wT = 0.2840*((1 + 6.4*Stability)^0.75) 'a parameter in eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al. (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + B_wT = 9.3447*((1 + 6.4*Stability)^(-0.825)) 'a parameter in eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al. (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + + Case Is > 4 'Similarity functions are defined in a range of z/L from -2 to 2 (pages 28, 41~43, Kaimal & Finnigan 1994). Extened to 4 as shown in Fig 5.23 in Stull (1988) + A_wT = 0.2840*((1 + 6.4*4.0)^0.75) 'a parameter in eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al. (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + B_wT = 9.3447*((1 + 6.4*4.0)^(-0.825)) 'a parameter in eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al. (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + EndSelect + + 'Calculate correction factor + For J = 0 To FREQ_BIN + freq = START_FREQ*(STEP_BASE_FREQ^J) + + PI2_pu_freq_csat = PI2_pu_csat*freq + + '** Cospectrum + If (Stability > 0) Then + cosp_wT = zu*freq/(A_wT + B_wT*(zu*freq)^2.1) 'Eq. 21 in Moore (1986), eqs. 12 & 13 in Moncrieff et al. (1997), eq. 2.80 & Table 2.1 in Dijk (2002) + Else + Select Case (freq*zu) 'Eq. 25 in Moore (1986), eqs. 15 & 16 in Moncrieff et al. (1997), eq. 2.84 in Dijk (2002) + Case Is < 0.54 + cosp_wT = 12.92*zu*freq/((1 + 26.7*zu*freq)^1.375) + Case Is >= 0.54 + cosp_wT = 4.378*zu*freq/((1 + 3.8*zu*freq)^2.4) '4.378 from original source of Eq.25 in Moore (1986) + EndSelect + EndIf + + '** Transfer function + tran_func_BA = 1 - (SIN (10800*OUTPUT_INTERVAL*freq)/(PI*60*OUTPUT_INTERVAL*freq))^2 'Block averaging: Eq. 4 in Kaimal et al. (1989), Eq. 3 in Massman (2000). Angle degree must be sued inside SIN(). + Tran_func_SP_wT = EXP(-9.9*(du_FW*freq)^1.5) 'Spatial separation: Eq. 4.8 in Foken et al. (2012) + tran_func_TC_TT = 1/(1+(2*PI*time_const*freq)^2) 'Time constant: Eq. 5 Horst (1997) + + If PI2_pu_freq_csat >= 0.01 Then + tran_func_LA_ww = (4/PI2_pu_freq_csat)*(1+ (PI2_pu_freq_csat+3)/(2*PI2_pu_freq_csat*EXP(PI2_pu_freq_csat)) -3/(2*PI2_pu_freq_csat)) 'Eq. 9 in Moore (1986), page 610 in Moncrieff et al. (1997) + Else + tran_func_LA_ww = 1 'Due to sigle precision in CR3K, this term cannot be calculated when 2PI*dimensionless_frequency < 0.01. This is an approximation with an error < 0.001. + EndIf + + 'Composite Simpson's Rule + weight = 2 + 2*(J MOD 2) + (J = 0) + (J = FREQ_BIN) 'In Composite Simpson's Rule, weight factor "1" for 1st and last terms, "2" for even, and "4" for odd terms in a sequential order. + + freq_factor_numerator += weight*cosp_wT + freq_factor_denominator += weight*cosp_wT*tran_func_BA*SQR(tran_func_LA_ww*tran_func_TC_TT) *Tran_func_SP_wT + + Next J + + '**Correction factor + Freq_factor = freq_factor_numerator/freq_factor_denominator + + Else + Freq_factor = 1 + EndIf +EndSub +#EndIf +'*** End of subroutines for freq correction factors *** + +'*** Beginning of subroutines for data quality classification *** +'a. Momentum flux +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' Planar_fit Planar_Fit_flg +' Stability Stability_zL +' Sigma_u u_std_R +' Sigma_w w_std_R +' Ustar u_star +' Lat latitude +' wnd_dir wnd_dir_sonic +' RNS RN_uw_vw_cov_R RNS: Relative Non-Stationarity +' QC tau_qc_grade quality classes 1 to 9. + +Sub Data_Quality_Grading_Momentum (Planar_Fit, Stability, Sigma_u, Sigma_w, Ustar, Lat, wnd_dir, RNS, QC) + ' Test on turbulence conditions in development + Dim ITC_uw(2) 'ITC: Integral Turbulence Chracteristic. This array is used in instruction MaxSpa to select max + Alias ITC_uw(1) = ITCuu 'Integral Turbulence Chracteristic for variance of horizontal velocity + Alias ITC_uw(2) = ITCww 'Integral Turbulence Chracteristic for variance of vertical velocity + + Dim ITC_uw_max(2) 'for use of instruction MaxSpa. Hold the max and the index of max location + Alias ITC_uw_max(1) = ITC_uu_ww 'Integral turbulence characteristic for momentum flux + Alias ITC_uw_max(2) = ITC_uu_ww_max_seq 'the index of max location + + Dim Coriolis_parameter + + Dim RNS_category(8) As Boolean 'Categorize the relative non-stationarity into possible grade categories in the overall grade system + Dim ITC_category(8) As Boolean 'Categorize the integral turbulence characteristic into possible grade categories in the overall grade system + + Dim Lowest_Seq_1st_Occurrence(3) + Alias Lowest_Seq_1st_Occurrence(1) = RNS_Momentum_1st_Occurrence 'The lowest possible grade of relative non-stationarity in the overall grade system + Alias Lowest_Seq_1st_Occurrence(2) = ITC_Momentum_1st_Occurrence 'The lowest possible grade of integral turbulence characteristics in the overall grade system + Alias Lowest_Seq_1st_Occurrence(3) = Wnd_Momentum_1st_Occurrence 'The lowest possible grade of wind direction in the overall grade system + + Dim Lowest_Seq_Max(2) 'for use of instruction MaxSpa. Hold the max in "Lowest_Seq_1st_Occurrence()" + + Dim J As Long 'Used for index of iteration. The upcase letter J is used to keep the editor's auto-correct feature + 'from changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + 'Reset + QC = 0 + + '1. Relative Non-Stationarity + 'Possible Grade for relative non-Stationarity (Steady state test) + RNS_category(1) = (RNS < 0.15) + RNS_category(2) = ((RNS >= 0.15) AND (RNS < 0.30)) + RNS_category(3) = (RNS < 0.30) + RNS_category(4) = ((RNS >= 0.30) AND (RNS < 0.75)) + RNS_category(5) = (RNS < 0.75) + RNS_category(6) = ((RNS >= 0.75) AND (RNS < 1.00)) + RNS_category(7) = ((RNS >= 1.00) AND (RNS < 2.50)) + RNS_category(8) = ((RNS >= 2.50) AND (RNS < 10.0)) + + For J = 1 To 8 + RNS_Momentum_1st_Occurrence = -J *RNS_category(J) + If (RNS_Momentum_1st_Occurrence = J) Then + ExitFor + EndIf + Next J + + '2. Integral Turbulence Chracteristic + Coriolis_parameter = 2*Omega*SIN(Lat) 'Omega: earth anglular velocity + + Select Case Stability + Case Is <= -0.032 + ITCuu = 4.15*ABS(Stability)^0.125 'Table 4.2 (Foken et al. 2012) + ITCww = 2.00*ABS(Stability)^0.125 'Table 4.2 (Foken et al. 2012) + + Case Is > -0.032 AND Is <= 0 + ITCuu = 2.7 'Table 4.2 (Foken et al. 2012) + ITCww = 1.3 'Table 4.2 (Foken et al. 2012) + + Case Is < 0.4 AND Is > 0 + ITCuu = 0.44*LN(ABS(Coriolis_parameter)/Ustar) + 6.3 'Table 4.3 (Foken et al. 2012) + ITCww = 0.21*LN(ABS(Coriolis_parameter)/Ustar) + 3.1 'Table 4.3 (Foken et al. 2012) + + Case Is >= 0.4 + ITCuu = -(Sigma_u/Ustar)/9.1 'Model unavailiable in this stability (z/L) range. Assume relative integral turbulence characteristic to be 10.1 for grade 9 due to a very stable condition + ITCww = -(Sigma_w/Ustar)/9.1 'Model unavailiable in this stability (z/L) range. Assume relative integral turbulence characteristic to be 10.1 for grade 9 due to a very stable condition + EndSelect + + ITCuu = ABS((ITCuu - (Sigma_u/Ustar))/ITCuu) 'In fraction + ITCww = ABS((ITCww - (Sigma_w/Ustar))/ITCww) 'In fraction + + If (NOT (Planar_Fit)) Then + 'If double rotation, both the max of ITC_uu and ITC_ww is used as ITC_uu_ww. + MaxSpa(ITC_uu_ww, 2, ITCuu) 'Max is used for momentum flux related to uw and vw + Else + 'If planar fit, only ITC_ww is used as ITC_uu_ww. + ITC_uu_ww = ITCww + EndIf + + 'Possible grade for the integral turbulence characteristics + ITC_category(1) = (ITC_uu_ww < 0.30) + ITC_category(2) = (ITC_uu_ww < 0.30) + ITC_category(3) = ((ITC_uu_ww >= 0.30) AND (ITC_uu_ww < 0.75)) + ITC_category(4) = (ITC_uu_ww < 0.30) + ITC_category(5) = ((ITC_uu_ww >= 0.30) AND (ITC_uu_ww < 1.00)) + ITC_category(6) = ((ITC_uu_ww >= 0.75) AND (ITC_uu_ww < 1.00)) + ITC_category(7) = ((ITC_uu_ww >= 1.00) AND (ITC_uu_ww < 2.50)) + ITC_category(8) = ((ITC_uu_ww >= 2.50) AND (ITC_uu_ww < 10.00)) + + For J = 1 To 8 + ITC_Momentum_1st_Occurrence = -J *ITC_category(J) + If (ITC_Momentum_1st_Occurrence = J) Then + ExitFor + EndIf + Next J + + '3. Wind Direction + 'The lowest possible grade of wind direction in the overall grade system + If ((wnd_dir <= 151) OR (wnd_dir >= 209)) Then + Wnd_Momentum_1st_Occurrence = 1 + ElseIf (((wnd_dir > 151) AND (wnd_dir <= 170)) OR ((wnd_dir >= 190) AND (wnd_dir < 209))) + Wnd_Momentum_1st_Occurrence = 7 + ElseIf ((wnd_dir > 170) AND (wnd_dir < 190)) + Wnd_Momentum_1st_Occurrence = 0 + EndIf + + '1st case + If (RNS_Momentum_1st_Occurrence = 0) OR (ITC_Momentum_1st_Occurrence =0) OR (Wnd_Momentum_1st_Occurrence = 0) Then 'Any in category 9 (0 used for 9) + QC = 9 + + '2nd case + Else + MaxSpa (Lowest_Seq_Max(1), 3, RNS_Momentum_1st_Occurrence) + QC = Lowest_Seq_Max(1) + EndIf + + '3rd case + If (((RNS = NaN) OR (ITC_uu_ww = NaN) OR (wnd_dir = NaN)) AND (QC = 9)) Then QC = NaN + +EndSub + +'b. Scalar flux +' Variable Notation +' SUBROUTINE MAIN PROGRAM +' Stability stability_zL +' Sigma_w w_std_R +' Ustar u_star +' Sigma_Ts Ts_std +' Tstar T_star +' Lat latitude +' wnd_dir wnd_dir_sonic +' RNS RN_wTs_cov_R, RN_wCO2_Cov_R, or RN_wH2O_Cov_R Relative Non-Stationarity +' QC Fc_qc_grade, LE_qc_grade, or H_qc_grade quality classes 1 to 9. + +Sub Data_Quality_Grading_Scalar (Stability, Sigma_w, Ustar, Sigma_Ts, Tstar, Lat, wnd_dir, RNS, QC) + ' Test on developed turbulence conditions + Dim ITC_TsTs 'ITC: Integral Turbulence Chracteristics + Dim ITC_wTs + Dim ITC_ww + + Dim Coriolis_parameter + + Dim RNS_category(8) As Boolean 'Categorize the relative non-stationarity into possible grade categories in the overall grade system + Dim ITC_category(8) As Boolean 'Categorize the integral turbulence characteristic into possible grade categories in the overall grade system + + Dim Lowest_Seq_1st_Occurrence(3) + Alias Lowest_Seq_1st_Occurrence(1) = RNS_Scalar_1st_Occurrence 'The lowest possible grade of relative non-stationarity in the overall grade system + Alias Lowest_Seq_1st_Occurrence(2) = ITC_Scalar_1st_Occurrence 'The lowest possible grade of integral turbulence characteristi in the overall grade system + Alias Lowest_Seq_1st_Occurrence(3) = Wnd_Scalar_1st_Occurrence 'The lowest possible grade of wind direction in the overall grade system + + Dim Lowest_Seq_Max(2) 'For use of instruction MaxSpa. Hold the max in "Lowest_Seq_1st_Occurrence()" + + Dim J As Long 'Used for index of iteration. The upcase letter J is used to keep the editor's auto-correct feature + 'From changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + 'Reset + QC = 0 + + '1. Relative Non-Stationarity + 'Possible Grade for relative non-stationarity (Steady state test) + RNS_category(1) = (RNS < 0.15) + RNS_category(2) = ((RNS >= 0.15) AND (RNS < 0.30)) + RNS_category(3) = (RNS < 0.30) + RNS_category(4) = ((RNS >= 0.30) AND (RNS < 0.75)) + RNS_category(5) = (RNS < 0.75) + RNS_category(6) = ((RNS >= 0.75) AND (RNS < 1.00)) + RNS_category(7) = ((RNS >= 1.00) AND (RNS < 2.50)) + RNS_category(8) = ((RNS >= 2.50) AND (RNS < 10.0)) + + For J = 1 To 8 + RNS_Scalar_1st_Occurrence = -J *RNS_category(J) + If (RNS_Scalar_1st_Occurrence = J) Then + ExitFor + EndIf + Next J + + '2. Integral Turbulence Chracteristic + Coriolis_parameter = 2*Omega*SIN(Lat) 'Omega: earth anglular velocity + + 'Test on developed turbulence conditions for sensible heat flux using the integral turbulence characteristic + Select Case Stability + Case Is <= -0.032 + ITC_ww = 2.00*ABS(Stability)^0.125 'Table 4.2 (Foken et al. 2012) + + Case Is > -0.032 AND Is <= 0 + ITC_ww = 1.3 'Table 4.2 (Foken et al. 2012) + + Case Is < 0.4 AND Is > 0 + ITC_ww = 0.21*LN(ABS(Coriolis_parameter)/Ustar) + 3.1 'Table 4.3 (Foken et al. 2012) + + Case Is >= 0.4 + ITC_ww = -(Sigma_w/Ustar)/9.1 'Model unavailiable in this z/L range. Assume relative integral turbulence characteristic to be 10.1 for grade 9 due to a very stable condition + EndSelect + ITC_ww = ABS((ITC_ww - (Sigma_w/Ustar))/ITC_ww) 'In fraction + + Select Case Stability + Case Is < -1 + ITC_TsTs = ABS(Stability)^(-1/3) 'Table 4.2 (Foken et al. 2012) + + Case Is <= -0.062 AND Is >= -1 + ITC_TsTs = ABS(Stability)^(-0.25) 'Table 4.2 (Foken et al. 2012) + + Case Is < 0.02 AND Is > -0.062 + ITC_TsTs = 0.5*ABS(Stability)^(-0.50) 'Table 4.2 (Foken et al. 2012) + + Case Is >= 0.02 AND Is < 1 + ITC_TsTs = 1.4*Stability^(-0.25) 'Table 4.2 (Foken et al. 2012) + + Case Is >=1 + ITC_TsTs = -(Sigma_Ts/ABS(Tstar))/9.1 'Classify it into grade 9 when z/L >= 1 + EndSelect + + ITC_TsTs = ABS((ITC_TsTs - Sigma_Ts/ABS(Tstar))/ITC_TsTs) 'in fraction + + ITC_wTs = IIF ( (ITC_TsTs > ITC_ww), ITC_TsTs, ITC_ww) + + 'Possible grade for the integral turbulence characteristics + ITC_category(1) = (ITC_wTs < 0.30) + ITC_category(2) = (ITC_wTs < 0.30) + ITC_category(3) = ((ITC_wTs >= 0.30) AND (ITC_wTs < 0.75)) + ITC_category(4) = (ITC_wTs < 0.30) + ITC_category(5) = ((ITC_wTs >= 0.30) AND (ITC_wTs < 1.00)) + ITC_category(6) = ((ITC_wTs >= 0.75) AND (ITC_wTs < 1.00)) + ITC_category(7) = ((ITC_wTs >= 1.00) AND (ITC_wTs < 2.50)) + ITC_category(8) = ((ITC_wTs >= 2.50) AND (ITC_wTs < 10.00)) + + For J = 1 To 8 + ITC_Scalar_1st_Occurrence = -J *ITC_category(J) + If (ITC_Scalar_1st_Occurrence = J) Then + ExitFor + EndIf + Next J + + '3. wind direction + 'The lowest possible grade of wind direction in the overall grade system + If ((wnd_dir <= 151) OR (wnd_dir >= 209)) Then + Wnd_Scalar_1st_Occurrence = 1 + ElseIf (((wnd_dir > 151) AND (wnd_dir <= 170)) OR ((wnd_dir >= 190) AND (wnd_dir < 209))) + Wnd_Scalar_1st_Occurrence = 7 + ElseIf ((wnd_dir > 170) AND (wnd_dir < 190)) + Wnd_Scalar_1st_Occurrence = 0 + EndIf + + '1st case + If (RNS_Scalar_1st_Occurrence = 0) OR (ITC_Scalar_1st_Occurrence =0) OR (Wnd_Scalar_1st_Occurrence = 0) Then 'Any in category 9 (0 used for 9) + QC = 9 + + '2nd case + Else + MaxSpa (Lowest_Seq_Max(1), 3, RNS_Scalar_1st_Occurrence) + QC = Lowest_Seq_Max(1) + EndIf + + '3rd case + If (((RNS = NaN) OR (ITC_wTs = NaN) OR (wnd_dir = NaN)) AND (QC = 9)) Then QC = NaN +EndSub +'*** End of subroutines for data quality classification *** + +'*** Beginning of subroutines for footprint characteristics *** +' 1. Footprint of Kljun et al. (2004): Footprint characteristics +' SUBROUTINE MAIN PROGRAM +' Ustar u_star +' Sigma_w w_std_R +' height_aerodynamic z +' Obukhov L +' roughness z0 +' upwnd_dist upwnd_dist_intrst Upwind range of interest (measurement targeted range) +' FP_win_range FP_dist_intrst Percentage of measured scalar flux from upwind range of interest +' x_max FP_max Upwind location of source/sink that contributes most to the measured flux +' FP_40pct_range FP_40 Upwind range within which the source/sink contributes 40% to the measured flux +' FP_55pct_range FP_55 Upwind range within which the source/sink contributes 55% to the measured flux +' FP_90pct_range FP_90 Upwind range within which the source/sink contributes 90% to the measured flux + +Sub FootprintCharacteristics_Kljun(Ustar, Sigma_w, height_aerodynamic, Obukhov, roughness, upwnd_dist, FP_win_range, x_max, FP_40pct_range, FP_55pct_range,FP_90pct_range) + '*** Variables used inside subroutine + 'Model parameters + Dim k1, k2, k3, k4 'Parameters in the model of Kljun et al (2004) + Dim h_PBL 'Planetary Boudary-Layer height + + 'Composit variables repeatedly used in iterational computation + Dim zh_ratio 'Ratio of aerodynamic height to planetary boundary-layer height (height_aerodynamic/h_PBL) + Dim suz 'for repeately used variable of ((Sigma_w/Ustar)^0.8)/height_aerodynamic + Dim k1_suz_zh 'for repeately used variable of k1*[((Sigma_w/Ustar)^0.8)*(1-height_aerodynamic/h_PBL)/height_aerodynamic] + + 'Working variables + Dim FP_cumulative 'Cumulative_footprint + Dim FP_cumulative_prev 'Cumulative_footprint in a previous iteration + Dim x_inflection_L 'x at the left inflection point of footprint (i.e. x_inflection_L < x_max) where x is the upwind distance to measurement station + Dim x_inflection_R 'x at the right inflection point of footprint (i.e. x_inflection_R > x_max) where x is the upwind distance to measurement station + Dim x_L 'x at the left boundary of an integration interval where x is the upwind distance to measurement station + Dim x_R 'x at the right boundary of an integration interval where x is the upwind distance to measurement station + Dim Integration_interval 'Interval for numerical integration (i.e. x_R - x_L) + + 'Variables for use of Boole's Rule for numerical integration + Dim FP_L 'footprint at x = x_L + Dim FP_M1 'footprint at x = x_L + 0.25*(x_R - x_L) + Dim FP_M2 'footprint at x = x_L + 0.50*(x_R - x_L) + Dim FP_M3 'footprint at x = x_L + 0.75*(x_R - x_L) + Dim FP_R 'footprint at x = x_R + + Dim Interval_count 'Used to calculate the number of intervals needed for numerical integration after FP_90pct_range was calculated, but before upwnd_dist is reached + Dim J As Long 'Used for index of iteration. The upcase letter J is used to keep the editor's auto-correct feature + 'From changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + + 'Calculate paramerters in Kljun et al (2004)]. + k1 = 0.175/(3.418 - LN(roughness)) 'page 515 & 516, left top panel in Fig. 7 and eq. (13). Email from Dr. Kljun on Feb 10, 2015 + k2 = 3.68254 'page 515 & 516, right top panel in Fig. 7 and eq.(14). Calculated from eq.(10) using k1 and k3 + k3 = 4.277*(3.418 - LN(roughness)) 'page 515 & 516, left bottom panel in Fig. 7 and eq.(15). Email from Dr. Kljun on Feb 10, 2015 + k4 = 1.685*(3.418 - LN(roughness)) 'page 515 & 516, right bottom panel in Fig. 7 and eq.(16). Email from Dr. Kljun on Feb 10, 2015 + + If ((Ustar <> NaN) AND (Sigma_w <> NaN) AND (Obukhov <> NaN)) Then + 'Estimate planetary boudary-layer (PBL) height using data in the L and h colums in Table I in Kljun et al (2004) + Select Case Obukhov + Case Is <= 0 + 'h_PBL = 1000 m when Obukhov is -infinity. h_PBL = 1200 m at Obukhov = -650. Assume when Obukhov is <-650, h_PBL will decreases at the same rate + 'as h_PBL decreases when -650 < Obukhov <-30. Thus h_PBL reaches the limit of 1000 m at Obukhov = -1013.3; therefore, h_PBL = 1000 m if Obukhov <= -1013.3. + If (Obukhov < -1013.3) Then + h_PBL = 1000 'Set h_PBL = 1000 m as long as Obukhov < -1013.3 m. + ElseIf (Obukhov <= -650) Then + h_PBL = 1200 - 200*((Obukhov + 650)/(-1013.3+650)) + ElseIf (Obukhov <= -30) Then + h_PBL = 1500 - 300*((Obukhov + 30)/(-650+30)) + ElseIf (Obukhov <= -5) Then + h_PBL = 2000 - 500*((Obukhov + 5)/(-30+5)) + ElseIf (Obukhov <= 0) Then + h_PBL = 2000 + 20* (Obukhov + 5) 'Extrapolation to Obukhov --> -0. + EndIf + + Case Is > 0 + 'h_PBL = 1000 m when Obukhov is +infinity, and h_PBL = 800 m at Obukhov = 1000. Assume that h_PBL becomes higher with Obukhov at the same rate + 'as in the Obukhov range of 130 to 1000. Thus h_PBL reaches the limit of 1000 m at Obukhov = 1316.4; therefore, h_PBL = 1000 m if Obukhov > 1316.4 + If (Obukhov > 1316.4) Then + h_PBL = 1000 'Set h_PBL = 1000 m as long as Obukhov > 1316.4 m. + ElseIf (Obukhov >= 1000) Then + h_PBL = 800 + 200*((Obukhov - 1000)/(1316.4-1000)) + ElseIf (Obukhov >= 130) Then + h_PBL = 250 + 550*((Obukhov -130)/(1000 - 130)) + ElseIf (Obukhov >= 84) Then + h_PBL = 200 + 50*((Obukhov - 84)/(130 -84)) + ElseIf (Obukhov > 0) Then + h_PBL = 200 - (84 - Obukhov)*(50/46) 'Extrapolation to Obukhov --> +0 + EndIf + EndSelect + + 'Calculate variables repeatedly used inside iteration loops + zh_ratio = height_aerodynamic/h_PBL + suz = ((Sigma_w/Ustar)^0.8)/height_aerodynamic + k1_suz_zh = k1*suz*(1-zh_ratio) + + 'Upwind location of source/sink that contributes most to the measured flux + x_max = (k3 - k4)/suz + x_inflection_L = x_max*(k3*((SQR(k2) - 1)/SQR(k2))-k4)/(k3-k4) 'x at the left inflection point of footprint (i.e. < x_max) + x_inflection_R = x_max*(k3*((SQR(k2) + 1)/SQR(k2))-k4)/(k3-k4) 'x at the right inflection point of footprint (i.e. > x_max) + + 'reset variables + FP_cumulative = 0 + FP_win_range = 0 + FP_40pct_range = 0 + FP_55pct_range = 0 + FP_90pct_range = 0 + + '***Calculate footprint characteristics: FP_win_range, FP_40pct_range, FP_55pct_range, and FP_90pct_range + ' Use five numerical integration segments to calculate the footprint characteristics + ' 1st: starting point of footprint defined (-k4/suz) to the left footprint inflection point (x_inflection_L) + ' 2nd: the left footprint inflection point to the footprint maximum (x_max) + ' 3rd: the footprint maximum to the right footptint inflection point (x_inflection_R) then further to [x_inflection_R + (x_inflection_R - x_max)] + ' 4th: from x > [x_inflection_R + (x_inflection_R - x_max)] or x at culumutive footprint > 90% and then until the distance of interest is reached + ' but limited x_max + 200*height_aerodynamic (x_200z). + ' 5th: If upwind range of interest has not been reached, this segment is integrated from x at FP_90 = 90% (x_90) + ' oR x_max + 200*height_aerodynamic (x_200z) to upwind distance of interest, but limited to x_90 (or x_200z) + 100*height_aerodynamic. + + ' Use a high resolution of integration intervals for the first three segments + ' a lower resolution for the 4th and 5th segments, but high precision numerical method of Boole's Rule + + '1st numerical integration segment: Upwind range until x reaches left inflection point + 'Preparation for use of x_L and x_R inside an iteration + x_R = - k4/suz 'Initialization. This value will be used for the starting point of integration + Integration_interval = (x_inflection_L - x_R)/NMBR_INT_INTERV_SEGMENT 'Use x at the left inflection point as a ending boundary of the 1st numerical integration segment + FP_R = 0 'Pre-calculation + + For J = 1 To NMBR_INT_INTERV_SEGMENT + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integration interval + FP_L = FP_R + + 'Footprint value at the right boundary of integration interval + FP_R = (suz*x_R + k4)/k3 'Pre-calculation + FP_R = k1_suz_zh*(FP_R^k2)*EXP(k2*(1 - FP_R)) + + 'The trapezoidal rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Next J + + '2nd numerical integration segment: Upwind range from the left footprint inflection point to the maxmum footprint + Integration_interval = (x_max - x_inflection_L)/NMBR_INT_INTERV_SEGMENT 'For numerical integration, use x at the left inflection point as the starting boundary and x_max as the ending boundary + + 'Upwind range within x_max + For J = 1 To NMBR_INT_INTERV_SEGMENT + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integration interval + FP_L = FP_R + + 'Footprint value at the right boundary of integration interval + FP_R = (suz*x_R + k4)/k3 'Pre-calculation + FP_R = k1_suz_zh*(FP_R^k2)*EXP(k2*(1 - FP_R)) + + 'The trapezoidal rule used for an individual interval to cumulate footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If (FP_cumulative >= 0.55) AND (FP_55pct_range = 0) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Next J + + '3rd numerical integration segment: Upwind range from the maximum footprint to the right footprint inflection point and then further + 'to [x_inflection_R + (x_inflection_R -x_max)] or until 90% of footprint is found + Integration_interval = (x_inflection_R - x_max)/NMBR_INT_INTERV_SEGMENT 'For numerical integration, use x_max as the starting boundary and x at the right inflection point as the middle boundary + + For J = 1 To 2*NMBR_INT_INTERV_SEGMENT 'Using the fine resolution for integration even beyong x_inflection_R to to [x_inflection_R + (x_inflection_R -x_max)] + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integration interval + FP_L = FP_R + + 'Footprint value at the right boundary of an integration interval + FP_R = (suz*x_R + k4)/k3 'Pre-calculation + FP_R = k1_suz_zh*(FP_R^k2)*EXP(k2*(1 - FP_R)) + + 'The trapezoidal rule used for an individual interval to cumulate footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If (FP_cumulative >= 0.55) AND (FP_55pct_range = 0) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 90% footprint distance + If (FP_cumulative >= 0.9) AND (FP_90pct_range = 0) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + Exit For + EndIf + Next J + + '4th numerical integration segment: x > [x_inflection_R + (x_inflection_R - x_max)] or culumutive footprint > 90% + 'Use lower integration resolution, but more accurate numerical integration method of Boole's Rule + Integration_interval = 4*height_aerodynamic + + 'If upwind range of 90% footprint is not reached. Continue to calculate + While ((FP_cumulative < 0.9) AND (x_R - x_max < 200*height_aerodynamic)) + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + '*** Boole's Rule for numerical integration *** + 'Footprint value at the left boundary of an integration interval + FP_L = FP_R + + FP_M1 = (suz*(x_L + 0.25*Integration_interval) + k4)/k3 'Pre-calculation + FP_M1 = k1_suz_zh*(FP_M1^k2)*EXP(k2*(1 - FP_M1)) + + FP_M2 = (suz*(x_L + 0.50*Integration_interval) + k4)/k3 'Pre-calculation + FP_M2 = k1_suz_zh*(FP_M2^k2)*EXP(k2*(1 - FP_M2)) + + FP_M3 = (suz*(x_L + 0.75*Integration_interval) + k4)/k3 'Pre-calculation + FP_M3 = k1_suz_zh*(FP_M3^k2)*EXP(k2*(1 - FP_M3)) + + 'Footprint value at the right boundary of an integration interval + FP_R = (suz*x_R + k4)/k3 'Pre-calculation + FP_R = k1_suz_zh*(FP_R^k2)*EXP(k2*(1 - FP_R)) + + 'Boole's Rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(7*FP_L + 32*FP_M1 + 12*FP_M2+ 32*FP_M3+ 7*FP_R)/90 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If ((FP_cumulative >= 0.4) AND (FP_40pct_range = 0)) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If ((FP_cumulative >= 0.55) AND (FP_55pct_range = 0)) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Wend + + 'Find the 90% footprint distance + If ((FP_cumulative >= 0.90) AND (FP_90pct_range = 0)) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Assign FP_90pct_range as NaN if culmulative footprint can not reach 0.9 within x_max + 200*height_aerodynamic + If ((FP_cumulative < 0.90) AND (FP_90pct_range = 0)) Then + FP_90pct_range = NaN + EndIf + + '5th numerical integration segment. + 'If upwind range of interest has not been reached, this segment is integrated from x at FP_90 = 90% (x_90) + 'or x_max + 200*height_aerodynamic (x_200z) to upwind distance of interest, but limited to x_90 (or x_200z) + 100*height_aerodynamic. + + If (x_R < upwnd_dist) Then + + ' Control the integration w/in 25 iterations after above integrations + If ((upwnd_dist - x_R) < (100*height_aerodynamic)) Then + + Interval_count = INT((upwnd_dist - x_R)/Integration_interval) + Integration_interval = (upwnd_dist - x_R)/Interval_count 'Rescale the intergration interval + + For J = 1 To Interval_count 'To Upwnd_dist, the cumulative footprint is enough + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + '*** Boole's Rule for numerical integration ***** + 'Footprint value in the left boundary of integration interval + FP_L = FP_R + + FP_M1 = (suz*(x_L + 0.25*Integration_interval) + k4)/k3 'Pre-calculation + FP_M1 = k1_suz_zh*(FP_M1^k2)*EXP(k2*(1 - FP_M1)) + + FP_M2 = (suz*(x_L + 0.50*Integration_interval) + k4)/k3 'Pre-calculation + FP_M2 = k1_suz_zh*(FP_M2^k2)*EXP(k2*(1 - FP_M2)) + + FP_M3 = (suz*(x_L + 0.75*Integration_interval) + k4)/k3 'Pre-calculation + FP_M3 = k1_suz_zh*(FP_M3^k2)*EXP(k2*(1 - FP_M3)) + + 'Footprint value in the right boundary of integration interval + FP_R = (suz*x_R + k4)/k3 'Pre-calculation + FP_R = k1_suz_zh*(FP_R^k2)*EXP(k2*(1 - FP_R)) + + 'Boole's Rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(7*FP_L + 32*FP_M1 + 12*FP_M2+ 32*FP_M3+ 7*FP_R)/90 + + 'Try to find the 90% footprint distance again + If ((FP_cumulative >= 0.9) AND (FP_90pct_range = NaN)) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + EndIf + Next J + + Select Case FP_cumulative + Case Is < 1.00 + FP_win_range = 100*FP_cumulative + Case Is >=1 + FP_win_range = 99 + EndSelect + + Else + FP_win_range = 99 + EndIf + + EndIf + + Else + x_max = NaN + FP_win_range = NaN + FP_40pct_range = NaN + FP_55pct_range = NaN + FP_90pct_range = NaN + EndIf +EndSub + +' 2. Footprint of Kormann and Meixner (2001) +' SUBROUTINE MAIN PROGRAM +' Ustar u_star +' height_aerodynamic z +' Stability stability_zL +' U rslt_wnd_spd +' upwnd_dist upwnd_dist_intrst Upwind range of interest (measurement target) +' FP_win_range FP_dist_intrst Percentage of measured scalar flux from upwind range of interest +' x_max FP_max Upwind location of source/sink that contributes most to the measured flux +' FP_40pct_range FP_40 Upwind range within which the source/sink contributes 40% to the measured flux +' FP_55pct_range FP_55 Upwind range within which the source/sink contributes 55% to the measured flux +' FP_90pct_range FP_90 Upwind range within which the source/sink contributes 90% to the measured flux + +Sub FootprintCharacteristics_KormannMeixner (Ustar, height_aerodynamic, Stability, U, upwnd_dist, FP_win_range, x_max, FP_40pct_range, FP_55pct_range, FP_90pct_range) + 'Parameters in the vertical profiles of horizontal wind and eddy diffusivity + Dim m_KM 'Exponent of vertical profile of horizontal wind in footprint of Kormann and Meixner (2001) + Dim n_KM 'Exponent of vertical profile of eddy diffusivity in footprint of Kormann and Meixner (2001) + Dim wnd_const 'Wind constant in the vertical profile of horizontal wind + + 'Composite variables + Dim r_KM 'Shape factor (r_KM =2 + m_KM - n_KM) in footprint of Kormann and Meixner (2001) + Dim Xi 'wnd_const/(k*r_KM^2) where k is von Kerman constant (0.41) + Dim Mu '(m_KM + 1)/r_KM + Dim Gamma_Mu 'Gamma function of Mu + Dim xgz '((Xi^Mu)*(height_aerodynamic^(m_KM +1)))/Gamma_Mu + Dim xz 'Xi*height_aerodynamic^r_KM + + 'Working variables + Dim FP_cumulative 'Cumulative_footprint + Dim FP_cumulative_prev 'Cumulative_footprint in a previous iteration + Dim x_inflection_L 'x at the left inflection point of footprint (i.e. x_inflection_L < x_max) where x is upwind distance to measurement station + Dim x_inflection_R 'x at the right inflection point of footprint (i.e. x_inflection_R > x_max) where x is upwind distance to measurement station + Dim x_L 'x at the left boundary of integration interval where x is upwind distance to measurement station + Dim x_R 'x at the right boundary of integration interval where x is upwind distance to measurement station + Dim Integration_interval 'Interval for numerical integration (i.e. x_R - x_L) + + 'Variables for use of Boole's rule + Dim FP_L 'footprint at x = x_L + Dim FP_M1 'footprint at x = x_L + 0.25*(x_R - x_L) + Dim FP_M2 'footprint at x = x_L + 0.50*(x_R - x_L) + Dim FP_M3 'footprint at x = x_L + 0.75*(x_R - x_L) + Dim FP_R 'footprint at x = x_R + + Dim Interval_count 'Used to calculate interval number after FP_90pct_range calculated, but before Upwnd_dist reaches + Dim J As Long 'Used for index of iteration. The upcase letter J is used to keep the editor's auto-correct feature + 'From changing the case of J in units as lowcase (e.g. J/s m^2) throughout the program. + + + If ((Ustar <> NaN) AND (Stability <> NaN) AND (U <> NaN)) Then + 'Calculate the exponent of vertical profile of horizontal wind and the exponent of vertical profile of eddy diffusivity + + If (Stability > 0) Then + 'Similarity functions are defined in a range of z/L from -2 to 2 (pages 28, 41~43, Kaimal & Finnigan 1994). Extened to +/-4 as shown in Fig 5.23 in Stull (1988) + Select Case Stability + Case Is <= 4.0 + m_KM = (Ustar/(k*U))*(1 + 5*Stability) 'Exponent of vertical profile of horizontal wind + n_KM = 1/(1 + 5*Stability) 'Exponent of vertical profile of eddy diffusivity + + Case Is > 4 + m_KM = (Ustar/(k*U))*(1 + 5*4) 'Exponent of vertical profile of horizontal wind + n_KM = 1/(1 + 5*4) 'Exponent of vertical profile of eddy diffusivity + EndSelect + Else + Select Case Stability + Case Is >= -4.0 + m_KM = (Ustar/(k*U))/((1 - 16*Stability)^0.25) 'Exponent of vertical profile of horizontal wind + n_KM = (1-24*Stability)/(1 - 16*Stability) 'Exponent of vertical profile of eddy diffusivity + + Case Is < -4.0 + m_KM = (Ustar/(k*U))/((1 - 16*(-4))^0.25) 'Exponent of vertical profile of horizontal wind + n_KM = (1-24*(-4))/(1 - 16*(-4)) 'Exponent of vertical profile of eddy diffusivity + EndSelect + EndIf + + 'Calculate the wind constant in the vertical profile of horizontal wind + wnd_const = U/(height_aerodynamic^m_KM) 'Wind constant + + 'Calculate the composite variables + r_KM = 2 + m_KM - n_KM 'Shape factor + + Xi = wnd_const/(k*r_KM*r_KM) + Mu = (m_KM + 1)/r_KM + + Gamma_Mu = SQR(2*PI/Mu)*(((Mu + 1/(12*Mu - 0.1/Mu))/EXP(1))^Mu) 'Nemes (2007) + + xgz = ((Xi^Mu)*(height_aerodynamic^(m_KM +1)))/Gamma_Mu + xz = Xi*(height_aerodynamic^r_KM) + + 'Turnning and inflection points + x_max = xz/(Mu + 1) 'Upwind location of source/sink that contributes most to the measured flux + x_inflection_L = x_max*(1 - 1/SQR(Mu + 2)) 'x at the left footprint inflection point + x_inflection_R = x_max*(1 + 1/SQR(Mu + 2)) 'x at the right footprint inflection point + + 'Reset variables + FP_cumulative = 0 + FP_win_range = 0 + FP_40pct_range = 0 + FP_55pct_range = 0 + FP_90pct_range = 0 + + '***Calculate footprint characteristics: FP_win_range, FP_40pct_range, FP_55pct_range, and FP_90pct_range + ' Use five numerical integration segments to calculate the footprint characteristics + ' 1st: starting segment from 0 (+ Delt-->0) to the left footprint inflection point (x_inflection_L) + ' 2nd: the left footprint inflection point to the footprint maximum (x_max) + ' 3rd: the footprint maximum to the right footptint inflection point (x_inflection_R) then further to [x_inflection_R + (x_inflection_R - x_max)] or until cumulative footprint reaches 90% + ' 4th: from x > [x_inflection_R + (x_inflection_R - x_max)] or x at culumutive footprint > 90% and then until the distance of interest is reached, + ' but limited x_max + 200*height_aerodynamic (x_200z). + ' 5th: If upwind range of interest has not been reached, this segment is integrated from x at FP_90 = 90% (x_90) + ' or x_max + 200*height_aerodynamic (x_200z) to upwind distance of interest, but limited to x_90 (or x_200z) + 100*height_aerodynamic. + + ' Use a high resolution of integration intervals for the first three segments + ' a lower resolution for the 4th and 5th segments, but high precision numerical method of Boole's rule + + '1st numerical integration segment: Upwind range within the left inflection point + x_R = 0 'Reset + Integration_interval = x_inflection_L/NMBR_INT_INTERV_SEGMENT 'In numerical integration, use x at the left footprint inflection point as the ending boundary of this segment + FP_R = 0 'Reset + + 'Upwind range within the left inflection point + For J = 1 To NMBR_INT_INTERV_SEGMENT + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integral interval + FP_L = FP_R + + 'Footprint value at the right boundary of integral interval + FP_R = xgz*EXP(-xz/x_R)/(x_R^(Mu + 1)) + + 'The trapezoidal rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Next J + + '2nd numerical integration segment: Upwind range from the left footprint inflection point to the maximum footprint + Integration_interval = (x_max - x_inflection_L)/NMBR_INT_INTERV_SEGMENT 'In this segment, use x at the left inflection point as the starting boundary and x_max as the ending boundary + + For J = 1 To NMBR_INT_INTERV_SEGMENT + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integral interval + FP_L = FP_R + + 'Footprint value at the right boundary of integral interval + FP_R = xgz*EXP(-xz/x_R)/(x_R^(Mu + 1)) + + 'The trapezoidal rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If (FP_cumulative >= 0.55) AND (FP_55pct_range = 0) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Next J + + '3rd numerical integration segment: Upwind range from the maximum footprint to the right footprint inflection point and further to [x_inflection_R + (x_inflection_R -x_max)] or until 90% footprint is reached + Integration_interval = (x_inflection_R - x_max)/NMBR_INT_INTERV_SEGMENT 'In this segment, use x_max as the starting boundary and x at the right inflection point as the boundary of middle interval + + 'Upwind range within two times of range from x_max to the right inflection point + For J = 1 To 2*NMBR_INT_INTERV_SEGMENT 'The fine resolution of integration is used even beyong x_inflection_R to [x_inflection_R + (x_inflection_R -x_max)] or until 90% footprint is reached + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + 'Footprint value at the left boundary of integration interval + FP_L = FP_R + + 'Footprint value at the right boundary of integration interval + FP_R = xgz*EXP(-xz/x_R)/(x_R^(Mu + 1)) + + 'The trapezoidal rule used for an individual interval to cumulate footprint + FP_cumulative += Integration_interval*(FP_L + FP_R)/2 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If (FP_cumulative >= 0.4) AND (FP_40pct_range = 0) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If (FP_cumulative >= 0.55) AND (FP_55pct_range = 0) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 90% footprint distance + If (FP_cumulative >= 0.9) AND (FP_90pct_range = 0) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + Exit For + EndIf + + Next J + + '4th numerical integration segment: x > [x_inflection_R + (x_inflection_R - x_max)] or culumutive footprint > 90% + ' Use lower intergration resolution, but the more accurate numerical integration method of Boole's rule + Integration_interval = 4*height_aerodynamic + + 'If upwind range of 90% footprint is not reached. Continue, but limited to x_max + 200*height_aerodynamic + While ((FP_cumulative < 0.9) AND (x_R - x_max < 200*height_aerodynamic)) + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + '*** Boole's rule ***** + 'Footprint value at the left boundary of an integration interval + FP_L = FP_R + + 'Footprint value at the 1st, 2nd, and 3rd quarter integration interval + FP_M1 = xgz*EXP(-xz/(x_L + 0.25*Integration_interval))/((x_L + 0.25*Integration_interval)^(Mu + 1)) + FP_M2 = xgz*EXP(-xz/(x_L + 0.50*Integration_interval))/((x_L + 0.50*Integration_interval)^(Mu + 1)) + FP_M3 = xgz*EXP(-xz/(x_L + 0.75*Integration_interval))/((x_L + 0.75*Integration_interval)^(Mu + 1)) + + 'Footprint value at the right boundary of an integration interval + FP_R = xgz*EXP(-xz/x_R)/(x_R^(Mu + 1)) + + 'The Boole's rule used for an individual interval to cumulate the footprint + FP_cumulative += Integration_interval*(7*FP_L + 32*FP_M1 + 12*FP_M2 + 32*FP_M3 +7*FP_R)/90 + + 'Find the footprint w/in the range of interest + If ((x_L < upwnd_dist) AND (x_R >= upwnd_dist)) Then + FP_win_range = 100*(FP_cumulative_prev + (FP_cumulative - FP_cumulative_prev)*(upwnd_dist - x_L)/Integration_interval) + EndIf + + 'Find the 40% footprint distance + If ((FP_cumulative >= 0.4) AND (FP_40pct_range = 0)) Then + FP_40pct_range = x_R - Integration_interval*(FP_cumulative - 0.4)/(FP_cumulative - FP_cumulative_prev) + EndIf + + 'Find the 55% footprint distance + If ((FP_cumulative >= 0.55) AND (FP_55pct_range = 0)) Then + FP_55pct_range = x_R - Integration_interval*(FP_cumulative - 0.55)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Wend + + 'Find the 90% footprint distance + If ((FP_cumulative >= 0.90) AND (FP_90pct_range = 0)) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + EndIf + + ' Assign FP_90pct_range as NaN if culmulative footprint can not reach 0.9 within x_max + 200*height_aerodynamic + If ((FP_cumulative < 0.90) AND (FP_90pct_range = 0)) Then + FP_90pct_range = NaN + EndIf + + ' 5th numerical integration segment: + ' If upwind range of interest has not been reached, this segment is integrated + ' from x at FP_90 = 90% (x_90) or x_max + 200*height_aerodynamic (x_200z)(if FP_90 is not reached) to upwind distance of interest, + ' but limited to x_90 (or x_200z) + 100*height_aerodynamic. + + If (x_R < upwnd_dist) Then + + 'Control the integration w/in 25 iterations after above integrations + If ((upwnd_dist - x_R) < (100*height_aerodynamic)) Then + + Interval_count = INT((upwnd_dist - x_R)/Integration_interval) + Integration_interval = (upwnd_dist - x_R)/Interval_count 'Rescale integration interval + + For J = 1 To Interval_count '100*height_aerodynamic after above integration, the cumulative footprint is enough + x_L = x_R + x_R = x_R + Integration_interval + FP_cumulative_prev = FP_cumulative + + '*** Boole's rule ***** + 'Footprint value at the left boundary of integration interval + FP_L = FP_R + + 'Footprint value at the right boudary of the 1st, 2nd, and 3rd quarter integration interval + FP_M1 = xgz*EXP(-xz/(x_L + 0.25*Integration_interval))/((x_L + 0.25*Integration_interval)^(Mu + 1)) + FP_M2 = xgz*EXP(-xz/(x_L + 0.50*Integration_interval))/((x_L + 0.50*Integration_interval)^(Mu + 1)) + FP_M3 = xgz*EXP(-xz/(x_L + 0.75*Integration_interval))/((x_L + 0.75*Integration_interval)^(Mu + 1)) + + 'Footprint value at the right boundary of integration interval + FP_R = xgz*EXP(-xz/x_R)/(x_R^(Mu + 1)) + + FP_cumulative += Integration_interval*(7*FP_L + 32*FP_M1 + 12*FP_M2 + 32*FP_M3 +7*FP_R)/90 + + 'Try FP FP_90pct_range again in case that FP_90pct_range is not resolved + If ((FP_cumulative >= 0.9) AND (FP_90pct_range = NaN)) Then + FP_90pct_range = x_R - Integration_interval*(FP_cumulative - 0.9)/(FP_cumulative - FP_cumulative_prev) + EndIf + + Next J + + Select Case FP_cumulative + Case Is < 1.00 + FP_win_range = 100*FP_cumulative + Case Is >=1 + FP_win_range = 99 + EndSelect + + Else + FP_win_range = 99 + EndIf + + EndIf + + Else + x_max = NaN + FP_win_range = NaN + FP_40pct_range = NaN + FP_55pct_range = NaN + FP_90pct_range = NaN + EndIf +EndSub +'*** End of subroutines for footprint characteristics *** + +#If (SENSOR_FW) Then +'*** Beginning self-defined function for time constant of FW sensor **** +' SUBROUTINE MAIN PROGRAM +' FW_D FW_diameter +' FW_temperature fw_avg +' U rslt_wnd_spd +' density_moist_air rho_a_avg +Function Time_Const_Thermocouple_E(FW_D, FW_temperature, U, density_moist_air) + Const C_TC_E = 420.7734 'Specific heat of junction of thermocouple E [J/(kg C)] + Const rho_TC_E = 8825 'Specific gravity (material density) of junction of thermocouple E [Kg/m^3] + + Dim K_air 'Thermal conductivity of air [W/(m C)] + Dim mu_air 'Viscosity of air [kg/(m s)] + Dim Re 'Reynolds number (dimensionless) + Dim Nu 'Nusselt number (dimensionless) + + K_air = 2.42508e-2 + 7.038086e-5*FW_temperature 'Table 1 Montgomery (1947) + mu_air = 1.716800e-5 + 4.982100e-8*FW_temperature 'Table 1 Montgomery (1947) + + Re = (2*density_moist_air*FW_D*U)/mu_air + Nu = 2.0 + 0.18*Re^0.67 + + Return ((0.250*FW_D*FW_D*rho_TC_E*C_TC_E)/(K_air*Nu)) +EndFunction +#EndIf + +' Calculate separation of scalar sensor sensing center to CSAT measurement center +' 1. Separation distance normal to wind direction (effective separation distance) +' 2. Separation distance along with wind direction (effective lag distance) +' SUBROUTINE MAIN PROGRAM +' wnd_dir wnd_dir_sonic +' separation_x separation_x_IRGA or separation_x_FW +' separation_y separation_y_IRGA or separation_y_FW +' separation_lat_dis separation_lat_dist_IRGA or separation_lat_dist_FW +' separation_lag_dis separation_lag_dist_IRGA or separation_lag_dist_FW + +Sub Separation_Lag_Lateral_Distances (wnd_dir, separation_x, separation_y, separation_lat_dis, separation_lag_dis) + separation_lag_dis = separation_x*COS(wnd_dir) + separation_y*SIN(wnd_dir) + separation_lat_dis = -separation_x*SIN(wnd_dir) + separation_y*COS(wnd_dir) +EndSub + +'********************' +'*** MAIN PROGRAM ***' +'*********************' +BeginProg + #If (SENSOR_HFP) Then + + 'Load calibrations of soil heat flux plate. + For i = 1 To NMBR_SHFP + Read shf_plate_cal(i) + Next i + + #EndIf + + ' *** Beginning to store and read station variables in CPU *** + sys_conf_var_file = FileOpen ("CPU:sys_conf_var.dat", "rb", 0) 'Open file and check if a file exists. + FileClose (sys_conf_var_file) 'Close file after check + + If (sys_conf_var_file = 0) Then + ' Set default values of station variables (Default values of 0 are listed for code readibilty) + sonic_azimuth = 0 + latitude = 41.766 'Latitude of Campbell Scientific Campus, Logan, UT, USA + hemisphere_NS = 1 '"1" for north and "-1" for south. Campbell Scientific Campus is located in Noth Hemisphere + longitude = 111.855 'Longitude of Campbell Scientific Campus, Logan, UT, USA + hemisphere_EW = -1 '"1" for east and "-1" for west. Campbell Scientific Campus is located in West Hemisphere + height_measurement = 3 + displacement_user = 0 '"0" indicates that the user DOES NOT have preferred zero displacement height + height_canopy = 0 + surface_type = BARELAND + roughness_user = 0 '"0" indicates that the user DOES NOT have preferred roughness length + + Select Case SENSOR_IRGASON + Case TRUE + separation_x_irga = 0 'Coordinate x of IRGASON IRGA measurement center in the sonic coordinate system + separation_y_irga = 0 'Coordinate y of IRGASON IRGA measurement center in the sonic coordinate system + Case FALSE + separation_x_irga = 0.04066 'Range: 0.04066 ~0.09126 m: Coordinate x of EC150 IRGA measurement center in the sonic coordinate system + separation_y_irga = 0.02905 'Range: 0.02905 ~0.03348 m: Coordinate y of EC150 IRGA measurement center in the sonic coordinate system + EndSelect + + #If (SENSOR_FW) Then + separation_x_FW = 0.35787-0.35200 'Coordinate x of fine wire thermocouple junction in the sonic coordinate system (0.35200 is the default length of FW sensor) + separation_y_FW = 0.03259 'Coordinate y of fine wire thermocouple junction in the sonic coordinate system + FW_diameter = FW05DIA 'Diameter of fine wire thermocouple + #EndIf + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + soil_bulk_density = 1300 'Default soil bulk density (kg/m^3) + Cds = 870 'Default specific heat of dry mineral soil [J/(kg K)] [Table 8.2 on page 118 in Campbell & Norman (1998)] + thick_abv_SHFP = 0.08 'Default depth of HFP01 or HFP01SC below soil surface (m) + #EndIf + + Calfile (stn_conf_array(1), NMBR_STN_VAR, "CPU:sys_conf_var.dat", 0) 'Store the default values to the file. + + Else + + Calfile (stn_conf_array(1), NMBR_STN_VAR, "CPU:sys_conf_var.dat", 1) 'Read the stored values from the file. + + EndIf + + 'IF IRGASON, but previously CSAT3A+EC150, automatically reset + If (SENSOR_IRGASON) Then + separation_x_irga = 0 'Coordinate x of IRGASON IRGA measurement center in the sonic coordinate system + separation_y_irga = 0 'Coordinate y of IRGASON IRGA measurement center in the sonic coordinate system + EndIf + + '*** Beginning to calculate zero displacement height, roughness length, and aerodynamic height for use inside the scan *** + Call Displacement_Roughness_heights (surface_type, displacement_user, roughness_user, height_canopy, height_measurement, d, z0, z) + '*** End of calculate zero displacement height, roughness length, and aerodynamic height for use inside the scan *** + + For i = 13 To 16 + If (NOT (stn_conf_array(i) > 0)) Then + stn_conf_array(i) = 100*z 'Default value of 100*z for all sectors in different directions + EndIf + Next + + z_prev = z + Move(stn_conf_array_prev(1), NMBR_STN_VAR , stn_conf_array(1), NMBR_STN_VAR) 'Keep current values of stn_conf_array() in stn_conf_array_prev() for later reference as previou values + surface_type_text = surface_type_array(surface_type) + + ' *** End to store and read station variables in CPU *** + + ' *** Beginning to store and read planar fit angles in CPU *** + sys_conf_var_file = FileOpen ("CPU:sys_planar_fit_angles.dat","rb",0) 'Open the file and check if a file exists + FileClose (sys_conf_var_file) 'Close file after check + + If (sys_conf_var_file = 0) Then + Move (planar_fit_angle_array(1,1), 8 , 0, 1) 'Default values of 0 are listed for code reading + Calfile (planar_fit_angle_array(1, 1), 8, "CPU:sys_planar_fit_angles.dat", 0)'Store the default values to the file + Else + Calfile (planar_fit_angle_array(1, 1), 8, "CPU:sys_planar_fit_angles.dat", 1)'Read the values from the file + For i =1 To 4 + If (planar_fit_angle_array (i, 1) <> 0) OR (planar_fit_angle_array (i, 2) <> 0) Then + Planar_Fit_flg = TRUE + ExitFor + EndIf + Next i + EndIf + + Move (planar_fit_angle_array_prev(1,1), 8, planar_fit_angle_array(1,1), 8) 'Keep current values PF planar_fit_angle_array() in planar_fit_angle_prev_array() for later reference as previou values + ' *** End of storing and reading Planar Fit Angles in CPU *** + + ' *** Beginning of loading transfer function values of Dijk (2002) *** + For i=1 To 35 + Read tran_func_LA_data_Dijk(1,i) 'Load transfer kl values in Dijk (2002) + Read tran_func_LA_data_Dijk(2,i) 'Load transfer function values of Dijk (2002) + Next i + ' *** End of loading transfer function values of Dijk (2002) *** + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + ' Variables used to calculate the number of seconds from the beginning of the program to the end of the first averaging interval (time interval offset) + RealTime(realtime_array(1)) + Offset_intv_Delta_ht_storage = ((3600*realtime_array(4) + 60*realtime_array(5) + realtime_array(6)) MOD (60*OUTPUT_INTERVAL)) + #EndIf + + 'Set the SDM clock speed. + SDMSpeed (SDM_PER) + + '*************************** SCAN LOOP ************************************************** + Scan (SCAN_INTERVAL, mSec, SCAN_BUFFER_SIZE, 0) + 'Datalogger panel temperature + PanelTemp (panel_tmpr, 250) + + #If (SENSOR_TE525mm) Then 'This is placed at beginning of scan because PulseCount() is not allowed in any conditional statements. + '*** Beginning of Precipitation measurements *** + PulseCount (Precipitation, 1, TE525_PULSE_INPUT, 2, 0, TE525_MULT, 0) + '*** End of Precipitation measurements *** + #EndIf + + #If (SENSOR_FW) Then + '*** Beginning of FW measurements *** + diag_FW_raw = 0 + TCDiff (FW_raw, 1, mV20, FW_ANALOG_INPUT, TypeE, panel_tmpr, TRUE, 450, 250, 1, 0) + If (FW_raw = NaN) OR (FW_raw > 80) OR (FW_raw < -50) Then diag_FW_raw = -1 + + CallTable delay_fw + '*** End of FW measurements *** + #EndIf + + '*** Beginning of CSI IRGA + sonic measurements *** + 'Get EC100 data. + EC100 (sonic_irga_raw(1), EC100_SDM_ADDR, 1) '1st to 5th elements: Sonic data and 6th to 12rd elements: IRGA, air temperature, and pressure data + CallTable delay_3d 'Sonic data + CallTable delay_cs 'IRGA, air temperature, and pressure data + + If (sonic_irga_raw(8) = NAN) Then 'The EC150 diagnostic word (diag_irga) is sonic_irga_raw(8). + NAN_cnt += 1 + Else + If (NAN_cnt > 4) Then configure_ec100_flg = TRUE + NAN_cnt = 0 + EndIf + + If (sonic_irga_raw(8) <> NAN) Then + + If (configure_ec100_flg) Then + Call Config (config_array(1,1), 4, configure_ec100_flg) + + ElseIf (set_press_source_flg) Then + press_source_array(1,2) = press_source + Call Config (press_source_array(1,1), 1, set_press_source_flg) + + ElseIf (do_zero_flg) Then + Call Config (zero_array(1,1), 1, do_zero_flg) + + ElseIf (do_CO2_span_flg) Then + span_CO2_array(1,2) = CO2_span_gas + Call Config (span_CO2_array(1,1), 2, do_CO2_span_flg) + + ElseIf (do_H2O_span_flg) + span_H2O_array(1,2) = Td_span_gas + Call Config (span_H2O_array(1,1), 2, do_H2O_span_flg) + + ElseIf (set_heater_flg) Then + Call Config (heater_option_array(1,1), 1, set_heater_flg) + + ElseIf (EC150_power_flg) Then + Call Config (EC150_power_array(1,1), 1, EC150_power_flg) + EndIf + + EndIf + '*** End of CSI IRGA + sonic measurements *** + + If (scan_count >= (OFFSET + MAX_LAG)) Then + + '*** Beginning of sonic head processing *** + 'Load in sonic head data that has been lagged by EC100_REC_BCK scans + GetRecord (dly_data_out(1),delay_3d, EC100_REC_BCK) + + Ts = dly_data_out(4) 'sonic(1): Ts + Move (Ux, 3, dly_data_out(1), 3) 'sonic(2), sonic(3), sonic(4) : Ux, Uy, Uz + diag_sonic = dly_data_out(5) 'sonic(5): diag_sonic + + 'Extract the six warning flags from the sonic diagnostic word + diag_sonic_tmp = IIF ((diag_sonic <> NAN) AND (diag_sonic <> -1), diag_sonic, &h3f) + mask = &h1 + For i = 1 To 6 + diag_bits_sonic(i) = diag_sonic_tmp AND mask + mask = mask*2 + Next i + + 'Turn on the intermediate processing disable flag when any sonic head warning flag is high. + sonic_disable_f = diag_sonic_tmp AND &h3f + + Ts_K = Ts + T_0C_K + + ' Call Table for 5-minute and 30-minute table + CallTable comp_cov_3d_5min 'for Steady State Test + CallTable comp_cov_3d + + ' The data for Steady State Test (SST) + If (comp_cov_3d_5min.Output(1, 1)) Then + GetRecord (u_Avg_SST, comp_cov_3d_5min, 1) + + If (NOT (Planar_Fit_flg)) Then + 'Double coordinate rotations + gamma_5min = wnd_dir_sonic_SST 'Rotation angle about z-axis + alpha_5min = -ATN2(w_Avg_SST, SQR(u_Avg_SST*u_Avg_SST+v_Avg_SST*v_Avg_SST)) 'Rotation angle about intermediate y-axis (range of -90 to 90 degrees) + + ' Rotation for momentum variables + Call Rotation12_Momentum(alpha_5min, gamma_5min, _ + u_Avg_SST, v_Avg_SST, w_Avg_SST, uu_Cov_SST, vv_Cov_SST, ww_Cov_SST, uv_Cov_SST, uw_Cov_SST, vw_Cov_SST, _ + u_Avg_SST_R, v_Avg_SST_R, w_Avg_SST_R, uu_Cov_SST_R, vv_Cov_SST_R, ww_Cov_SST_R,uv_Cov_SST_R, uw_Cov_SST_R, vw_Cov_SST_R) + + 'Rotation for the covariance of sonic temperature with velocities + Call Rotation12_Scalar_Covariance(alpha_5min, gamma_5min, _ + uTs_Cov_SST, vTs_Cov_SST, wTs_Cov_SST, _ + uTs_Cov_SST_R, vTs_Cov_SST_R, wTs_Cov_SST_R) + Else + 'Planar Fit Rotation + If (wnd_dir_sonic_SST <= 60) Then + alpha_5min = alpha_PF_60_300 + beta_5min = beta_PF_60_300 + ElseIf (wnd_dir_sonic_SST <= 170) Then + alpha_5min = alpha_PF_60_170 + beta_5min = beta_PF_60_170 + ElseIf (wnd_dir_sonic_SST < 190) Then + alpha_5min = alpha_PF_170_190 + beta_5min = beta_PF_170_190 + ElseIf (wnd_dir_sonic_SST < 300) Then + alpha_5min = alpha_PF_190_300 + beta_5min = beta_PF_190_300 + Else + alpha_5min = alpha_PF_60_300 + beta_5min = beta_PF_60_300 + EndIf + + ' Rotations for momentum variables + Call Rotation23_Momentum(alpha_5min, beta_5min, _ + u_Avg_SST, v_Avg_SST, w_Avg_SST, uu_Cov_SST, vv_Cov_SST, ww_Cov_SST, uv_Cov_SST, uw_Cov_SST, vw_Cov_SST, _ + u_Avg_SST_R, v_Avg_SST_R, w_Avg_SST_R, uu_Cov_SST_R, vv_Cov_SST_R, ww_Cov_SST_R, uv_Cov_SST_R, uw_Cov_SST_R, vw_Cov_SST_R) + + ' Rotations for the covariance of sonic temperature with velocities + Call Rotation23_Scalar_Covariance(alpha_5min, beta_5min, _ + uTs_Cov_SST, vTs_Cov_SST, wTs_Cov_SST, _ + uTs_Cov_SST_R, vTs_Cov_SST_R, wTs_Cov_SST_R) + EndIf + + If (uw_Cov_SST_R <> NaN) AND (vw_Cov_SST_R <> NaN) AND (wTs_Cov_SST_R <> NaN) Then + RN_uw_cov_R += uw_Cov_SST_R + RN_vw_cov_R += vw_Cov_SST_R + RN_wTs_cov_R += wTs_Cov_SST_R + + nmbr_interval_qc_csat += 1 + EndIf + + EndIf + + If (comp_cov_3d.Output(1, 1) AND comp_cov_3d_5min.Output(1, 1))Then + GetRecord (Ux_Avg, comp_cov_3d, 1) 'Ux_avg is the 1st element of cov_out_sonic + Ts_Std = SQR(Ts_Std) + + '*** Coordinate rotations *** + If (NOT (Planar_Fit_flg)) Then + 'Double coordinate rotations + gamma = wnd_dir_sonic 'Rotation angle about z-axis + alpha = -ATN2(Uz_Avg, SQR(Ux_Avg*Ux_Avg + Uy_Avg*Uy_Avg)) 'Rotation angle about intermediate y-axis (range of -90 to 90 degrees) + + ' Rotation for momentum variables + Call Rotation12_Momentum(alpha, gamma, _ + Ux_Avg, Uy_Avg, Uz_Avg, Ux_Std, Uy_Std, Uz_Std, UxUy_Cov, UxUz_Cov, UyUz_Cov, _ + u_Avg_R, v_Avg_R, w_Avg_R, u_Std_R, v_Std_R, w_Std_R, uv_Cov_R, uw_Cov_R, vw_Cov_R) + 'Here, u_std_R, v_std_R, and w_std_R are uu_cov_R, vv_cov_R, and wv_cov_R. The three variables + 'are converted into standard deviation as indicated by "std" in subsequent calculations + Ux_Std = SQR(Ux_Std) + Uy_Std = SQR(Uy_Std) + Uz_Std = SQR(Uz_Std) + 'Rotation for the covariance of sonic temperature with velocities + Call Rotation12_Scalar_Covariance(alpha, gamma, _ + TsUx_Cov, TsUy_Cov, TsUz_Cov, _ + uTs_Cov_R, vTs_Cov_R, wTs_Cov_R) + Else + 'Planar Fit Rotation + If (wnd_dir_sonic <= 60) Then + alpha = alpha_PF_60_300 + beta = beta_PF_60_300 + ElseIf (wnd_dir_sonic <= 170) Then + alpha = alpha_PF_60_170 + beta = beta_PF_60_170 + ElseIf (wnd_dir_sonic < 190) Then + alpha = alpha_PF_170_190 + beta = beta_PF_170_190 + ElseIf (wnd_dir_sonic < 300) Then + alpha = alpha_PF_190_300 + beta = beta_PF_190_300 + Else + alpha = alpha_PF_60_300 + beta = beta_PF_60_300 + EndIf + + ' Rotations for momentum variables + Call Rotation23_Momentum(alpha, beta, _ + Ux_Avg, Uy_Avg, Uz_Avg, Ux_Std, Uy_Std, Uz_Std, UxUy_Cov, UxUz_Cov, UyUz_Cov, _ + u_Avg_R, v_Avg_R, w_Avg_R, u_Std_R, v_Std_R, w_Std_R, uv_Cov_R, uw_Cov_R, vw_Cov_R) + 'Here, u_std_R, v_std_R, and w_std_R are uu_cov_R, vv_cov_R, and ww_cov_R. The three variables + 'are converted into standard deviation as indicated by "std" in subsequent calculations + Ux_Std = SQR(Ux_Std) + Uy_Std = SQR(Uy_Std) + Uz_Std = SQR(Uz_Std) + ' Rotations for the covariance of sonic temperature with velocities + Call Rotation23_Scalar_Covariance(alpha, beta, _ + TsUx_Cov, TsUy_Cov, TsUz_Cov, _ + uTs_Cov_R,vTs_Cov_R, wTs_Cov_R) + EndIf + '*** End of coordinate rotations *** + + 'Rotate the sonic head RHC system so the negative x-axis points north + wnd_dir_compass = (360 + sonic_azimuth - wnd_dir_sonic) MOD 360 + + 'Compute specific turbulence kinetic energy + TKE = 0.5*(u_Std_R + v_Std_R + w_Std_R) + + 'Compute the standard deviation from the variance after rotation + u_Std_R = SQR (u_Std_R) + v_Std_R = SQR (v_Std_R) + w_Std_R = SQR (w_Std_R) + + '*** Freq corrections for uw_cov_R, vw_cov_R, and wTs_cov_R *** + 'Compute online fluxes after rotations. + u_star_R = SQR(SQR((uw_Cov_R*uw_Cov_R) + (vw_Cov_R*vw_Cov_R))) + + ' Preparation for freq corection to uw_cov_R, vw_cov_R, and wTs_cov_R + ' Obukhov length + L = -u_star_R*u_star_R*u_star_R*(Ts_Avg + T_0C_K)/(k*g0*wTs_Cov_R) + + ' Atmospheric boundary-layer stability + stability_zL = z/L + + FreqFactor_uw_vw_Prev = 0 + Call FreqFactorCSAT_uw_vw_BA_LA(z, stability_zL, rslt_wnd_spd, FreqFactor_uw_vw) + + uw_Cov_R_F = FreqFactor_uw_vw * uw_Cov_R + vw_Cov_R_F = FreqFactor_uw_vw * vw_Cov_R + u_star = SQR(SQR ((uw_Cov_R_F*uw_Cov_R_F) + (vw_Cov_R_F*vw_Cov_R_F))) + + FreqFactor_wTs_Prev = 0 + Call FreqFactorCSAT_wTs_BA_LA (z, stability_zL, rslt_wnd_spd, tran_func_LA_data_Dijk(1,1), FreqFactor_wTs) + + wTs_Cov_R_F = FreqFactor_wTs * wTs_Cov_R + + ' Recalculate Obukhov length + L = -u_star*u_star*u_star*(Ts_Avg+T_0C_K)/(k*g0*wTs_Cov_R_F) + + ' Recalculate atmospheric boundary-layer stability + stability_zL_prev = stability_zL + stability_zL = z/L + + iteration_FreqFactor = 1 + While (((ABS (FreqFactor_uw_vw_Prev -FreqFactor_uw_vw) >= ACCURACY_FREQ_FACTOR) OR _ + (ABS (FreqFactor_wTs_Prev - FreqFactor_wTs) >= ACCURACY_FREQ_FACTOR)) AND ((stability_zL > 0) AND (iteration_FreqFactor <= 10))) + + stability_zL_prev = stability_zL + FreqFactor_uw_vw_Prev = FreqFactor_uw_vw + FreqFactor_wTs_Prev = FreqFactor_wTs + + Call FreqFactorCSAT_uw_vw_BA_LA (z, stability_zL, rslt_wnd_spd, FreqFactor_uw_vw) + uw_Cov_R_F = FreqFactor_uw_vw * uw_Cov_R + vw_Cov_R_F = FreqFactor_uw_vw * vw_Cov_R + u_star = SQR(SQR (uw_Cov_R_F*uw_Cov_R_F + vw_Cov_R_F*vw_Cov_R_F)) + + Call FreqFactorCSAT_wTs_BA_LA (z, stability_zL, rslt_wnd_spd, tran_func_LA_data_Dijk(1,1), FreqFactor_wTs) + wTs_Cov_R_F = FreqFactor_wTs * wTs_Cov_R + + ' Obukhov length + L = -u_star*u_star*u_star*(Ts_Avg+T_0C_K)/(k*g0*wTs_Cov_R_F) + + ' Atmospheric boundary-layer stability + stability_zL = z/L + + iteration_FreqFactor += 1 + Wend + '*** End of freq corrections for uw_cov_R, vw_cov_R, and wTs_cov_R *** + + '*** Beginning of data quality classification for momentum flux *** + 'Calculate the measures of relative non-stationarity (Steady State Test) + RN_uw_vw_cov_R = ABS(((RN_uw_cov_R + RN_vw_cov_R)/nmbr_interval_qc_csat - uw_Cov_R - vw_Cov_R)/(uw_Cov_R + vw_Cov_R)) 'in fraction + Call Data_Quality_Grading_Momentum (Planar_Fit_flg, stability_zL, u_Std_R, w_Std_R, u_star, latitude, wnd_dir_sonic, RN_uw_vw_cov_R, tau_qc_grade) + RN_uw_cov_R = 0 + RN_vw_cov_R = 0 + '*** End of data quality classification for momentum flux *** + + '*** Footprint characteristics of measured fluxes *** + 'Update roughness length when a user does not specify z0 and wind is sufficiently strong during a neutral condition + If ((ABS(stability_zL) < 0.02) AND (roughness_user = 0) AND (rslt_wnd_spd > 3) AND (tau_qc_grade <= 6)) Then z0 = z*EXP(-k*rslt_wnd_spd/u_star) + + 'Determining upwind distance of interest + If (wnd_dir_sonic <= 60) Then + upwnd_dist_intrst = dist_intrst_60_300 + ElseIf (wnd_dir_sonic <= 170) Then + upwnd_dist_intrst = dist_intrst_60_170 + ElseIf (wnd_dir_sonic < 190) Then + upwnd_dist_intrst = dist_intrst_170_190 + ElseIf (wnd_dir_sonic < 300) Then + upwnd_dist_intrst = dist_intrst_190_300 + Else + upwnd_dist_intrst = dist_intrst_60_300 + EndIf + + 'Footprint selection + If ((stability_zL >= -200) AND (stability_zL <= 1) AND (u_star >= 0.2) AND (z >= 1)) Then + 'Kljun et al (2004) + FP_Equation = "Kljun et al" + 'Calculate footprint charactetistics + Call FootprintCharacteristics_Kljun(u_star, w_Std_R, z, L, z0, upwnd_dist_intrst, FP_dist_intrst, FP_max, FP_40, FP_55, FP_90) + Else + 'Kormann and Meixner (2001) + FP_Equation = "KormannMeixner" + 'Calculate footprint charactetistics + Call FootprintCharacteristics_KormannMeixner(u_star, z, stability_zL, rslt_wnd_spd, upwnd_dist_intrst, FP_dist_intrst, FP_max, FP_40, FP_55, FP_90) + EndIf + '*** End of footprint characteristics of measured fluxes *** + EndIf + '*** End of sonic head processing *** + + '*** Beginning of IRGA processing *** + 'Load in the IRGA data that has been lagged by EC100_REC_BCK scans. + mask = &h1 + For i = MAX_LAG To - MAX_LAG Step -1 + array_index = MAX_LAG + 1 - i 'Convert i = 2, 1, 0, -1, -2 to array_index = 1, 2, 3, 4, 5 + + GetRecord (dly_data_out(1), delay_CS, (EC100_REC_BCK + i)) + If (i = 0) Then Move (CO2, 7, dly_data_out(1), 7) 'CO2, H2O, diag_irga, amb_tmpr, amb_press, CO2_sig_strgth, H2O_sig_strgth + + 'Load the arrays that hold the input data for the covariance instructions. + Move (cov_array_CO2(array_index, 1), 1, dly_data_out(1),1) 'CO2 + Move (cov_array_CO2(array_index, 2), 3, Ux, 3) + CO2_bad_rng_sig_array (array_index) = ((dly_data_out(6) < CO2_SIG_STRGTH_THRESHOULD) OR (dly_data_out(1) <0) OR (dly_data_out(1) > CO2_RNG_TOP_LIMIT)) + + Move (cov_array_H2O(array_index, 1), 1, dly_data_out(2),1) 'H2O + Move (cov_array_H2O(array_index, 2), 3, Ux, 3) + H2O_bad_rng_sig_array (array_index) = ((dly_data_out(7) < H2O_SIG_STRGTH_THRESHOULD) OR (dly_data_out(2) <0) OR (dly_data_out(2) > H2O_RNG_TOP_LIMIT)) + + 'Extract the diagnostic word from each record of lagged data, used to exclude data from covariance calculation in Tables: comp_cov_CO2, comp_cov_H2O, and comp_cov_cs_5min. + irga_bad_data_flg_array(array_index) = mask AND IIF ((dly_data_out(3) <> NAN) AND (dly_data_out(3) <> -1),dly_data_out(3), &h3fffff) + + Next i + + 'Call tables for lag maximuzation + CallTable comp_cov_CO2 + CallTable comp_cov_H2O + + 'Extract the twenty two flags from the IRGA diagnostic word + diag_irga_tmp = IIF ((diag_irga <> NAN) AND (diag_irga <> -1),diag_irga, &h3fffff) + For i = 1 To 22 + diag_bits_irga(i) = diag_irga_tmp AND mask + mask = mask*2 + Next i + + 'Filter data in the covariance instruction if the IRGA reports bad data. + irga_disable_f = irga_bad_data_f + + 'Call table for data used for data quality grading + CallTable Comp_cov_CS_5min + + If ((SENSOR_IRGASON) AND (Ts_K <> NaN)) Then + 'Compute fast response air temperature from sonic temperature and IRGASON vapor density. + Tc_K = Ts_K/(1+0.32*Rv*H2O*Ts_K/amb_press) 'eq 20 in Swiatek (2007) + + ElseIf ((SENSOR_CSAT3AEC150) OR (Ts_K = NaN)) Then + Tc_K = amb_tmpr + T_0C_K 'Tc_K in K + EndIf + + 'Calculate water vapor pressure using IRGASON measurements + e = H2O*Rv*Tc_K 'Ideal gas equation (kPa) + rho_d = (amb_press-e)/(Tc_K*Rd) 'g/m^3 + rho_a = (rho_d + H2O)/1000 'kg/m^3 -Dim cov_array_sonic(1,4) 'used to hold input data for cov instructions -Dim cov_array_cs(4,4) - -Dim etcvar(3) -Alias etcvar(1) = divisor 'used to find molar mixing ratio. -Alias etcvar(2) = rho_d_mean 'Density of dry air used in WPL [kg / m^3]. -Alias etcvar(3) = sigma_wpl 'density of water vapor / density of dry air. - -Dim results(19) -Alias results(1) = Ts_absolute 'sonic temp in Kelvin -Alias results(2) = CO2_ppm 'CO2 mixing ratio -Alias results(3) = Xv 'H2O mixing ratio -Alias results(4) = L 'Obukohov length -Alias results(5) = Hs 'Sensible heat flux using sonic temperature. -Alias results(6) = tau 'Momentum flux. -Alias results(7) = u_star 'Friction velocity. -Alias results(8) = sonic_uptime -Alias results(9) = Fc_wpl 'Carbon dioxide flux (EC150), with WPL -Alias results(10) = LE_wpl 'Latent heat flux (EC150), with WPL -Alias results(11) = Hc 'Sensible heat flux with h2o-corrected sonic temp -Alias results(12) = irga_uptime -Alias results(13) = rho_a_mean -Alias results(14) = Fc_irga 'Carbon dioxide flux (EC150), without WPL -Alias results(15) = LE_irga 'Latent heat flux (EC150), without WPL -Alias results(16) = CO2_wpl_LE 'Carbon dioxide flux (EC150), WPL latent heat flux. -Alias results(17) = CO2_wpl_H 'Carbon dioxide flux (EC150), WPL sensible heat flux. -Alias results(18) = H2O_wpl_LE 'Latent heat flux (EC150), WPL latent heat flux. -Alias results(19) = H2O_wpl_H 'Latent heat flux (EC150), WPL sensible heat flux. -Units Ts_absolute = Kelvin -Units CO2_ppm = ppm -Units Xv = ppt -Units L = m -Units Hs = W/m^2 -Units tau = kg/(m s^2) -Units u_star = m/s -Units sonic_uptime = unity -Units Fc_wpl = mg/(m^2 s) -Units LE_wpl = W/m^2 -Units Hc = W/m^2 -Units irga_uptime = unity -Units rho_a_mean = kg/m^3 -Units Fc_irga = mg/(m^2 s) -Units LE_irga = W/m^2 -Units CO2_wpl_LE = mg/(m^2 s) -Units CO2_wpl_H = mg/(m^2 s) -Units H2O_wpl_LE = W/m^2 -Units H2O_wpl_H = W/m^2 - -Dim Fc_hf_irga 'CO2 flux using alt. CO2 value, without WPL -Dim CO2_hf_wpl_LE 'CO2 flux WPL latent heat component, using alt. CO2 value -Dim CO2_hf_wpl_H 'CO2 flux WPL sensible heat component, using alt. CO2 value -Dim Fc_hf_wpl 'CO2 flux using alt. CO2 value with WPL corrections -Units Fc_hf_wpl = mg/m^2/s - - -'********** HMP-155A temp/RH probe ********** -Dim hmp(4) -Alias hmp(1) = T_hmp 'HMP temperature -Alias hmp(2) = RH_hmp 'HMP relative humidity -Alias hmp(3) = e_hmp 'HMP vapor pressure -Alias hmp(4) = e_sat_hmp 'HMP saturation vapor pressure -Units T_hmp = C -Units RH_hmp = percent -Units e_hmp = kPa -Units e_sat_hmp = kPa - -Dim hmp_stats(3) -Alias hmp_stats(1) = H2O_hmp_mean -Alias hmp_stats(2) = RH_hmp_Avg -Units H2O_hmp_mean = g/m^3 -Units RH_hmp_Avg = % - - -'********** NR-Lite2 ********** -Dim nrlite_mult - -Dim nrlite(2) -Alias nrlite(1) = Rn -Alias nrlite(2) = Rn_meas -Units Rn = W/m^2 -Units Rn_meas = W/m^2 - -Dim hor_wind -Dim hor_wind_raw - - -'********** LI190SB quantum PAR sensor *********** -Dim li190_dens_mult -Dim li190_tot_mult - -Dim par(3) -Alias par(1) = PAR_mV -Alias par(2) = PAR_flxdens -Alias par(3) = PAR_totflx -Units PAR_mV = mV -Units PAR_flxdens = umol/m^2/s -Units PAR_totflx = mmol/m^2 - - -'*********** 034B wind vane ********** -Dim oh34B(2) -Alias oh34B(1) = WS_ms -Alias oh34B(2) = WindDir -Units WS_ms = m/s -Units WindDir = degrees - - -'********** TE525 rain gage ********** -Dim Rain_mm -Units Rain_mm=mm - - -'********** GPS16X-HVS ********** -Dim nmea_sentence(2) As String * 90 -Dim gps_data(15) -Alias gps_data(1) = latitude_a 'Degrees latitude (+ = East; - = West) -Alias gps_data(2) = latitude_b 'Minutes latitude -Alias gps_data(3) = longitude_a 'Degress longitude (+ = East; - = West) -Alias gps_data(4) = longitude_b 'Minutes longitude -Alias gps_data(5) = speed 'Speed -Alias gps_data(6) = course 'Course over ground -Alias gps_data(7) = magnetic_variation 'Magnetic variation from true north (+ = East; - = West) -Alias gps_data(8) = fix_quality 'GPS fix quality: 0 = invalid, 1 = GPS, 2 = 'differential GPS, 6 = estimated -Alias gps_data(9) = nmbr_satellites 'Number of satellites used for fix -Alias gps_data(10) = altitude 'Antenna altitude -Alias gps_data(11) = pps 'Elapsed ms since last pulse per second (PPS) from GPS -Alias gps_data(12) = dt_since_gprmc 'Time since last GPRMC string, normally less than '1 second -Alias gps_data(13) = gps_ready 'Counts from 0 to 10, 10 = ready -Alias gps_data(14) = max_clock_change 'Maximum value the clock was changed -Alias gps_data(15) = nmbr_clock_change 'Number of times the clock was changed -Units latitude_a = degreesN -Units latitude_b = minutesN -Units longitude_a = degreesE -Units longitude_b = minutesE -Units speed = m/s -Units course = degreesEofN -Units magnetic_variation = degreesEofN -Units fix_quality = unitless -Units nmbr_satellites = unitless -Units altitude = m -Units pps = ms -Units dt_since_gprmc = s -Units gps_ready = unitless -Units max_clock_change = ms -Units nmbr_clock_change = occurrences - - -'********** HFP01SC heat flux plate ********** -Dim hfp(4) -Alias hfp(1) = soil_hfp1_heat_flux -Alias hfp(2) = soil_hfp2_heat_flux -Alias hfp(3) = soil_hfp1_sensitivity -Alias hfp(4) = soil_hfp2_sensitivity -Units soil_hfp1_heat_flux = W/m^2 -Units soil_hfp2_heat_flux = W/m^2 -Units soil_hfp1_sensitivity = W/m^2/mV -Units soil_hfp2_sensitivity = W/m^2/mV - -'********** Averaging thermocouple ********** -Dim tcav(1) -Alias tcav(1) = tcav_T -Units tcav = degC - - -'********** Intermediate variables ********** -Dim dly_data_out(13) 'used to temporarily store the lagged record. - -Dim work_stats_out(40) -'sonic processing -Alias work_stats_out(1) = Ts_Std 'results of covariance instructions, 10 qntys -Alias work_stats_out(2) = Ts_Ux_cov -Alias work_stats_out(3) = Ts_Uy_cov -Alias work_stats_out(4) = Ts_Uz_cov -Alias work_stats_out(5) = Ux_Std -Alias work_stats_out(6) = Ux_Uy_cov -Alias work_stats_out(7) = Ux_Uz_cov -Alias work_stats_out(8) = Uy_Std -Alias work_stats_out(9) = Uy_Uz_cov -Alias work_stats_out(10) = Uz_Std -Alias work_stats_out(11) = wnd_spd 'results of windvector instruction, 4 qntys -Alias work_stats_out(12) = rslt_wnd_spd -Alias work_stats_out(13) = rslt_wnd_dir -Alias work_stats_out(14) = std_wnd_dir -Alias work_stats_out(15) = sonic_samples '1 @ totalize -'irga processing -Alias work_stats_out(16) = CO2_mg_m3_Std 'results of 3 covariances, 12 #s -Alias work_stats_out(17) = CO2_Ux_cov -Alias work_stats_out(18) = CO2_Uy_cov -Alias work_stats_out(19) = CO2_Uz_cov -Alias work_stats_out(20) = H2O_g_m3_Std -Alias work_stats_out(21) = H2O_Ux_cov -Alias work_stats_out(22) = H2O_Uy_cov -Alias work_stats_out(23) = H2O_Uz_cov -Alias work_stats_out(24) = Tc_stdev -Alias work_stats_out(25) = Tc_Ux_cov -Alias work_stats_out(26) = Tc_Uy_cov -Alias work_stats_out(27) = Tc_Uz_cov -Alias work_stats_out(28) = CO2_mg_m3_Avg 'four averages -Alias work_stats_out(29) = H2O_g_m3_Avg -Alias work_stats_out(30) = amb_press_Avg -Alias work_stats_out(31) = Tc_Avg -Alias work_stats_out(32) = irga_samples '1 @ totalize -'hmp processing -Alias work_stats_out(33) = e_hmp_Avg 'two averages -Alias work_stats_out(34) = e_sat_hmp_Avg -Alias work_stats_out(35) = samples_possible -Alias work_stats_out(36) = CO2_hf_mg_m3_Avg '1 average -Alias work_stats_out(37) = CO2_hf_mg_m3_Std 'results of 1 covariance, 4#s -Alias work_stats_out(38) = CO2_hf_Ux_cov -Alias work_stats_out(39) = CO2_hf_Uy_cov -Alias work_stats_out(40) = CO2_hf_Uz_cov -Units Ts_Std = C -Units Ts_Ux_cov = C m/s -Units Ts_Uy_cov = C m/s -Units Ts_Uz_cov = C m/s -Units Ux_Std = m/s -Units Ux_Uy_cov = (m/s)^2 -Units Ux_Uz_cov = (m/s)^2 -Units Uy_Std = m/s -Units Uy_Uz_cov = (m/s)^2 -Units Uz_Std = m/s -Units wnd_spd = m/s -Units rslt_wnd_spd = m/s -Units rslt_wnd_dir = degrees -Units std_wnd_dir = degrees -Units sonic_samples = samples -Units CO2_mg_m3_Std = mg/m^3 -Units CO2_Ux_cov = mg/(m^2 s) -Units CO2_Uy_cov = mg/(m^2 s) -Units CO2_Uz_cov = mg/(m^2 s) -Units H2O_g_m3_Std = g/m^3 -Units H2O_Ux_cov = g/(m^2 s) -Units H2O_Uy_cov = g/(m^2 s) -Units H2O_Uz_cov = g/(m^2 s) -Units Tc_stdev = C -Units Tc_Ux_cov = C m/s -Units Tc_Uy_cov = C m/s -Units Tc_Uz_cov = C m/s -Units CO2_mg_m3_Avg = mg/m^3 -Units H2O_g_m3_Avg = g/m^3 -Units amb_press_Avg = kPa -Units Tc_Avg = C -Units irga_samples = samples -Units e_hmp_Avg = kPa -Units e_sat_hmp_Avg = kPa -Units samples_possible = samples -Units CO2_hf_mg_m3_Std = mg/m^3 -Units CO2_hf_Ux_cov = mg/m^2/s -Units CO2_hf_Uy_cov = mg/m^2/s -Units CO2_hf_Uz_cov = mg/m^2/s - - -'============================ REMOTE MONITORING ============================ -DataTable(debug,True,2) - Sample(2,hmp(1),IEEE4) - Sample(2,nrlite(1),IEEE4) - Sample(3,par(1),IEEE4) - Sample(2,oh34B(1),IEEE4) - Sample(1,Rain_mm,IEEE4) - Sample(15,gps_data(1),IEEE4) - Sample(4,hfp(1),IEEE4) - Sample(1,tcav(1),IEEE4) -EndTable + 'Convert Tc in K to Tc in C + Tc = Tc_K - T_0C_K 'Tc in C + 'Saturation water pressure at current temperature + Enhance_Factor1 = 1.00041 + amb_press*(3.48e-5 + 7.4e-9*(Tc + 30.6 - 0.38*amb_press)^2) 'Eq. 6 from Appendix A of flux program manual -'=========================== PROCESSING DATA TABLES =================================== -DataTable(work_delay_ec100,TRUE,OFFSET) 'handles lagging CSAT+IRGA data - TableHide - Sample(13,sonic_irga_raw(1),IEEE4) -EndTable + Select Case Tc 'Eq. 5 from Appendix A of flux program manual + Case Is >= 0 + e_sat = 0.61121*Enhance_Factor1*EXP(17.368*Tc/(Tc + 238.88)) + Case Is < 0 + e_sat = 0.61121*Enhance_Factor1*EXP(17.966*Tc/(Tc + 247.15)) + EndSelect -DataTable(work_30min,TRUE,1) - TableHide - DataInterval(0,STAT_OUT_30,Min,1) - Covariance(4,cov_array_sonic(1,1),IEEE4,sonic_disable_f,10) - WindVector(1,-1*Uy,Ux,IEEE4,sonic_disable_f,0,1,2) - Totalize(1,n,IEEE4,sonic_disable_f) - FieldNames("sonic_total") - Covariance(4,cov_array_cs(1,1),IEEE4,irga_disable_f,4) - Covariance(4,cov_array_cs(2,1),IEEE4,irga_disable_f,4) - Covariance(4,cov_array_cs(3,1),IEEE4,irga_disable_f,4) - Average(1,CO2,IEEE4,irga_disable_f) - Average(1,H2O,IEEE4,irga_disable_f) - Average(1,amb_press,IEEE4,irga_disable_f) - Average(1,Tc,IEEE4,irga_disable_f) - Totalize(1,n,IEEE4,irga_disable_f) - FieldNames("irga_total") - Average(1,e_hmp,IEEE4,(inbetween_1hz_scan OR e_hmp=NAN)) - Average(1,e_sat_hmp,IEEE4,(inbetween_1hz_scan OR e_sat_hmp=NAN)) - Totalize(1,n,IEEE4,False) - Average(1,CO2_hf,IEEE4,irga_disable_f) - Covariance(4,cov_array_cs(4,1),IEEE4,irga_disable_f,4) -EndTable + 'Relative humidity + RH = 100 * e/e_sat -'=========================== BASE OUTPUT DATA TABLES ================================== -Const DAYS = 42 '6 weeks - -'time series data @ 10hz -DataTable (tsdata,TRUE,600 - DataInterval (0,FAST_INTV,mSec,100) - TableFile("CRD:TOA5_" & self & ".tsdata_", 108, 24, 0, 1, hr, 0, 0) - CardOut(0, DAYS*864000) - Sample (4,sonic_irga_raw(1),IEEE4) - FieldNames ("Ux,Uy,Uz,Ts") - Sample (1,sonic_irga_raw(5),FP2) - FieldNames ("diag_sonic") - Sample (1,sonic_irga_raw(13),IEEE4) - FieldNames ("CO2_hf") - Sample (5,sonic_irga_raw(6),IEEE4) - FieldNames ("CO2,H2O,diag_irga,amb_tmpr,amb_press") - Sample (2,sonic_irga_raw(11),FP2) - FieldNames ("CO2_signal,H2O_signal") -EndTable + 'Dew point temperature for general use for accurately computing the final dew point temperature + Enhance_Factor2 = 1.00072 + 3.46e-5*amb_press 'Eq. 9 from Appendix A of flux program manual -'30min statistics -DataTable (stats30,TRUE,10) - DataInterval (0,STAT_OUT_30,Min,10) - CardOut (0, DAYS*48) - Sample(1,L,IEEE4) 'monin obukhov length, meters - Sample(1,u_star,FP2) 'friction velocity, m/s - Sample(1,tau,FP2) 'momemtum flux, kg/(m s^2) - Sample(1,Fc_wpl,IEEE4) 'density-corrected (WPL) CO2 flux, mg/m3 - Sample(1,Fc_hf_wpl,IEEE4) 'WPL-corrected CO2 flux using alt. CO2 value - Sample(1,LE_wpl,FP2) 'density-corrected (WPL) latent heat flux, W/m2 - Sample(1,Hc,FP2) 'density-corrected sensible heat flux, W/m2 - Average(1,Ts,FP2,sonic_disable_f) 'mean sonic temperature, degC - Sample(1,Ts_Std,FP2) 'stdev of sonic temp, degC - Sample(1,Tc_Avg,FP2) 'mean of corrected sonic temp, degC - Sample(1,Uz_Std,FP2) 'stdev of vertical wind, m/s - Sample(1,wnd_spd,FP2) 'mean scalar wind speed, m/s - Sample(1,rslt_wnd_spd,FP2) 'vector mean wind speed, m/s - Sample(1,rslt_wnd_dir,FP2) 'mean wind direction rel2 north, degrees - Sample(1,std_wnd_dir,FP2) 'scalar stdev of wind direction, degrees - Sample(1,sonic_uptime,FP2) - Average(1,CO2_ppm,FP2,irga_disable_f) - Sample (1,CO2_mg_m3_Avg,FP2) 'mean of CO2 conc, mg/m3 - Sample (1,CO2_mg_m3_Std,FP2) 'stdev of CO2 conc, mg/m3 - Sample(1,CO2_hf_mg_m3_Avg,FP2) - Sample(1,CO2_hf_mg_m3_Std,FP2) - Average(1,CO2_signal,FP2,irga_disable_f) - Average(1,(Xv / MU_WPL),FP2,irga_disable_f) - FieldNames("H2O_g_kg_Avg") - Sample (1,H2O_g_m3_Avg,FP2) 'mean of H2O conc, g/m3 - Sample (1,H2O_g_m3_Std,FP2) 'stdev of H2O conc, g/m3 - Average(1,H2O_signal,FP2,irga_disable_f) - Average(1,amb_tmpr,IEEE4,irga_disable_f) - Sample (1,amb_press_Avg,IEEE4) 'mean of ambient pressure, kPa - Sample (1,irga_uptime,FP2) - Average(1,T_hmp,IEEE4,(inbetween_1hz_scan OR T_hmp=NAN)) - Sample (1,RH_hmp_Avg,FP2) 'mean HMP relative humidity, % - Sample (1,e_hmp_Avg,FP2) - Sample (1,e_sat_hmp_Avg,FP2) - Average(1,Rn,FP2,(inbetween_1hz_scan OR Rn=NAN)) - Average(1,Rn_meas,FP2,inbetween_1hz_scan OR Rn_meas=NAN)) - Totalize(1,PAR_totflx,FP2,(inbetween_1hz_scan OR PAR_totflx=NAN)) - Average(1,PAR_flxdens,FP2,(inbetween_1hz_scan OR PAR_flxdens=NAN)) - WindVector(1,WS_ms,WindDir,FP2,(WS_ms=NAN OR WindDir=NAN),0,0,2) - FieldNames("Met1_wnd_spd,Met1_rslt_wnd_spd,Met1_rslt_wnd_dir,Met1_std_wnd_dir") - 'units propogate from other datatable since names match - Totalize(1,Rain_mm,FP2,Rain_mm=NAN) '10hz loop - Average(1,soil_hfp1_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp1_heat_flux=NAN)) - Sample (1,soil_hfp1_sensitivity,IEEE4) - Average(1,soil_hfp2_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp2_heat_flux=NAN)) - Sample (1,soil_hfp2_sensitivity,IEEE4) - Average(1,panel_tmpr,FP2,(inbetween_1hz_scan OR panel_tmpr=NAN)) - Average(1,batt_volt,FP2,(inbetween_1hz_scan OR batt_volt=NAN)) -EndTable + x_tmp = LN(e/(0.61121*Enhance_Factor2)) 'For dew point temperature, assume that e is saturation water vapor pressure + Td_gu = 240.97*x_tmp/(17.502-x_tmp) -'Daily values -DataTable (site_daily,TRUE,2) - DataInterval (0,1,Day,10) - CardOut(0, DAYS) - Median(1,(latitude_a + latitude_b/60),DAILY_MEDNUM,IEEE4,(latitude_a=NAN OR latitude_b=NAN)) - FieldNames("latitude_Med") - Units latitude_Med = decDegreesN - Median(1,(longitude_a + longitude_b/60),DAILY_MEDNUM,IEEE4,(longitude_a=NAN OR longitude_b=NAN)) - FieldNames("longitude_Med") - Units longitude_Med = decDegreesE - Median(1,magnetic_variation,DAILY_MEDNUM,FP2,magnetic_variation=NAN) - Average(1,nmbr_satellites,FP2,nmbr_satellites=NAN) - Median(1,altitude,DAILY_MEDNUM,IEEE4,altitude=NAN) - Average(1,altitude,IEEE4,altitude=NAN) - Minimum(1,gps_ready,FP2,gps_ready=NAN,0) - Sample(1,max_clock_change,UINT2) - Sample(1,nmbr_clock_change,UINT2) - Minimum(1,batt_volt,FP2,batt_volt=NAN,1) - Maximum(1,batt_volt,FP2,batt_volt=NAN,1) - Minimum(1,T_hmp,FP2,T_hmp=NAN,1) - Maximum(1,T_hmp,FP2,T_hmp=NAN,1) -EndTable + 'Accurate dew point temperature + Enhance_Factor1 = 1.00041 + amb_press*(3.48e-5 + 7.4e-9*(Td_gu + 30.6 - 0.38*amb_press)^2) 'Eq. 6 from Appendix A of flux program manual -'program start-up information -DataTable (site_info,TRUE,20) - CardOut(0,1000) - Sample(1,UTC_OFFSET,FP2) - FieldNames("UTC_offset") - Units UTC_OFFSET = hours - Sample(1,sonic_azimuth,FP2) - Sample(1,NRLite2_sens,FP2) - FieldNames("NR_sens") - Sample(1,LI190SB_sens,FP2) - FieldNames("PAR_sens") - Sample(1,soil_hfp1_sensitivity,IEEE4) 'heat flux plate #1 info - FieldNames("HFP_1_sens") - Units HFP_1_SENS = W/m^2/mV - Sample(1,soil_hfp2_sensitivity,IEEE4) 'heat flux plate #2 info - FieldNames("HFP_2_sens") - Units HFP_2_SENS = W/m^2/mV - Sample(1,Status.CompileResults,String) - FieldNames("CompileResults") - Sample(1,Status.CardStatus,String) - FieldNames("CardStatus") - Sample(1,Status.RunSignature,UINT2) 'program information - FieldNames("RunSig") - Sample(1,Status.ProgSignature,UINT2) - FieldNames("ProgSig") - Sample(1,GIT_TAG,String) - FieldNames("GitRepoTag") - Sample(1,sensor_shfp,Boolean) - FieldNames("hfp_installed") -EndTable + x_tmp = LN(e/(0.61121*Enhance_Factor1)) 'For dew point temperature, assume that e is saturation water vapor pressure -'=========================== SUPPLEMENTAL OUTPUT DATA TABLES ========================== -DataTable(soil,True,100) - DataInterval(0,5,Min,4) - CardOut(0,DAYS*288) - Average(1,soil_hfp1_heat_flux,IEEE4,soil_hfp1_heat_flux=NAN)) - Average(1,soil_hfp2_heat_flux,IEEE4,soil_hfp2_heat_flux=NAN)) - Average(1,tcav_T,IEEE4,tcav_T=NAN) -EndTable + Select Case Td_gu 'Eq. 11 from Appendix A of flux program manual + Case Is >= 0 + Td = 238.88*x_tmp/(17.386 - x_tmp) + Case Is < 0 + Td = 247.15*x_tmp/(17.966 - x_tmp) + EndSelect + 'Compute the molar mixing ratio of CO2 and H2O. + divisor = (amb_press/(R*Tc_K))-(H2O/18) + CO2_mixratio = CO2/(0.04401*divisor) + H2O_mixratio = H2O/(0.01802*divisor) + CallTable comp_mean -'================================ MENU ================================================ -Const Enable = True -Const Yes = True -Const Apply = True -Const Disable = False -Const No = False -Const Cancel = False -Public save_changes As Boolean -Dim recompile As Boolean + If (comp_cov_cs_5min.Output(1, 1)) Then + GetRecord (CO2CO2_Cov_SST, comp_cov_cs_5min, 1) -DisplayMenu("Vineyard DAQ", -1) 'add submenu to main - SubMenu("Initial Setup") - SubMenu("Soil heat flux plate") - MenuItem("Enable?", SHFP_ENABLED) - MenuPick(Yes, No) - EndSubMenu - MenuRecompile("Apply now?", recompile) - MenuPick(No, Apply) - EndSubMenu + If (NOT (Planar_Fit_flg)) Then + 'Rotation for the covariance of CO2 with velocities + Call Rotation12_Scalar_Covariance(alpha_5min, gamma_5min, _ + uCO2_Cov_SST, vCO2_Cov_SST, wCO2_Cov_SST, _ + uCO2_Cov_SST_R, vCO2_Cov_SST_R, wCO2_Cov_SST_R) + 'Rotation for the covariance of H2O with velocities + Call Rotation12_Scalar_Covariance(alpha_5min, gamma_5min, _ + uH2O_Cov_SST, vH2O_Cov_SST, wH2O_Cov_SST, _ + uH2O_Cov_SST_R, vH2O_Cov_SST_R, wH2O_Cov_SST_R) + Else + 'Rotations for the covariance of CO2 with velocities + Call Rotation23_Scalar_Covariance(alpha_5min, beta_5min, _ + uCO2_Cov_SST, vCO2_Cov_SST, wCO2_Cov_SST, _ + uCO2_Cov_SST_R, vCO2_Cov_SST_R, wCO2_Cov_SST_R) + 'Rotations for the covariance of H2O with velocities + Call Rotation23_Scalar_Covariance(alpha_5min, beta_5min, _ + uH2O_Cov_SST, vH2O_Cov_SST, wH2O_Cov_SST, _ + uH2O_Cov_SST_R, vH2O_Cov_SST_R, wH2O_Cov_SST_R) + EndIf - SubMenu("Settings") - SubMenu("Sonic anemometer") - MenuItem("Azmiuth", set_sonic_azimuth) - DisplayLine(" degE of True North") - EndSubMenu - SubMenu("Net radiometer") - MenuItem("Sensitivity", set_NRLite2_sens) - DisplayLine(" uV/W/m^2") - EndSubMenu - SubMenu("PAR sensor") - MenuItem("Sensitivity", set_LI190SB_sens) - DisplayLine(" uA/mmol/m^s/s") - EndSubMenu - SubMenu("Cup & vane windset") - MenuItem("Enable WS?", set_cup_ws_enabled) - MenuPick(Yes, No) - MenuItem("Enable WD?", set_vane_wd_enabled) - MenuPick(Yes, No) - EndSubMenu - SubMenu("Rain gage") - MenuItem("Enable?", set_rain_enabled) - MenuPick(Yes, No) - EndSubMenu - #If (SHFP_ENABLED) Then - SubMenu("Soil heat flux plate") - DisplayLine("Plate #1 (DF 6):") - MenuItem("Sensitivity", set_hfp1_sens) - DisplayLine(" uV/W/m^2") - DisplayLine("Plate #2 (DF 7):") - MenuItem("Sensitivity", set_hfp2_sens) - DisplayLine(" uV/W/m^2") - EndSubMenu - #Else - DisplayLine("SHFP disabled") + If ((wCO2_Cov_SST_R <> NaN) AND (wH2O_Cov_SST_R <> NaN)) Then + RN_wCO2_Cov_R += wCO2_Cov_SST_R + RN_wH2O_Cov_R += wH2O_Cov_SST_R + nmbr_interval_qc_irga += 1 + EndIf + + EndIf + + If (comp_cov_CO2.Output(1,1) AND comp_cov_H2O.Output(1,1) AND comp_mean.Output(1,1) AND comp_cov_cs_5min.Output(1, 1)) Then + GetRecord (CO2_Avg_b2, comp_cov_CO2, 1) + GetRecord (H2O_Avg_b2, comp_cov_H2O, 1) + GetRecord (amb_tmpr_Avg, comp_mean, 1) + + VPD_air = e_sat_Avg - e_Avg 'Water vapor pressue deficit + + 'Rotate CO2-related covariance + wCO2_Cov_major_sign = 0 'Variable indicating the major direction (sign) of CO2 flux + + For i = 1 To (2* MAX_LAG + 1) + array_index = 5*(i-1) +3 + If (NOT (Planar_Fit_flg)) Then + 'Double rotations + ' Rotation for the covariance of CO2 with velocities + Call Rotation12_Scalar_Covariance(alpha, gamma, _ + Cov_out_CO2(array_index), Cov_out_CO2(array_index + 1), Cov_out_CO2(array_index + 2), _ + uCO2_vCO2_Cov_lag_R(i, 1), uCO2_vCO2_Cov_lag_R(i, 2), wCO2_Cov_lag_R (i)) + Else + ' Planar Fit rotations + ' Rotation for the covariance of CO2 with velocities + Call Rotation23_Scalar_Covariance(alpha, beta, _ + Cov_out_CO2(array_index), Cov_out_CO2(array_index + 1), Cov_out_CO2(array_index + 2), _ + uCO2_vCO2_Cov_lag_R(i, 1), uCO2_vCO2_Cov_lag_R(i, 2), wCO2_Cov_lag_R (i)) + EndIf + + wCO2_Cov_major_sign += wCO2_Cov_lag_R (i) + + Next i + + ' Calculate the separation distance normal (lateral) to wind and separation distance along wind + Call Separation_Lag_Lateral_Distances (wnd_dir_sonic, separation_x_irga, separation_y_irga, separation_lat_dist_irga, separation_lag_dist_irga) + separation_lag_scan_irga = 1000*(separation_lag_dist_irga/rslt_wnd_spd)/SCAN_INTERVAL 'in scan + + wCO2_Cov_R = NaN + Select Case wCO2_Cov_major_sign + Case Is >=0 + + If separation_lag_scan_irga <= -2 Then 'Find max of wCO2_cov_R + MaxSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (1)) + + ElseIf separation_lag_scan_irga < 0 Then 'Search three elements in the array to ensure maximization. + MaxSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (1)) + + ElseIf separation_lag_scan_irga = 0 Then + wCO2_Cov_R = wCO2_Cov_lag_R (3) + lag_irga = MAX_LAG + 1 + + ElseIf separation_lag_scan_irga < 2 Then + MaxSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (3)) + lag_irga = lag_irga + 2 + + Else + MaxSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (3)) 'Search three elements in the array to ensure maximization. + lag_irga = lag_irga + 2 + EndIf + + Case Is < 0 + + If separation_lag_scan_irga <= -2 Then 'Find min of wCO2_cov_R + MinSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (1)) + + ElseIf separation_lag_scan_irga < 0 Then 'Search three elements in the array to ensure maximization in terms of absolute value. + MinSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (1)) + + ElseIf separation_lag_scan_irga = 0 Then + wCO2_Cov_R = wCO2_Cov_lag_R (3) + lag_irga = MAX_LAG + 1 + + ElseIf separation_lag_scan_irga < 2 Then 'Search three elements in the array to ensure maximization in terms of absolute value. + MinSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (3)) + lag_irga = lag_irga + 2 + + Else + MinSpa (wCO2_Cov_R, 3, wCO2_Cov_lag_R (3)) + lag_irga = lag_irga + 2 + EndIf + EndSelect + + If (wCO2_Cov_R = NaN) Then lag_irga = MAX_LAG + 1 'Lag_IRGA is not evaluated inside SELECT CASE if wCO2_Cov_R = NaN. In this case, data w/o lag delay in cov_out_CO2 are kept. + + 'For final storage in flux file + 'Covariance values related to CO2 and H2O before coordinate rotation can be found using lag-IRGA + array_index = 5*(lag_irga - 1) + 1 + Move (CO2_Avg, 5, Cov_out_CO2(array_index), 5) + CO2_Std = SQR (CO2_Std) + CO2_molfrac_Avg = (CO2_Avg/0.04401) *R*(Tc_Avg + T_0C_K)/amb_press_Avg 'umol/mol + + Move (H2O_Avg, 5, Cov_out_H2O(array_index), 5) + H2O_Std = SQR (H2O_Std) + H2O_molfrac_Avg = (H2O_Avg/0.01802)*R*(Tc_Avg + T_0C_K)/amb_press_Avg 'mmol/mol + + 'Covariance of horizontal wind (after coordinate rotations) and CO2 using lag-IRGA + uCO2_Cov_R = uCO2_vCO2_Cov_lag_R(lag_irga, 1) + vCO2_Cov_R = uCO2_vCO2_Cov_lag_R(lag_irga, 2) + + 'Rotate covariance related to H2O + If (NOT (Planar_Fit_flg)) Then + 'Double rotations + ' Rotation for the covariance of H2O with velocities + Call Rotation12_Scalar_Covariance(alpha, gamma, _ + UxH2O_Cov, UyH2O_Cov, UzH2O_Cov, _ + uH2O_Cov_R, vH2O_Cov_R, wH2O_Cov_R) + ElseIf (Planar_Fit_flg) Then + ' Planar Fit rotations + ' Rotation for the covariance of H2O with velocities + Call Rotation23_Scalar_Covariance(alpha, beta, _ + UxH2O_Cov, UyH2O_Cov, UzH2O_Cov, _ + uH2O_Cov_R, vH2O_Cov_R, wH2O_Cov_R) + EndIf + + 'Convert lag_IRGA as an array index in sequential number as a lag number in scan (compare to sonic data, negative: backward and positive: forward) + lag_irga = lag_irga - (MAX_LAG + 1) + + ' Calculate the frequency correction factor for wCO2_cov_R and wH2O_cov_R + Call FreqFactorCSOPEC_wco2_wh2o_BA_LA_SP (z, stability_zL, rslt_wnd_spd, separation_lat_dist_irga, FreqFactor_wCO2_wH2O) + wCO2_Cov_R_F = FreqFactor_wCO2_wH2O*wCO2_Cov_R + wH2O_Cov_R_F = FreqFactor_wCO2_wH2O*wH2O_Cov_R + + 'Momentum flux after coordinater rotation and frequency corrections + tau = rho_a_Avg*u_star^2 + + 'Correct sonic temperature flux for humidity and calculate sensible heat flux + wTs_Cov_R_F_SND = wTs_Cov_R_F*(1- 0.51*(H2O_Avg/(1e3*rho_a_Avg)))-0.51*(Ts_Avg+ T_0C_K)*wH2O_Cov_R_F/(1e3*rho_a_Avg) 'eq. 2.53 in van Dijk (2002) + + Cp = (Cpd*rho_d_Avg + Cpw*H2O_Avg)/(rho_d_Avg + H2O_Avg) 'Specific heat of moist air + H = Cp*rho_a_Avg*wTs_Cov_R_F_SND + + T_star = - wTs_Cov_R_F_SND/u_star + + 'Apply WPL correction after coordinate rotation and freq corrections + 'IRGA Webb et al. (1980) term for carbon dioxide Eq. (24). + sigma_wpl = H2O_Avg/rho_d_Avg + CO2_E_WPL_R_F = MU_WPL*(CO2_Avg/rho_d_Avg)*wH2O_Cov_R_F + CO2_T_WPL_R_F = (1 + (MU_WPL*sigma_wpl))*(CO2_Avg/(Tc_Avg+T_0C_K))*wTs_Cov_R_F_SND + rho_d_Avg = 0.001*rho_d_Avg 'Convert g/m^3 to kg/m^3 for output + + Fc_mass = wCO2_Cov_R_F + CO2_E_WPL_R_F + CO2_T_WPL_R_F 'in mg/(m^2 s) + Fc_molar = 22.72237*Fc_mass '"22.72237" converts mg/(m^2 s) to umol/(m^2 s) + + 'IRGA Webb et al. (1980) term for water vapor Eq. (25). + H2O_E_WPL_R_F = MU_WPL*sigma_wpl*wH2O_Cov_R_F + H2O_T_WPL_R_F = (1 + (MU_WPL*sigma_wpl))*(H2O_Avg/(Tc_Avg+T_0C_K))*wTs_Cov_R_F_SND + + Lv = 2501 - 2.365*Tc_Avg 'Stull (1989) + LE = Lv* (wH2O_Cov_R_F + H2O_E_WPL_R_F + H2O_T_WPL_R_F) + + Bowen_ratio = H/LE + + '*** Data quality classification for scalar fluxes *** + 'Sensible heat flux + 'Calculate the measures of relative non-stationarity (Steady State Test) + RN_wTs_cov_R = ABS((RN_wTs_cov_R/nmbr_interval_qc_csat - wTs_Cov_R)/wTs_Cov_R) 'in fraction + Call Data_Quality_Grading_Scalar (stability_zL, w_Std_R, u_star, Ts_Std, T_star, latitude, wnd_dir_sonic, RN_wTs_cov_R, H_qc_grade) 'Quality classification for sensible heat flux + RN_wTs_cov_R = 0 + nmbr_interval_qc_csat = 0 + + 'CO2 flux + 'Calculate measures of relative non-stationarity (Steady State Test) + RN_wCO2_Cov_R = ABS((RN_wCO2_Cov_R/nmbr_interval_qc_irga - wCO2_Cov_R)/wCO2_Cov_R) 'in fraction + Call Data_Quality_Grading_Scalar (stability_zL, w_Std_R, u_star, Ts_Std, T_star, latitude, wnd_dir_sonic, RN_wCO2_Cov_R, Fc_qc_grade) 'Quality classification for CO2 flux + RN_wCO2_Cov_R = 0 + + 'H2O flux + 'Calculate measures of relative non-stationarity (Steady State Test) + RN_wH2O_Cov_R = ABS((RN_wH2O_Cov_R/nmbr_interval_qc_irga - wH2O_Cov_R)/wH2O_Cov_R) 'in fraction + Call Data_Quality_Grading_Scalar (stability_zL, w_Std_R, u_star, Ts_Std, T_star, latitude, wnd_dir_sonic, RN_wH2O_Cov_R, LE_qc_grade) 'Quality classification for latent heat flux + RN_wH2O_Cov_R = 0 + nmbr_interval_qc_irga = 0 + '*** End of data quality classification for scalar fluxes *** + + EndIf + '*** End of IRGA processing *** + #If (SENSOR_TMPR_RH) Then + + '*** Beginning of temperature and humidity processing *** + CallTable stats_tmpr_rh + If (stats_tmpr_rh.Output(1,1)) Then + GetRecord (T_probe_Avg,stats_tmpr_rh,1) + + H2O_probe_Avg = e_probe_Avg/((T_probe_Avg + T_0C_K)*Rv) 'g/m^3 + rho_d_probe_Avg = 0.001*(amb_press_Avg - e_probe_Avg)/((T_probe_Avg + T_0C_K)*Rd) 'kg/m^3 + rho_a_probe_Avg = rho_d_probe_Avg + H2O_probe_Avg/1000 'kg/m^3 + RH_probe_Avg = 100*e_probe_Avg/e_sat_probe_Avg '% + EndIf + '*** End of temperature and humidity probe processing *** + #EndIf + + #If (SENSOR_FW) Then + '*** Beginning of FW processing *** + 'Load in the FW data that has been lagged by OFFSET scans. + For i = MAX_LAG To - MAX_LAG Step -1 + array_index = MAX_LAG + 1 - i 'Convert i = 2, 1, 0 -1, -2 to array_index = 1, 2, 3, 4, 5 + + GetRecord (dly_data_out(1), delay_fw, (OFFSET +i)) + + 'Load the arrays that hold the input data for the covariance instructions. + Cov_array_fw(array_index, 1) = dly_data_out(1) 'fw + Move (Cov_array_fw(array_index, 2), 3, Ux, 3) + + FW_bad_data_flg(array_index) = (dly_data_out(2) = -1) + + Next i + + FW = Cov_array_fw(MAX_LAG + 1, 1) 'FW with no lag will be stored to Time_Series table + + CallTable comp_cov_fw + + If (comp_cov_fw.Output(1,1)) Then + GetRecord (FW_Avg_b2, comp_cov_fw, 1) + + wFW_cov_major_sign =0 + + For i = 1 To (2* MAX_LAG + 1) + array_index = 5*(i -1) + 3 + If (NOT (Planar_Fit_flg)) Then + ' Double rotations + ' Rotation for the covariance of FW temperature with wind velocities + Call Rotation12_Scalar_Covariance(alpha, gamma, _ + Cov_out_fw(array_index), Cov_out_fw(array_index + 1), Cov_out_fw(array_index + 2), _ + uFW_vFW_Cov_lag_R(i, 1), uFW_vFW_Cov_lag_R(i, 2), wFW_Cov_lag_R (i)) + Else + ' Planar fit rotations + ' Rotation for the covariance of FW temperature with velocities + Call Rotation23_Scalar_Covariance(alpha, beta, _ + Cov_out_fw(array_index), Cov_out_fw(array_index + 1), Cov_out_fw(array_index + 2), _ + uFW_vFW_Cov_lag_R(i, 1), uFW_vFW_Cov_lag_R(i, 2), wFW_Cov_lag_R (i)) + EndIf + + wFW_cov_major_sign += wFW_Cov_lag_R(i) + Next i + + 'Calculate the separation distances normal (lateral) to wind and separation distances along wind + Call Separation_Lag_Lateral_Distances (wnd_dir_sonic, separation_x_FW, separation_y_FW, separation_lat_dist_FW, separation_lag_dist_FW) + separation_lag_scan_FW = 1000*(separation_lag_dist_FW/rslt_wnd_spd)/SCAN_INTERVAL ' in scan + + wFW_Cov_R = NaN + Select Case wFW_cov_major_sign + Case Is >=0 + If (separation_lag_scan_FW <= -2) Then 'Find max of wFW_cov_R + MaxSpa (wFW_Cov_R, 3, wFW_Cov_lag_R(1)) + + ElseIf (separation_lag_scan_FW <= 0) Then 'Search two elements in the array to ensure maximization. + MaxSpa (wFW_Cov_R, 2, wFW_Cov_lag_R(1)) + + ElseIf (separation_lag_scan_FW < 2) Then + MaxSpa (wFW_Cov_R, 2, wFW_Cov_lag_R(3)) + lag_FW = lag_FW + 2 + + Else + MaxSpa (wFW_Cov_R, 3, wFW_Cov_lag_R(3)) 'Search three elements in the array to ensure maximization. + lag_FW = lag_FW + 2 + EndIf + + Case Is < 0 + If (separation_lag_scan_FW <= -2) Then 'Find min of wFW_cov_R + MinSpa (wFW_Cov_R, 3, wFW_Cov_lag_R(1)) + + ElseIf (separation_lag_scan_FW <= 0) Then 'Search two elements in the array to ensure maximization in terms of absolute value. + MinSpa (wFW_Cov_R, 2, wFW_Cov_lag_R(1)) + + ElseIf (separation_lag_scan_FW < 2) Then + MinSpa (wFW_Cov_R, 2, wFW_Cov_lag_R(3)) + lag_FW = lag_FW + 2 + + Else + MinSpa (wFW_Cov_R, 3, wFW_Cov_lag_R (3)) 'Search three elements in the array to ensure maximization in terms of absolute value. + lag_FW = lag_FW + 2 + EndIf + + EndSelect + + If (wFW_Cov_R = NaN) Then lag_FW = MAX_LAG + 1 'Lag_FW is not evaluated inside SELECT CASE if FW_Uz_Cov_R = NaN. In this case, data w/o lag delay in cov_out_fw are kept. + + ' For final storage in flux table + ' FW Covariance before coordinate rotation can be found using lag-variable + array_index = 5*(lag_FW - 1) + FW_Avg = Cov_out_fw(array_index + 1) + FW_Std = SQR(Cov_out_fw(array_index + 2)) + UxFW_Cov = Cov_out_fw(array_index + 3) + UyFW_Cov = Cov_out_fw(array_index + 4) + UzFW_Cov = Cov_out_fw(array_index + 5) + + ' FW Covariance after coordinate rotation also can be found using lag-variable + uFW_Cov_R = uFW_vFW_Cov_lag_R(lag_FW, 1) + vFW_Cov_R = uFW_vFW_Cov_lag_R(lag_FW, 2) + + 'Convert lag_FW in sequential number for array index to that in scan number. Compare to sonic data, negative: backward and positive: forward. + lag_FW = lag_FW - (MAX_LAG + 1) + + 'Calculate FW time constant + time_const_FW = Time_Const_Thermocouple_E(FW_diameter, FW_Avg, rslt_wnd_spd, rho_a_Avg) + + Call FreqFactorCSATFW_wT_BA_LA_TC_SP (z, stability_zL, rslt_wnd_spd, separation_lat_dist_FW, time_const_FW, FreqFactor_wFW) + wFW_Cov_R_F = FreqFactor_wFW*wFW_Cov_R + + 'Calculate sensible heat flux + ' Using the specific heat and density of moist air that are caluated using IRGASON data + H_FW = Cp*rho_a_Avg*wFW_Cov_R_F + + EndIf + '*** End of FW processing *** + #EndIf + #If (SENSOR_NR_LITE) Then + + '*** Beginning of NR Lite processing *** + hor_wind_raw = SQR (sonic_irga_raw(1)*sonic_irga_raw(1) + sonic_irga_raw(2)*sonic_irga_raw(2)) + AvgRun (hor_wind, 1 , hor_wind_raw, NMBR_WND_SAMPLES) 'Maintain a three second running mean of horizontal wind. + AvgRun (hor_wind_diag, 1, sonic_irga_raw(5), NMBR_WND_SAMPLES) 'Only correct for wind when hor_wind_diag has been non-zero for past 3 minutes. + '*** End of NR Lite processing *** + + #EndIf + #If (SENSOR_Rn) Then + CallTable stats_net_radiation + + 'Get Rn for the current averaging interval *** + If (stats_net_radiation.Output(1,1)) Then + + GetRecord (Rn, stats_net_radiation, 1) + + EndIf + #EndIf + + #If (SENSOR_HFP) Then + + '*** Beginning of table for soil heat flux plate *** + CallTable stats_SHF + '*** End of table for soil heat flux plate *** + + '*** Beginning of calculating the change in heat storage of soil above soil heat flux plate *** + If (stats_SHF.Output(1,1)) Then + + GetRecord (shf_plate_avg(1), stats_SHF, 1) + + #If (((SENSOR_TCAV) OR (SENSOR_CS65X)) AND (SENSOR_CS6XX)) Then + AvgSpa(G_surface, NMBR_SHFP, shf_plate_avg(1)) 'G_surface is used as a temporary variable + + #If (SENSOR_TCAV) Then + AvgSpa(Tsoil_current_Avg, NMBR_TCAV, Tsoil_current (1)) + #EndIf + #If ((NOT SENSOR_TCAV) AND (SENSOR_CS65X)) Then + AvgSpa(Tsoil_current_Avg, NMBR_CS6xx, Tsoil_current (1)) + #EndIf + + AvgSpa(soil_wtr_current_Avg, NMBR_CS6xx, soil_wtr_current (1)) + + Delta_soil_ht_storage = ((Tsoil_current_Avg - Tsoil_prev_Avg)*Cds*soil_bulk_density + _ + (Tsoil_current_Avg*soil_wtr_current_Avg - Tsoil_prev_Avg*soil_wtr_prev_Avg)*1000*Cw)*thick_abv_SHFP/(60*OUTPUT_INTERVAL-Offset_intv_Delta_ht_storage) + + Offset_intv_Delta_ht_storage = 0 'Reset time interval offset + + G_surface = G_surface + Delta_soil_ht_storage + + Tsoil_prev_Avg = Tsoil_current_Avg + soil_wtr_prev_Avg = soil_wtr_current_Avg + + #If (SENSOR_Rn) Then + 'CNR1, NR01, CNR4: smallest sensitivity is 10 uV/(W/m^2), CR3K resolution at the measurement range (+/-50 mV) is 0.83 uV. + 'Radiation < 0.083 W/m^2 can not be resolved by CR3K. The value of 0.083 is used for this threshould although this is approximation. + If (ABS(Rn - G_surface) > 0.083) Then + energy_closure = (LE + H)/(Rn - G_surface) + Else + energy_closure = 1 + EndIf + #EndIf + #EndIf + + EndIf + #EndIf + + process_time = (Status.ProcessTime(1,1))/1000 'in ms + buff_depth = Status.BuffDepth(1,1) + + 'Save time series data. + CallTable Time_Series + + 'Save averaged and calculated data. + CallTable Flux + + #If (NOT ONE_FULL_TABLE) Then + CallTable Flux_Notes + #EndIf + + slowsequence_disable_flg = TRUE + If (slowsequence_finished_flg) Then + slowsequence_finished_flg = FALSE + slowsequence_disable_flg = FALSE + EndIf + + Else + scan_count += 1 + EndIf + CallTable diagnostic + + NextScan + + SlowSequence + + Scan (SLOWSEQUENCE_SCAN_INTERVAL, mSec, 3, 0) + + 'Measure battery voltage. + Battery (batt_volt) + + #If (SENSOR_TMPR_RH) Then + + '*** Beginning of temperature and humidity probe measurements *** + VoltSe (T_probe, 2, mV1000, TMPR_RH_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + T_probe = T_probe*TMPR_RH_T_MULT + TMPR_RH_T_OFFSET + RH_probe = RH_probe*0.1 + VaporPressure (e_probe, T_probe, RH_probe) + + 'Saturation water pressure at current temperature + Enhance_factor1_probe = 1.00041 + amb_press*(3.48e-5 + 7.4e-9*(T_probe + 30.6 - 0.38*amb_press)^2) 'Eq. 6 from Appendix A of flux program manual + + Select Case T_probe 'Eq. 5 from Appendix A of flux program manual + Case Is >= 0 + e_sat_probe = 0.61121*Enhance_factor1_probe*EXP(17.368*T_probe/(T_probe + 238.88)) + Case Is < 0 + e_sat_probe = 0.61121*Enhance_factor1_probe*EXP(17.966*T_probe/(T_probe + 247.15)) + EndSelect + + 'Dew point temperature for general use for accurately computing the final dew point temperature + Enhance_factor2_probe = 1.00072 + 3.46e-5*amb_press 'Eq. 9 from Appendix A of flux program manual + + x_tmp_probe = LN(e_probe/(0.61121*Enhance_factor2_probe)) 'For dew point temperature, assume that e is saturation water vapor pressure + Td_gu_probe = 240.97*x_tmp_probe/(17.502-x_tmp_probe) + + 'Accurate dew point temperature + Enhance_factor1_probe = 1.00041 + amb_press*(3.48e-5 + 7.4e-9*(Td_gu_probe + 30.6 - 0.38*amb_press)^2) 'Eq. 6 from Appendix A of flux program manual + + x_tmp_probe = LN(e_probe/(0.61121*Enhance_factor1_probe)) 'For dew point temperature, assume that e is saturation water vapor pressure + + Select Case Td_gu_probe 'Eq. 11 from Appendix A of flux program manual + Case Is >= 0 + Td_probe = 238.88*x_tmp_probe/(17.386 - x_tmp_probe) + Case Is < 0 + Td_probe = 247.15*x_tmp_probe/(17.966 - x_tmp_probe) + EndSelect + + '*** End of temperature and humidity probe measurements *** #EndIf - SubMenu("Save changes") - MenuItem("Save now?", save_changes) - MenuPick(Cancel,Yes) - EndSubMenu - EndSubMenu - - SubMenu("Debug") - SubMenu("Monitor sensors") - DisplayValue("sonic Ux", sonic_irga_raw(1)) - DisplayValue("sonic Uy", sonic_irga_raw(2)) - DisplayValue("sonic Uz", sonic_irga_raw(3)) - DisplayValue("sonic Ts", sonic_irga_raw(4)) - DisplayValue("sonic diag", sonic_irga_raw(5)) - DisplayValue("irga CO2", sonic_irga_raw(6)) - DisplayValue("irga H2O", sonic_irga_raw(7)) - DisplayValue("irga diag", sonic_irga_raw(8)) - DisplayValue("irga tmpr", sonic_irga_raw(9)) - DisplayValue("irga press", sonic_irga_raw(10)) - DisplayValue("irga CO2 sig", sonic_irga_raw(11)) - DisplayValue("irga H2O sig", sonic_irga_raw(12)) - DisplayValue("HMP tmpr", T_hmp) - DisplayValue("HMP RH", RH_hmp) - DisplayValue("NR Rn", Rn) - DisplayValue("NR Rn meas", Rn_meas) - DisplayValue("PAR mV", PAR_mV) - DisplayValue("PAR flx dens", PAR_flxdens) - DisplayValue("PAR total flx", PAR_totflx) - DisplayValue("034B WS", WS_ms) - DisplayValue("034B WD", WindDir) - DisplayValue("Rain", Rain_mm) - DisplayValue("GPS lat deg", latitude_a) - DisplayValue("GPS lat min", latitude_b) - DisplayValue("GPS long deg", longitude_a) - DisplayValue("GPS long min", longitude_b) - DisplayValue("GPS speed", speed) - DisplayValue("GPS course", course) - DisplayValue("GPS mag var", magnetic_variation) - DisplayValue("GPS fix qual", fix_quality) - DisplayValue("GPS num sats", nmbr_satellites) - DisplayValue("GPS altitude", altitude) - DisplayValue("GPS pps", pps) - DisplayValue("GPS msg time", dt_since_gprmc) - DisplayValue("GPS ready", gps_ready) - DisplayValue("GPS max adj", max_clock_change) - DisplayValue("GPS num adj", nmbr_clock_change) - DisplayValue("SHFP 1 flux", soil_hfp1_heat_flux) - DisplayValue("SHFP 1 sens", soil_hfp1_sensitivity) - DisplayValue("SHFP 2 flux", soil_hfp2_heat_flux) - DisplayValue("SHFP 2 sens", soil_hfp2_sensitivity) - DisplayValue("TCAV tmpr", tcav_T) - EndSubMenu - MenuItem("Debug table", debug_on) - MenuPick(Disable,Enable) - EndSubMenu -EndMenu + #If (SENSOR_Rn) Then + '*** Beginning of net radiation measurements *** + #If (SENSOR_NR_LITE) Then -'=============================== SUBROUTINES ========================================== -Sub set_default_choices() - set_sonic_azimuth = NAN - set_NRLite2_sens = 0 - set_LI190SB_sens = 0 - set_cup_ws_enabled = False - set_vane_wd_enabled = False - set_rain_enabled = False - set_hfp1_sens = 0 - set_hfp2_sens = 0 -EndSub + '*** Beginning of NR Lite measurements *** + VoltDiff (Rn_meas, 1, AutoRange, NR_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, NRLITE_CAL, 0) -Sub populate_choices() - Move(choice(1),NUM_SETTINGS,settings(1),NUM_SETTINGS) -EndSub + 'Apply calibration and wind correction to net radiometer measurement. + If ((hor_wind_diag = 0) AND (hor_wind > 5)) Then + Rn_raw = Rn_meas*(1 + (0.021286*(hor_wind - 5))) + Else + Rn_raw = Rn_meas + EndIf + '*** End of NR Lite measurements *** + #EndIf -Sub save_current_choices() - 'input validation + #If (SENSOR_NR01) OR (SENSOR_CNR4) Then - Move(settings(1),NUM_SETTINGS,choice(1),NUM_SETTINGS) - Calfile(settings,NUM_SETTINGS,SETTINGS_FILE,WRITEFILE) + '*** Beginning of a 4-way radiometer measurements *** + VoltDiff (R_SW_in, 4, AutoRange, NR_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) - 'update dependent variables - nrlite_mult = 1000/NRLite2_sens - li190_dens_mult = 1000/(LI190SB_sens*0.604) - li190_tot_mult = (1/(LI190SB_sens*0.604))*(SLOW_INTV/1) + #EndIf + #If (SENSOR_NR01) Then - sensor_shfp = SHFP_ENABLED - #If (SHFP_ENABLED) Then - soil_hfp1_sensitivity = 1000/hfp1_sens - soil_hfp2_sensitivity = 1000/hfp2_sens - #Else - soil_hfp1_heat_flux = NAN - soil_hfp1_sensitivity = 0 - soil_hfp2_heat_flux = NAN - soil_hfp2_sensitivity = 0 - #EndIf -EndSub + 'Compute net radiation, albedo, downwelling and upwelling long-wave radiation. + R_SW_in = R_SW_in*NR01_SW_IN_CAL + R_SW_out = R_SW_out*NR01_SW_OUT_CAL + R_LW_in_meas = R_LW_in*NR01_LW_IN_CAL + R_LW_out_meas = R_LW_out*NR01_LW_OUT_CAL -Sub setup() - filehandle = FileOpen(SETTINGS_FILE,"rb",0) ' attempt to open file - FileClose(filehandle) - If (filehandle = 0) Then 'if file not found - set_default_choices() - Else - Calfile(settings,NUM_SETTINGS,SETTINGS_FILE,READFILE) - populate_choices() - EndIf - save_current_choices() + Rn_raw = R_SW_in - R_SW_out + R_LW_in_meas - R_LW_out_meas - CallTable (site_info) - SDMSpeed (SDM_PER) - self = Status.StationName -EndSub + If (R_SW_in >0) AND (R_SW_in >= R_SW_out) Then + albedo = R_SW_out/R_SW_in + Else + albedo = 0 + EndIf + 'Correct long-wave radiation. + Resistance (T_nr, 1, mV200, T_NR_ANALOG_INPUT, T_NR_CURRENT_EXCITATION, 1, 1675, TRUE, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + T_nr = T_nr/100 + PRT (T_nr, 1, T_nr, 1, T_0C_K) -'================================ PROGRAM ============================================= -BeginProg - setup() + 'Compute net radiation, albedo, downwelling and upwelling longwave radiation. + R_LW_in = R_LW_in_meas + (5.67e-8*T_nr*T_nr*T_nr*T_nr) + R_LW_out = R_LW_out_meas + (5.67e-8*T_nr*T_nr*T_nr*T_nr) - Scan (FAST_INTV,mSec,FAST_BUFFER_SIZE,0) - - '== 034B wind vane acquisition - BrHalf(WindDir,1,mV5000,oh34B_WD_SE,oh34B_WD_VX,1,5000,True,0,INTEG,oh34B_WD_MULT,oh34B_WD_OFFSET) - If (vane_wd_enabled) Then - If ((WindDir >= 360) OR (WindDir < 0)) Then (WindDir = 0) + '*** End of a 4-way radiometer measurements *** + + #EndIf + #If (SENSOR_CNR4) Then + + 'Compute net radiation, albedo, downwelling and upwelling long-wave radiation. + R_SW_in = R_SW_in*CNR4_SW_IN_CAL + R_SW_out = R_SW_out*CNR4_SW_OUT_CAL + R_LW_in_meas = R_LW_in*CNR4_LW_IN_CAL + R_LW_out_meas = R_LW_out*CNR4_LW_OUT_CAL + + Rn_raw = R_SW_in - R_SW_out + R_LW_in_meas - R_LW_out_meas + + If (R_SW_in >0) AND (R_SW_in >= R_SW_out) Then + albedo = R_SW_out/R_SW_in Else - WindDir = NAN + albedo = 0 + EndIf + + 'Correct longwave radiation. + BrHalf (X_cnr4, 1, mV1000, (2*T_NR_ANALOG_INPUT -1), T_NR_VOLTAGE_EXCITATION, 1, 1000, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + ln_R = LOG (1000*X_cnr4/(1-X_cnr4)) + T_nr = (1/(A_SHH+B_SHH*ln_R+C_SHH*ln_R*ln_R*ln_R)) + + R_LW_in = R_LW_in_meas + (5.67e-8*T_nr*T_nr*T_nr*T_nr) + R_LW_out = R_LW_out_meas + (5.67e-8*T_nr*T_nr*T_nr*T_nr) + '*** End of a 4-way radiometer measurements *** + #EndIf + + '*** End of net radiation measurements *** + + #EndIf + #If (SENSOR_HFP01) Then + + '*** Beginning of HFP01 measurements *** + VoltDiff (shf_plate(1), NMBR_SHFP, AutoRange, SHF_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, shf_plate_cal(),0) + '*** End of HFP01 measurements *** + + #EndIf + #If ( SENSOR_HFP01SC ) Then + + '*** Beginning of HFP01SC measurements *** + VoltSe (shf_mV(1), NMBR_SHFP, mV50C, SHF_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + + 'Apply HFP01SC soil heat flux plate calibration. + For i_slow = 1 To NMBR_SHFP + shf_plate(i_slow) = shf_mV(i_slow)*shf_plate_cal(i_slow) + Next i_slow + + 'Power the HFP01SC heaters. + PortSet (9, sw12_1_state) + + 'Measure voltage across the heater (V_Rf). + VoltSe (V_Rf(1), NMBR_SHFP, mV5000, SHF_HEATER_ANALOG_INPUT , TRUE, 0, ANALOG_INTEGRATION, 0.001, 0) + + 'SHF_HEATER_ANALOG_INPUT + NMBR_SHFP + 'Maintain filtered values for calibration. + AvgRun (shf_mV_run(1), NMBR_SHFP, shf_mV(1), 10) + AvgRun (V_Rf_run(1), NMBR_SHFP, V_Rf(1), 10) + + 'Begin HFP01SC calibration one minute into very CAL_INTERVAL minutes. + If (IfTime (1, CAL_INTERVAL, Min)) Then + shf_cal_on_f = TRUE + Move (shf_mV_0(1), NMBR_SHFP, shf_mV_run(1), NMBR_SHFP) + sw12_1_state = TRUE + EndIf + + If (IfTime (4, CAL_INTERVAL, Min)) Then + Move (shf_mV_180(1), NMBR_SHFP, shf_mV_run(1), NMBR_SHFP) + Move (V_Rf_180(1), NMBR_SHFP, V_Rf_run(1), NMBR_SHFP) + sw12_1_state = FALSE + EndIf + + 'End HFP01SC calibration sequence. + If (IfTime(END_CAL, CAL_INTERVAL, Min)) Then + Move (shf_mV_end(1), NMBR_SHFP, shf_mV_run(1), NMBR_SHFP) + 'Compute new HFP01SC calibration factors. + For i_slow = 1 To NMBR_SHFP + If ((V_Rf_180(i_slow) <> NaN) AND (shf_mV_0(i_slow) <> NaN) AND (shf_mV_180(i_slow)<> NaN)) Then + shf_plate_cal(i_slow) = V_Rf_180(i_slow)*V_Rf_180(i_slow)*128.7/ABS (((shf_mV_0(i_slow)+shf_mV_end(i_slow))/2)-shf_mV_180(i_slow)) + EndIf + Next i_slow + shf_cal_on_f = FALSE + EndIf + '*** End of HFP01SC measurements *** + #EndIf + #If ( SENSOR_TCAV ) Then + + '*** Beginning of TCAV measurements *** + TCDiff (Tsoil(1), NMBR_TCAV, AutoRange, TCAV_ANALOG_INPUT, TypeE, panel_tmpr, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + AvgRun (Tsoil_current(1), NMBR_TCAV, Tsoil(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (Tsoil_prev_Avg = NaN) Then 'As soon as program starts + AvgSpa (Tsoil_prev_Avg, NMBR_TCAV, Tsoil(1)) EndIf - PulseCount(WS_ms,1,oh34B_WS_PULSE,2,1,oh34B_WS_MULT,oh34B_WS_OFFSET) - If (cup_ws_enabled) Then - If (WS_ms <= oh34B_WS_OFFSET) Then (WS_ms = 0) + #EndIf + '*** End of TCAV measurements *** + + #EndIf + #If (SENSOR_CS616) Then + + '*** Beginning of CS616 measurements *** + CS616 (cs616_wcr(1), NMBR_CS6xx, CS616_ANALOG_INPUT, CS616_POWER_CTRL, NMBR_CS6xx, 1, 0) + + #If ((SENSOR_CS616) AND (SENSOR_TCAV)) Then + If (NMBR_CS6xx >= NMBR_TCAV) Then + Move(Tsoil_for_CS616_correct(1), NMBR_CS6xx, Tsoil(1), NMBR_TCAV) Else - WS_ms = NAN + Move(Tsoil_for_CS616_correct(1), NMBR_CS6xx, Tsoil(1), 1) EndIf - - '== TE525 rain gage acquisition - PulseCount(Rain_mm,1,TE525_PULSE,2,0,TE525_MULT,0) - If (NOT rain_enabled) Then Rain_mm = NAN - - '== EC100/EC150/CSAT3A irga/sonic acquisition - EC100 (sonic_irga_raw(1),EC100_SDM_ADDR,2) - CallTable(work_delay_ec100) - CallTable(tsdata) + #EndIf - '== NR-Lite2 correction factor calc - hor_wind_raw = SQR (sonic_irga_raw(1)*sonic_irga_raw(1)+sonic_irga_raw(2)*sonic_irga_raw(2)) - AvgRun (hor_wind,1,hor_wind_raw,NMBR_WND_SAMPLES) '3-sec running mean of horiz. WS + 'Apply temperature correction to CS616 period and find volumetric water content. + For i_slow = 1 To NMBR_CS6xx - If ( scan_count >= OFFSET ) Then 'IF HAVE ENUF SCANS TO DO STATS, - - '== EC100/EC150/CSAT3A lagged data retrieval - GetRecord (dly_data_out(1),work_delay_ec100,EC150_REC_BCK) - Move (Ux,5,dly_data_out(1),5) 'Ux, Uy, Uz, Ts, diag_sonic - Move (CO2,7,dly_data_out(6),8) '+H2O,diag_irga,amb_tmpr,amb_press,CO2_signal,H2O_signal,CO2_hf - If ( (diag_sonic <> NAN) AND (diag_sonic <> -1) ) Then - sonic_disable_f = diag_sonic AND &h3f '= 0011 1111 - Else - Move(Ux,5,NAN,1) - sonic_disable_f = TRUE - EndIf - Ts_absolute = IIF(sonic_disable_f, NAN, Ts+273.15) - If ( (diag_irga <> NAN) AND (diag_irga <> -1) ) Then - irga_disable_f = sonic_disable_f OR (diag_irga AND &h1) 'bit 0 always HI for warning - Else - Move(CO2,8,NAN,1) - irga_disable_f = TRUE - EndIf - If ( NOT irga_disable_f ) Then - Tc = Ts_absolute/(1+0.32*H2O*R*Ts_absolute/(amb_press*18)) - 273.15'Kaimal and Gaynor (1991) Eq. (3). - divisor = (amb_press/(R*(Tc+273.15)))-(H2O/18) '[divisor] = mol/m^3 - CO2_ppm = CO2/(MW_CO2/1000)/divisor - CO2_hf_ppm = CO2_hf/(MW_CO2/1000)/divisor - Xv = H2O/(MW_H2O/1000)/divisor + #If ((SENSOR_CS616) AND (SENSOR_TCAV)) Then + If ( (10 <= Tsoil_for_CS616_correct(i_slow)) AND (Tsoil_for_CS616_correct(i_slow) <= 40) ) Then + cs616_T(i_slow) = cs616_wcr(i_slow)+(20-Tsoil_for_CS616_correct(i_slow))*(0.526+cs616_wcr(i_slow)*(-0.052+cs616_wcr(i_slow)*0.00136)) Else - Tc = NAN - CO2_ppm = NAN - CO2_hf_ppm = NAN - Xv = NAN - EndIf - - 'sonic cov for stats 1 - cov_array_sonic(1,1) = Ts - Move (cov_array_sonic(1,2),3,Ux,3) - - 'irga cov for stats 1 - cov_array_cs(1,1) = CO2 - cov_array_cs(2,1) = H2O - cov_array_cs(3,1) = Tc - cov_array_cs(4,1) = CO2_hf - Move (cov_array_cs(1,2),3,Ux,3) - Move (cov_array_cs(2,2),3,Ux,3) - Move (cov_array_cs(3,2),3,Ux,3) - Move(cov_array_cs(4,2),3,Ux,3) - - '+++++ 30 min statistics +++++ - CallTable (work_30min) - If ( work_30min.Output(1,1) ) Then - GetRecord(work_stats_out(1),work_30min,1) - - sonic_uptime = sonic_samples/samples_possible - irga_uptime = irga_samples/samples_possible - - 'add azimuth to calculated wind dir - rslt_wnd_dir = (360 + rslt_wnd_dir + sonic_azimuth) MOD 360 - tau = SQR ((Ux_Uz_cov*Ux_Uz_cov)+(Uy_Uz_cov*Uy_Uz_cov)) - u_star = SQR (tau) - Ts_Std = SQR (Ts_Std) - Ux_Std = SQR (Ux_Std) - Uy_Std = SQR (Uy_Std) - Uz_Std = SQR (Uz_Std) - - L=-u_star^3*(Tc_Avg+273.15)/(0.4*9.8*Ts_Uz_cov) 'obukohov length - rho_d_mean = (amb_press_Avg/((Tc_Avg+273.15)*RD))-(H2O_g_m3_Avg*MU_WPL) - rho_a_mean = (rho_d_mean+H2O_g_m3_Avg)/1000 - Fc_irga = CO2_Uz_cov 'online fluxes - LE_irga = LV*H2O_Uz_cov - CO2_mg_m3_Std = SQR (CO2_mg_m3_Std) 'stdevs - H2O_g_m3_Std = SQR (H2O_g_m3_Std) - Tc_stdev = SQR (Tc_stdev) - sigma_wpl = H2O_g_m3_Avg/rho_d_mean 'WPL term - - 'EC150 Webb et al. (1980) term for carbon dioxide Eq. (24). - CO2_wpl_LE = MU_WPL*CO2_mg_m3_Avg/rho_d_mean*H2O_Uz_cov - CO2_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov - Fc_wpl = Fc_irga+CO2_wpl_LE+CO2_wpl_H - - 'EC150 Webb et al. (1980) term for water vapor Eq. (25). - H2O_wpl_LE = MU_WPL*sigma_wpl*LE_irga - H2O_wpl_H = (1+(MU_WPL*sigma_wpl))*H2O_g_m3_Avg/(Tc_Avg+273.15)*LV*Tc_Uz_cov - LE_wpl = LE_irga+H2O_wpl_LE+H2O_wpl_H - - 'repeat using high-frequency tmpr CO2 value - Fc_hf_irga = CO2_hf_Uz_cov - CO2_hf_mg_m3_Std = SQR(CO2_hf_mg_m3_Std) - CO2_hf_wpl_LE = MU_WPL*CO2_hf_mg_m3_Avg/rho_d_mean*H2O_Uz_cov - CO2_hf_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_hf_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov - Fc_hf_wpl = Fc_hf_irga+CO2_hf_wpl_LE+CO2_hf_wpl_H - - RH_hmp_Avg = 100*e_hmp_Avg/e_sat_hmp_Avg - - Hs = rho_a_mean*CP*Ts_Uz_cov - tau = rho_a_mean*tau - Hc = rho_a_mean*CP*Tc_Uz_cov - EndIf - CallTable(stats30) '**************************************************** - - inbetween_1hz_scan = TRUE - If ( just_had_1hz_scan ) Then - just_had_1hz_scan = FALSE - inbetween_1hz_scan = FALSE - EndIf - - inbetween_5s_scan = TRUE - If ( just_had_soil_scan ) Then - just_had_soil_scan = FALSE - inbetween_5s_scan = FALSE + cs616_T(i_slow) = cs616_wcr(i_slow) EndIf - Else - scan_count = scan_count+1 + soil_wtr_T(i_slow) = -0.0663+cs616_T(i_slow)*(-0.0063+cs616_T(i_slow)*0.0007) + #EndIf + + #If ((SENSOR_CS616) AND (NOT SENSOR_TCAV)) Then + soil_wtr(i_slow) = -0.0663+cs616_wcr(i_slow)*(-0.0063+cs616_wcr(i_slow)*0.0007) + #EndIf + + Next i_slow + + #If ((SENSOR_HFP) AND (SENSOR_CS616) AND (SENSOR_TCAV)) Then + AvgRun (soil_wtr_current(1), NMBR_CS6xx, soil_wtr_T(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If soil_wtr_prev_Avg = NaN Then 'As soon as program started + AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, soil_wtr_T(1)) EndIf - NextScan + #EndIf + '*** End of CS616 measurements *** + #EndIf + #If (SENSOR_CS65X) Then + '*** Beginning of CS65X measurements *** + SDI12Recorder (cs65x_raw(1), CS65X_SDI12_PORT, CS65X_SDI12_Address_1, "M!", 1, 0) + cs65x_wc(1) = cs65x_raw(1) + cs65x_ec(1) = cs65x_raw(2) + cs65x_tmpr(1) = cs65x_raw(3) - '====================== SLOW SCAN INTERVAL ================================= - SlowSequence - Scan (SLOW_INTV,Sec,SLOW_BUFFER_SIZE,0) - PanelTemp (panel_tmpr,INTEG) - Battery (batt_volt) + #If (NMBR_CS6xx = 2) Then + SDI12Recorder (cs65x_raw(1), CS65X_SDI12_PORT, CS65X_SDI12_Address_2, "M!", 1, 0) + cs65x_wc(2) = cs65x_raw(1) + cs65x_ec(2) = cs65x_raw(2) + cs65x_tmpr(2) = cs65x_raw(3) + #EndIf + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + + AvgRun (soil_wtr_current(1), NMBR_CS6xx, cs65x_wc(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (soil_wtr_prev_Avg = NaN) Then + AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, cs65x_wc(1)) + EndIf + + #If ((SENSOR_CS65X) AND ( NOT SENSOR_TCAV)) Then + AvgRun (Tsoil_current(1), NMBR_CS6xx, cs65x_tmpr(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (Tsoil_prev_Avg = NaN) Then 'As soon as program starts + AvgSpa (Tsoil_prev_Avg, NMBR_CS6xx, cs65x_tmpr(1)) + EndIf + #EndIf + #EndIf + '*** End of CS65X measurements *** + #EndIf - '== HMP-155A temp/RH - VoltDiff (T_hmp,1,mV1000,HMP_T_DIFF,TRUE,0,INTEG,HMP_T_MULT,HMP_T_OFFSET) - VoltDiff (RH_hmp,1,mV1000,HMP_RH_DIFF,TRUE,0,INTEG,HMP_RH_MULT,HMP_RH_OFFSET) - VaporPressure (e_hmp,T_hmp,RH_hmp) - SatVP (e_sat_hmp,T_hmp) + #If (SENSOR_LI200X) OR (SENSOR_CS300) Then - '== NR-Lite2 net radiometer, expected range 0-15mV - VoltDiff (Rn_meas,1,mV20,NRLITE_DIFF,TRUE,0,INTEG,nrlite_mult,0) - If ( sonic_irga_raw(5)=0 AND hor_wind>5 ) Then 'sonic_irga_raw(5) = CSAT3 diag word - Rn = Rn_meas*(1+(0.021286*(hor_wind-5))) + '*** Beginning of pyranometer measurements *** + VoltDiff (R_pyran, 1, PYRAN_VOLTAGE_RANG, PYRAN_ANALOG_INPUT, True, 0, ANALOG_INTEGRATION, 1, 0) + If R_pyran <=0 Then + R_pyran = 0 Else - Rn = Rn_meas + R_pyran =PYRAN_MULT*R_pyran + PYRAN_OFFSET EndIf - - '== LI190SB - VoltDiff (PAR_mV,1,mV20,LI190_DIFF,True,0,INTEG,1,0) 'MULT/OFF applied below - If (PAR_mV > 0) Then - PAR_flxdens = PAR_mV*li190_dens_mult - PAR_totflx = PAR_mV*li190_tot_mult + '*** End of pyranometer measurements *** + #EndIf + #If (SENSOR_LI190SB) Then + + '*** Beginning of LI190SB measurements *** + VoltDiff (PAR_density, 1, QUANTUM_VOLTAGE_RANGE, QUANTUM_ANALOG_INPUT, True, 0, ANALOG_INTEGRATION, 1, 0) + If (PAR_density <= 0) Then + PAR_density = 0 Else - PAR_flxdens = NAN - PAR_totflx = NAN + PAR_density = QUANTUM_MULT*PAR_density + QUANTUM_OFFSET EndIf + '*** End of LI190SB measurements *** + #EndIf - If (debug_on) Then CallTable debug + #If (SENSOR_SI111) Then - If (save_changes) Then - save_changes = False 'reset b4 we forget - save_current_choices() - CallTable(site_info) - EndIf - - just_had_1hz_scan = TRUE - NextScan + '*** Beginning of SI111 measurements *** + 'Measure SI111 body temperature + Therm109 (T_SI111_body, 1, 2*SI111_ANALOG_INPUT+1, SI111_EXCITATION, 0, ANALOG_INTEGRATION, 1.0, 0) 'T_SI111_body in C + m_SI111 = m0_SI111 + m1_SI111*T_SI111_body + m2_SI111*T_SI111_body*T_SI111_body 'T_SI111_body in C + b_SI111 = b0_SI111 + b1_SI111*T_SI111_body + b2_SI111*T_SI111_body*T_SI111_body 'T_SI111_body in C - '====================== SOIL SCAN INTERVAL ================================= - SlowSequence - Scan (SOIL_INTV,Sec,SOIL_BUFFER_SIZE,0) - - '== Garmin GPS - GPS (latitude_a,GPS_COM_ADDR,UTC_OFFSET*3600,0,nmea_sentence(1)) - CallTable(site_daily) - - #If (SHFP_ENABLED) Then - VoltDiff(soil_hfp1_heat_flux,1,mv200,HFP_1_SGNL_DIFF,TRUE,0,INTEG, _ - soil_hfp1_sensitivity,0) - VoltDiff(soil_hfp2_heat_flux,1,mv200,HFP_2_SGNL_DIFF,TRUE,0,INTEG, _ - soil_hfp2_sensitivity,0) - TCDiff(tcav_T,1,mV50,TCAV_DIFF,TypeE,panel_tmpr,1,0,INTEG,0,1) + VoltDiff (T_SI111_targeted, 1, mV20, SI111_ANALOG_INPUT, True, 0, ANALOG_INTEGRATION, 1, 0) + T_SI111_targeted = ((T_SI111_body + T_0C_K)^4 + m_SI111*T_SI111_targeted + b_SI111)^0.25 - T_0C_K 'T_SI111_targeted in C + '*** End of SI111 measurements *** #EndIf - - CallTable(soil) - just_had_soil_scan = TRUE + + '*** Beginning of updating files of station variables and planar fit angles *** + 'Determing whether or not the planar fit is used. It is used as long as one planar fit angle is not zero. + stn_var_check_count += 1 + + If (stn_conf_array_prev(stn_var_check_count) <> stn_conf_array(stn_var_check_count)) Then + + Select Case stn_var_check_count + 'Update geo-coordinates + Case 2, 3, 4, 5 + If (hemisphere_NS = Hemisphere_North) Then + latitude = ABS(latitude) + Else + latitude = - ABS(latitude) + EndIf + + If (hemisphere_EW = Hemisphere_East) Then + longitude = ABS(longitude) + Else + longitude = -ABS(longitude) + EndIf + + ' Update Aerodynamic height (z) + Case 6, 7, 8, 9 + Call Displacement_Roughness_heights (surface_type, displacement_user, roughness_user, height_canopy, height_measurement, d, z0, z) + surface_type_text = surface_type_array(surface_type) + + For i = 13 To 16 + If (stn_conf_array(i) = 100*z_prev) Then + stn_conf_array(i) = 100*z 'Default value of 100*z for all sectors in different directions + EndIf + Next + + z_prev = z + + EndSelect + + Calfile (stn_conf_array(1), NMBR_STN_VAR, "CPU:sys_conf_var.dat", 0) 'Store the new values to the file. + Move(stn_conf_array_prev(1), NMBR_STN_VAR , stn_conf_array(1), NMBR_STN_VAR) 'Update stn_conf_array_prev() + + EndIf + + If stn_var_check_count <= 4 Then + + If (planar_fit_angle_array_prev (stn_var_check_count, 1) <> planar_fit_angle_array (stn_var_check_count, 1)) _ + OR (planar_fit_angle_array_prev (stn_var_check_count, 2) <> planar_fit_angle_array (stn_var_check_count, 2)) Then + + Calfile (planar_fit_angle_array (1,1),8,"CPU:sys_planar_fit_angles.dat",0) 'Store the new values to the file. + + 'Keep current values of planar_fit_angle_array() in planar_fit_angle_prev_array() for later use as previous values + Move (planar_fit_angle_array_prev(stn_var_check_count, 1), 2, planar_fit_angle_array(stn_var_check_count, 1), 2) + + Planar_Fit_flg = FALSE + For i_slow = 1 To 4 + If (planar_fit_angle_array (i_slow, 1) <> 0) OR (planar_fit_angle_array (i_slow, 2) <> 0) Then + Planar_Fit_flg = TRUE + ExitFor + EndIf + Next i_slow + EndIf + EndIf + + If (stn_var_check_count = NMBR_STN_VAR) Then stn_var_check_count =0 + '*** End of updating files of station variables and planar fit angles *** + + slowsequence_finished_flg = TRUE NextScan EndProg diff --git a/src/old_default.cr3 b/src/old_default.cr3 new file mode 100644 index 0000000..f8bf2e0 --- /dev/null +++ b/src/old_default.cr3 @@ -0,0 +1,998 @@ +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +' Vineyard Pilot Study (2015) +' Laboratory for Atmospheric Research at Washington State University +' https://bitbucket.org/wsular/2015-vineyard-tower-logger +' +'========================== SEMI-EDITABLE VALUES ====================================== + +'manually update prior to pushing but do not check-in with other than empty string! +Const GIT_TAG = "" + +'----- TIMEZONE ----- +'This must be set as a constant for use with GPS instruction. It cannot be dynamically +'assigned based on logger's serial # because of this fact. +Const UTC_OFFSET = -8 'offset from UTC as +/- hours; PST = -8 + +'----- PROGRAM TIMING ----- +Const FAST_INTV = 100 'length of primary scan interval, milliseconds +Const SLOW_INTV = 1 'length of secondary scan interval, seconds +Const SOIL_INTV = 30 'length of slowest sensors (soil probes, gps, shfp) +Const STAT_OUT_30 = 30 'stats output interval minutes +Const SDM_PER = 30 'default SDM clock speed +Const INTEG = 250 'analog measurement integration time (250/_50hz/_60hz) + +'----- PROGRAM OPERATION ----- +Const SETTINGS_FILE = "CPU:wine_settings.dat" +Const FAST_BUFFER_SIZE = 600 '= 60sec = 1min buffer +Const SLOW_BUFFER_SIZE = 60 '= 1min buffer +Const SOIL_BUFFER_SIZE = 24 '= 2min buffer +Const DAILY_MEDNUM = 480 '# of values to include in median for daily stats +Const NMBR_WND_SAMPLES = 3000/FAST_INTV '#pts to compute 3sec mean horizontal wind + +'----- BASE SENSORS ANALOG INPUT MAP ------ +Const HMP_T_DIFF = 2 'HMP T diff input chan # +Const HMP_RH_DIFF = 3 'HMP RH diff input chan # +Const NRLITE_DIFF = 4 'NR-Lite2 diff input chan # +Const LI190_DIFF = 5 'LI190SB diff input chan # + +Const oh34B_WD_SE = 1 '034B single ended input chan # = D1H +Const oh34B_WD_VX = 1 '034B voltage excitation chan # +Const oh34B_WS_PULSE = 1 '034B pulse input chan # +Const TE525_PULSE = 2 'TE525 rain gage pulse input chan # + +'----- BASE SENSORS DIGITAL INPUT MAP ----- +Const EC100_SDM_ADDR = 1 'SDM address for EC100/EC150/CSAT3A +Const GPS_COM_ADDR = Com4 'GPS serial input port # +Const SDI_COM_ADDR = 5 'serial port reserved for SDI communications = Com3 + +'------ OPTIONAL SENSORS ANALOG INPUT MAP ----- +Const HFP_1_SGNL_DIFF = 6 'heat flux plate sensor signal diff input chan # +Const HFP_2_SGNL_DIFF = 7 ' plate #2 + +Const TCAV_DIFF = 8 'averaging thermcouple diff input chan # + + +ConstTable + Const SHFP_ENABLED = True +EndConstTable + +'----- FIXED CALIBRATION VALUES ------ +Const HMP_T_MULT = (60 - -80)/1000 '-80 to +60 *C over 1V = 0.14 +Const HMP_T_OFFSET = -80 +Const HMP_RH_MULT = (100 - 0)/1000 '0 - 100% over 1V +Const HMP_RH_OFFSET = 0 +Const oh34B_WD_MULT = 720 '720/0 as specified in CSI manual: +Const oh34B_WD_OFFSET = 0 ' Met One 034B Windset rev3/12, pg 6 +Const oh34B_WS_MULT = 0.7989 '0.7989/0.28 as specified in above CSI manual +Const oh34B_WS_OFFSET = 0.28 +Const TE525_MULT = 0.254 'Table 7-2, CSI manual rev 8/16 + + +'========================== NO USER-SERVICEABLE PARTS BELOW =========================== +'----- PHYSICAL CONSTANTS ----- +Const MW_CO2 = 44.01 'molecular weight of CO2, g/mol +Const MW_H2O = 18.016 'molecular weight of water, g/mol +Const MW_AIR = 28.964 'molecular weight of dry air, g/mol +Const MU_WPL = MW_AIR/MW_H2O 'Ratio of the molecular weight of dry air to water vapor +Const R = .0083143 'Universal gas constant [kPa m^3/(K mol)] +Const RD = R/29 'Gas constant for dry air [kPa m^3/(K g)] +Const LV = 2440 'Estimate of the latent heat of vaporization [J/g] +Const RV = R/18 'Gas constant for water vapor [kPa m^3/(K g)] +Const CP = 1004.67 'Estimate of heat capacity of air [J/(kg K)] + + +'----- PROGRAM OPERATION VARIABLES ----- +Public debug_on As Boolean +Dim self As String * 16 +Dim filehandle As Long +Dim scan_count As Long 'Number scans executed. +Dim just_had_1hz_scan As Boolean 'Flag used to indicate the SlowSequence has finished its scan. +Dim inbetween_1hz_scan As Boolean = {TRUE} 'Flag used to decimate statistics in main scan. +Dim just_had_soil_scan As Boolean +Dim inbetween_5s_scan As Boolean = {TRUE} +Dim i As Long 'Main scan index variable. +Dim ii As Long 'Slow sequence scan index variable. +Dim n = {1} +Units n = samples + +Dim sensor_shfp As Boolean 'set based on site SN + +'----- RETAINED SETTINGS ----- +Const NUM_SETTINGS = {24} 'set to length of settings array +Const WRITEFILE = 0 +Const READFILE = 1 + +Dim settings(NUM_SETTINGS) 'values retained via file written to datalogger CPU +Alias settings(1) = sonic_azimuth +Alias settings(2) = NRLite2_sens +Alias settings(3) = LI190SB_sens +Alias settings(4) = cup_ws_enabled +Alias settings(5) = vane_wd_enabled +Alias settings(6) = rain_enabled +Alias settings(23) = hfp1_sens +Alias settings(24) = hfp2_sens +Units hfp1_sens = uV/W/m^2 +Units hfp2_sens = uV/W/m^2 +Units sonic_azimuth = degEofTN +Units NRLite2_sens = uV/W/m^2 +Units LI190SB_sens = uA/mmol/m^2/s + +Public choice(NUM_SETTINGS) +Alias choice(1) = set_sonic_azimuth +Alias choice(2) = set_NRLite2_sens +Alias choice(3) = set_LI190SB_sens +Alias choice(4) = set_cup_ws_enabled +Alias choice(5) = set_vane_wd_enabled +Alias choice(6) = set_rain_enabled +Alias choice(23) = set_hfp1_sens +Alias choice(24) = set_hfp2_sens + + +'*********** CR3000 ************ +Dim panel_tmpr +Units panel_tmpr = C +Dim batt_volt +Units batt_volt = V + + +'*********** EC100/EC150/CSAT3A ********** +Const OFFSET = 17 'min # recs req'd to compensate for IRGA/CSAT lags on-the-fly +Const BANDWIDTH = 20 '20 = 20 Hz +Const DELAY_EC150 = INT (4000/FAST_INTV/BANDWIDTH) 'Automatically computed lag of the EC150 data. +Const EC150_REC_BCK = OFFSET-DELAY_EC150 'Number of records back to align EC150 data. + +Dim sonic_irga_raw(13) 'unlagged EC150 irga + CSAT3A sonic data + +Dim sonic(5) 'lagged working CSAT3A data +Alias sonic(1) = Ux +Alias sonic(2) = Uy +Alias sonic(3) = Uz +Alias sonic(4) = Ts +Alias sonic(5) = diag_sonic +Units Ux = m/s +Units Uy = m/s +Units Uz = m/s +Units Ts = C +Units diag_sonic = bitmap + +Dim irga(9) +Alias irga(1) = CO2 +Alias irga(2) = H2O +Alias irga(3) = diag_irga +Alias irga(4) = amb_tmpr +Alias irga(5) = amb_press +Alias irga(6) = CO2_signal +Alias irga(7) = H2O_signal +Alias irga(8) = Tc +Alias irga(9) = CO2_hf 'irga(1) calculated using sonic temp instead of thermistor +Units CO2 = mg/m^3 +Units H2O = g/m^3 +Units diag_irga = bitmap +Units amb_tmpr = C +Units amb_press = kPa +Units CO2_signal = unity +Units H2O_signal = unity +Units Tc = C +Units CO2_hf = mg/m^3 + +Dim CO2_hf_ppm +Units CO2_hf_ppm = ppmv + +Dim mask As Long +Dim diag_sonic_tmp As Long 'used to break out the CSAT3A sonic head diagnostic bits. +Dim sonic_disable_f As Boolean 'TRUE if CSAT3A diag warning flag, SDM error or no data +Dim diag_irga_tmp As Long 'used to break out the EC150 diagnostic bits. +Dim irga_disable_f As Boolean 'TRUE when EC150 sends bad data. + +Dim cov_array_sonic(1,4) 'used to hold input data for cov instructions +Dim cov_array_cs(4,4) + +Dim etcvar(3) +Alias etcvar(1) = divisor 'used to find molar mixing ratio. +Alias etcvar(2) = rho_d_mean 'Density of dry air used in WPL [kg / m^3]. +Alias etcvar(3) = sigma_wpl 'density of water vapor / density of dry air. + +Dim results(19) +Alias results(1) = Ts_absolute 'sonic temp in Kelvin +Alias results(2) = CO2_ppm 'CO2 mixing ratio +Alias results(3) = Xv 'H2O mixing ratio +Alias results(4) = L 'Obukohov length +Alias results(5) = Hs 'Sensible heat flux using sonic temperature. +Alias results(6) = tau 'Momentum flux. +Alias results(7) = u_star 'Friction velocity. +Alias results(8) = sonic_uptime +Alias results(9) = Fc_wpl 'Carbon dioxide flux (EC150), with WPL +Alias results(10) = LE_wpl 'Latent heat flux (EC150), with WPL +Alias results(11) = Hc 'Sensible heat flux with h2o-corrected sonic temp +Alias results(12) = irga_uptime +Alias results(13) = rho_a_mean +Alias results(14) = Fc_irga 'Carbon dioxide flux (EC150), without WPL +Alias results(15) = LE_irga 'Latent heat flux (EC150), without WPL +Alias results(16) = CO2_wpl_LE 'Carbon dioxide flux (EC150), WPL latent heat flux. +Alias results(17) = CO2_wpl_H 'Carbon dioxide flux (EC150), WPL sensible heat flux. +Alias results(18) = H2O_wpl_LE 'Latent heat flux (EC150), WPL latent heat flux. +Alias results(19) = H2O_wpl_H 'Latent heat flux (EC150), WPL sensible heat flux. +Units Ts_absolute = Kelvin +Units CO2_ppm = ppm +Units Xv = ppt +Units L = m +Units Hs = W/m^2 +Units tau = kg/(m s^2) +Units u_star = m/s +Units sonic_uptime = unity +Units Fc_wpl = mg/(m^2 s) +Units LE_wpl = W/m^2 +Units Hc = W/m^2 +Units irga_uptime = unity +Units rho_a_mean = kg/m^3 +Units Fc_irga = mg/(m^2 s) +Units LE_irga = W/m^2 +Units CO2_wpl_LE = mg/(m^2 s) +Units CO2_wpl_H = mg/(m^2 s) +Units H2O_wpl_LE = W/m^2 +Units H2O_wpl_H = W/m^2 + +Dim Fc_hf_irga 'CO2 flux using alt. CO2 value, without WPL +Dim CO2_hf_wpl_LE 'CO2 flux WPL latent heat component, using alt. CO2 value +Dim CO2_hf_wpl_H 'CO2 flux WPL sensible heat component, using alt. CO2 value +Dim Fc_hf_wpl 'CO2 flux using alt. CO2 value with WPL corrections +Units Fc_hf_wpl = mg/m^2/s + + +'********** HMP-155A temp/RH probe ********** +Dim hmp(4) +Alias hmp(1) = T_hmp 'HMP temperature +Alias hmp(2) = RH_hmp 'HMP relative humidity +Alias hmp(3) = e_hmp 'HMP vapor pressure +Alias hmp(4) = e_sat_hmp 'HMP saturation vapor pressure +Units T_hmp = C +Units RH_hmp = percent +Units e_hmp = kPa +Units e_sat_hmp = kPa + +Dim hmp_stats(3) +Alias hmp_stats(1) = H2O_hmp_mean +Alias hmp_stats(2) = RH_hmp_Avg +Units H2O_hmp_mean = g/m^3 +Units RH_hmp_Avg = % + + +'********** NR-Lite2 ********** +Dim nrlite_mult + +Dim nrlite(2) +Alias nrlite(1) = Rn +Alias nrlite(2) = Rn_meas +Units Rn = W/m^2 +Units Rn_meas = W/m^2 + +Dim hor_wind +Dim hor_wind_raw + + +'********** LI190SB quantum PAR sensor *********** +Dim li190_dens_mult +Dim li190_tot_mult + +Dim par(3) +Alias par(1) = PAR_mV +Alias par(2) = PAR_flxdens +Alias par(3) = PAR_totflx +Units PAR_mV = mV +Units PAR_flxdens = umol/m^2/s +Units PAR_totflx = mmol/m^2 + + +'*********** 034B wind vane ********** +Dim oh34B(2) +Alias oh34B(1) = WS_ms +Alias oh34B(2) = WindDir +Units WS_ms = m/s +Units WindDir = degrees + + +'********** TE525 rain gage ********** +Dim Rain_mm +Units Rain_mm=mm + + +'********** GPS16X-HVS ********** +Dim nmea_sentence(2) As String * 90 +Dim gps_data(15) +Alias gps_data(1) = latitude_a 'Degrees latitude (+ = East; - = West) +Alias gps_data(2) = latitude_b 'Minutes latitude +Alias gps_data(3) = longitude_a 'Degress longitude (+ = East; - = West) +Alias gps_data(4) = longitude_b 'Minutes longitude +Alias gps_data(5) = speed 'Speed +Alias gps_data(6) = course 'Course over ground +Alias gps_data(7) = magnetic_variation 'Magnetic variation from true north (+ = East; - = West) +Alias gps_data(8) = fix_quality 'GPS fix quality: 0 = invalid, 1 = GPS, 2 = 'differential GPS, 6 = estimated +Alias gps_data(9) = nmbr_satellites 'Number of satellites used for fix +Alias gps_data(10) = altitude 'Antenna altitude +Alias gps_data(11) = pps 'Elapsed ms since last pulse per second (PPS) from GPS +Alias gps_data(12) = dt_since_gprmc 'Time since last GPRMC string, normally less than '1 second +Alias gps_data(13) = gps_ready 'Counts from 0 to 10, 10 = ready +Alias gps_data(14) = max_clock_change 'Maximum value the clock was changed +Alias gps_data(15) = nmbr_clock_change 'Number of times the clock was changed +Units latitude_a = degreesN +Units latitude_b = minutesN +Units longitude_a = degreesE +Units longitude_b = minutesE +Units speed = m/s +Units course = degreesEofN +Units magnetic_variation = degreesEofN +Units fix_quality = unitless +Units nmbr_satellites = unitless +Units altitude = m +Units pps = ms +Units dt_since_gprmc = s +Units gps_ready = unitless +Units max_clock_change = ms +Units nmbr_clock_change = occurrences + + +'********** HFP01SC heat flux plate ********** +Dim hfp(4) +Alias hfp(1) = soil_hfp1_heat_flux +Alias hfp(2) = soil_hfp2_heat_flux +Alias hfp(3) = soil_hfp1_sensitivity +Alias hfp(4) = soil_hfp2_sensitivity +Units soil_hfp1_heat_flux = W/m^2 +Units soil_hfp2_heat_flux = W/m^2 +Units soil_hfp1_sensitivity = W/m^2/mV +Units soil_hfp2_sensitivity = W/m^2/mV + +'********** Averaging thermocouple ********** +Dim tcav(1) +Alias tcav(1) = tcav_T +Units tcav = degC + + +'********** Intermediate variables ********** +Dim dly_data_out(13) 'used to temporarily store the lagged record. + +Dim work_stats_out(40) +'sonic processing +Alias work_stats_out(1) = Ts_Std 'results of covariance instructions, 10 qntys +Alias work_stats_out(2) = Ts_Ux_cov +Alias work_stats_out(3) = Ts_Uy_cov +Alias work_stats_out(4) = Ts_Uz_cov +Alias work_stats_out(5) = Ux_Std +Alias work_stats_out(6) = Ux_Uy_cov +Alias work_stats_out(7) = Ux_Uz_cov +Alias work_stats_out(8) = Uy_Std +Alias work_stats_out(9) = Uy_Uz_cov +Alias work_stats_out(10) = Uz_Std +Alias work_stats_out(11) = wnd_spd 'results of windvector instruction, 4 qntys +Alias work_stats_out(12) = rslt_wnd_spd +Alias work_stats_out(13) = rslt_wnd_dir +Alias work_stats_out(14) = std_wnd_dir +Alias work_stats_out(15) = sonic_samples '1 @ totalize +'irga processing +Alias work_stats_out(16) = CO2_mg_m3_Std 'results of 3 covariances, 12 #s +Alias work_stats_out(17) = CO2_Ux_cov +Alias work_stats_out(18) = CO2_Uy_cov +Alias work_stats_out(19) = CO2_Uz_cov +Alias work_stats_out(20) = H2O_g_m3_Std +Alias work_stats_out(21) = H2O_Ux_cov +Alias work_stats_out(22) = H2O_Uy_cov +Alias work_stats_out(23) = H2O_Uz_cov +Alias work_stats_out(24) = Tc_stdev +Alias work_stats_out(25) = Tc_Ux_cov +Alias work_stats_out(26) = Tc_Uy_cov +Alias work_stats_out(27) = Tc_Uz_cov +Alias work_stats_out(28) = CO2_mg_m3_Avg 'four averages +Alias work_stats_out(29) = H2O_g_m3_Avg +Alias work_stats_out(30) = amb_press_Avg +Alias work_stats_out(31) = Tc_Avg +Alias work_stats_out(32) = irga_samples '1 @ totalize +'hmp processing +Alias work_stats_out(33) = e_hmp_Avg 'two averages +Alias work_stats_out(34) = e_sat_hmp_Avg +Alias work_stats_out(35) = samples_possible +Alias work_stats_out(36) = CO2_hf_mg_m3_Avg '1 average +Alias work_stats_out(37) = CO2_hf_mg_m3_Std 'results of 1 covariance, 4#s +Alias work_stats_out(38) = CO2_hf_Ux_cov +Alias work_stats_out(39) = CO2_hf_Uy_cov +Alias work_stats_out(40) = CO2_hf_Uz_cov +Units Ts_Std = C +Units Ts_Ux_cov = C m/s +Units Ts_Uy_cov = C m/s +Units Ts_Uz_cov = C m/s +Units Ux_Std = m/s +Units Ux_Uy_cov = (m/s)^2 +Units Ux_Uz_cov = (m/s)^2 +Units Uy_Std = m/s +Units Uy_Uz_cov = (m/s)^2 +Units Uz_Std = m/s +Units wnd_spd = m/s +Units rslt_wnd_spd = m/s +Units rslt_wnd_dir = degrees +Units std_wnd_dir = degrees +Units sonic_samples = samples +Units CO2_mg_m3_Std = mg/m^3 +Units CO2_Ux_cov = mg/(m^2 s) +Units CO2_Uy_cov = mg/(m^2 s) +Units CO2_Uz_cov = mg/(m^2 s) +Units H2O_g_m3_Std = g/m^3 +Units H2O_Ux_cov = g/(m^2 s) +Units H2O_Uy_cov = g/(m^2 s) +Units H2O_Uz_cov = g/(m^2 s) +Units Tc_stdev = C +Units Tc_Ux_cov = C m/s +Units Tc_Uy_cov = C m/s +Units Tc_Uz_cov = C m/s +Units CO2_mg_m3_Avg = mg/m^3 +Units H2O_g_m3_Avg = g/m^3 +Units amb_press_Avg = kPa +Units Tc_Avg = C +Units irga_samples = samples +Units e_hmp_Avg = kPa +Units e_sat_hmp_Avg = kPa +Units samples_possible = samples +Units CO2_hf_mg_m3_Std = mg/m^3 +Units CO2_hf_Ux_cov = mg/m^2/s +Units CO2_hf_Uy_cov = mg/m^2/s +Units CO2_hf_Uz_cov = mg/m^2/s + + +'============================ REMOTE MONITORING ============================ +DataTable(debug,True,2) + Sample(2,hmp(1),IEEE4) + Sample(2,nrlite(1),IEEE4) + Sample(3,par(1),IEEE4) + Sample(2,oh34B(1),IEEE4) + Sample(1,Rain_mm,IEEE4) + Sample(15,gps_data(1),IEEE4) + Sample(4,hfp(1),IEEE4) + Sample(1,tcav(1),IEEE4) +EndTable + + +'=========================== PROCESSING DATA TABLES =================================== +DataTable(work_delay_ec100,TRUE,OFFSET) 'handles lagging CSAT+IRGA data + TableHide + Sample(13,sonic_irga_raw(1),IEEE4) +EndTable + +DataTable(work_30min,TRUE,1) + TableHide + DataInterval(0,STAT_OUT_30,Min,1) + Covariance(4,cov_array_sonic(1,1),IEEE4,sonic_disable_f,10) + WindVector(1,-1*Uy,Ux,IEEE4,sonic_disable_f,0,1,2) + Totalize(1,n,IEEE4,sonic_disable_f) + FieldNames("sonic_total") + Covariance(4,cov_array_cs(1,1),IEEE4,irga_disable_f,4) + Covariance(4,cov_array_cs(2,1),IEEE4,irga_disable_f,4) + Covariance(4,cov_array_cs(3,1),IEEE4,irga_disable_f,4) + Average(1,CO2,IEEE4,irga_disable_f) + Average(1,H2O,IEEE4,irga_disable_f) + Average(1,amb_press,IEEE4,irga_disable_f) + Average(1,Tc,IEEE4,irga_disable_f) + Totalize(1,n,IEEE4,irga_disable_f) + FieldNames("irga_total") + Average(1,e_hmp,IEEE4,(inbetween_1hz_scan OR e_hmp=NAN)) + Average(1,e_sat_hmp,IEEE4,(inbetween_1hz_scan OR e_sat_hmp=NAN)) + Totalize(1,n,IEEE4,False) + Average(1,CO2_hf,IEEE4,irga_disable_f) + Covariance(4,cov_array_cs(4,1),IEEE4,irga_disable_f,4) +EndTable + +'=========================== BASE OUTPUT DATA TABLES ================================== +Const DAYS = 42 '6 weeks + +'time series data @ 10hz +DataTable (tsdata,TRUE,600 + DataInterval (0,FAST_INTV,mSec,100) + TableFile("CRD:TOA5_" & self & ".tsdata_", 108, 24, 0, 1, hr, 0, 0) + CardOut(0, DAYS*864000) + Sample (4,sonic_irga_raw(1),IEEE4) + FieldNames ("Ux,Uy,Uz,Ts") + Sample (1,sonic_irga_raw(5),FP2) + FieldNames ("diag_sonic") + Sample (1,sonic_irga_raw(13),IEEE4) + FieldNames ("CO2_hf") + Sample (5,sonic_irga_raw(6),IEEE4) + FieldNames ("CO2,H2O,diag_irga,amb_tmpr,amb_press") + Sample (2,sonic_irga_raw(11),FP2) + FieldNames ("CO2_signal,H2O_signal") +EndTable + +'30min statistics +DataTable (stats30,TRUE,10) + DataInterval (0,STAT_OUT_30,Min,10) + CardOut (0, DAYS*48) + Sample(1,L,IEEE4) 'monin obukhov length, meters + Sample(1,u_star,FP2) 'friction velocity, m/s + Sample(1,tau,FP2) 'momemtum flux, kg/(m s^2) + Sample(1,Fc_wpl,IEEE4) 'density-corrected (WPL) CO2 flux, mg/m3 + Sample(1,Fc_hf_wpl,IEEE4) 'WPL-corrected CO2 flux using alt. CO2 value + Sample(1,LE_wpl,FP2) 'density-corrected (WPL) latent heat flux, W/m2 + Sample(1,Hc,FP2) 'density-corrected sensible heat flux, W/m2 + Average(1,Ts,FP2,sonic_disable_f) 'mean sonic temperature, degC + Sample(1,Ts_Std,FP2) 'stdev of sonic temp, degC + Sample(1,Tc_Avg,FP2) 'mean of corrected sonic temp, degC + Sample(1,Uz_Std,FP2) 'stdev of vertical wind, m/s + Sample(1,wnd_spd,FP2) 'mean scalar wind speed, m/s + Sample(1,rslt_wnd_spd,FP2) 'vector mean wind speed, m/s + Sample(1,rslt_wnd_dir,FP2) 'mean wind direction rel2 north, degrees + Sample(1,std_wnd_dir,FP2) 'scalar stdev of wind direction, degrees + Sample(1,sonic_uptime,FP2) + Average(1,CO2_ppm,FP2,irga_disable_f) + Sample (1,CO2_mg_m3_Avg,FP2) 'mean of CO2 conc, mg/m3 + Sample (1,CO2_mg_m3_Std,FP2) 'stdev of CO2 conc, mg/m3 + Sample(1,CO2_hf_mg_m3_Avg,FP2) + Sample(1,CO2_hf_mg_m3_Std,FP2) + Average(1,CO2_signal,FP2,irga_disable_f) + Average(1,(Xv / MU_WPL),FP2,irga_disable_f) + FieldNames("H2O_g_kg_Avg") + Sample (1,H2O_g_m3_Avg,FP2) 'mean of H2O conc, g/m3 + Sample (1,H2O_g_m3_Std,FP2) 'stdev of H2O conc, g/m3 + Average(1,H2O_signal,FP2,irga_disable_f) + Average(1,amb_tmpr,IEEE4,irga_disable_f) + Sample (1,amb_press_Avg,IEEE4) 'mean of ambient pressure, kPa + Sample (1,irga_uptime,FP2) + Average(1,T_hmp,IEEE4,(inbetween_1hz_scan OR T_hmp=NAN)) + Sample (1,RH_hmp_Avg,FP2) 'mean HMP relative humidity, % + Sample (1,e_hmp_Avg,FP2) + Sample (1,e_sat_hmp_Avg,FP2) + Average(1,Rn,FP2,(inbetween_1hz_scan OR Rn=NAN)) + Average(1,Rn_meas,FP2,inbetween_1hz_scan OR Rn_meas=NAN)) + Totalize(1,PAR_totflx,FP2,(inbetween_1hz_scan OR PAR_totflx=NAN)) + Average(1,PAR_flxdens,FP2,(inbetween_1hz_scan OR PAR_flxdens=NAN)) + WindVector(1,WS_ms,WindDir,FP2,(WS_ms=NAN OR WindDir=NAN),0,0,2) + FieldNames("Met1_wnd_spd,Met1_rslt_wnd_spd,Met1_rslt_wnd_dir,Met1_std_wnd_dir") + 'units propogate from other datatable since names match + Totalize(1,Rain_mm,FP2,Rain_mm=NAN) '10hz loop + Average(1,soil_hfp1_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp1_heat_flux=NAN)) + Sample (1,soil_hfp1_sensitivity,IEEE4) + Average(1,soil_hfp2_heat_flux, IEEE4,(inbetween_5s_scan OR soil_hfp2_heat_flux=NAN)) + Sample (1,soil_hfp2_sensitivity,IEEE4) + Average(1,panel_tmpr,FP2,(inbetween_1hz_scan OR panel_tmpr=NAN)) + Average(1,batt_volt,FP2,(inbetween_1hz_scan OR batt_volt=NAN)) +EndTable + +'Daily values +DataTable (site_daily,TRUE,2) + DataInterval (0,1,Day,10) + CardOut(0, DAYS) + Median(1,(latitude_a + latitude_b/60),DAILY_MEDNUM,IEEE4,(latitude_a=NAN OR latitude_b=NAN)) + FieldNames("latitude_Med") + Units latitude_Med = decDegreesN + Median(1,(longitude_a + longitude_b/60),DAILY_MEDNUM,IEEE4,(longitude_a=NAN OR longitude_b=NAN)) + FieldNames("longitude_Med") + Units longitude_Med = decDegreesE + Median(1,magnetic_variation,DAILY_MEDNUM,FP2,magnetic_variation=NAN) + Average(1,nmbr_satellites,FP2,nmbr_satellites=NAN) + Median(1,altitude,DAILY_MEDNUM,IEEE4,altitude=NAN) + Average(1,altitude,IEEE4,altitude=NAN) + Minimum(1,gps_ready,FP2,gps_ready=NAN,0) + Sample(1,max_clock_change,UINT2) + Sample(1,nmbr_clock_change,UINT2) + Minimum(1,batt_volt,FP2,batt_volt=NAN,1) + Maximum(1,batt_volt,FP2,batt_volt=NAN,1) + Minimum(1,T_hmp,FP2,T_hmp=NAN,1) + Maximum(1,T_hmp,FP2,T_hmp=NAN,1) +EndTable + +'program start-up information +DataTable (site_info,TRUE,20) + CardOut(0,1000) + Sample(1,UTC_OFFSET,FP2) + FieldNames("UTC_offset") + Units UTC_OFFSET = hours + Sample(1,sonic_azimuth,FP2) + Sample(1,NRLite2_sens,FP2) + FieldNames("NR_sens") + Sample(1,LI190SB_sens,FP2) + FieldNames("PAR_sens") + Sample(1,soil_hfp1_sensitivity,IEEE4) 'heat flux plate #1 info + FieldNames("HFP_1_sens") + Units HFP_1_SENS = W/m^2/mV + Sample(1,soil_hfp2_sensitivity,IEEE4) 'heat flux plate #2 info + FieldNames("HFP_2_sens") + Units HFP_2_SENS = W/m^2/mV + Sample(1,Status.CompileResults,String) + FieldNames("CompileResults") + Sample(1,Status.CardStatus,String) + FieldNames("CardStatus") + Sample(1,Status.RunSignature,UINT2) 'program information + FieldNames("RunSig") + Sample(1,Status.ProgSignature,UINT2) + FieldNames("ProgSig") + Sample(1,GIT_TAG,String) + FieldNames("GitRepoTag") + Sample(1,sensor_shfp,Boolean) + FieldNames("hfp_installed") +EndTable + +'=========================== SUPPLEMENTAL OUTPUT DATA TABLES ========================== +DataTable(soil,True,100) + DataInterval(0,5,Min,4) + CardOut(0,DAYS*288) + Average(1,soil_hfp1_heat_flux,IEEE4,soil_hfp1_heat_flux=NAN)) + Average(1,soil_hfp2_heat_flux,IEEE4,soil_hfp2_heat_flux=NAN)) + Average(1,tcav_T,IEEE4,tcav_T=NAN) +EndTable + + + +'================================ MENU ================================================ +Const Enable = True +Const Yes = True +Const Apply = True +Const Disable = False +Const No = False +Const Cancel = False +Public save_changes As Boolean +Dim recompile As Boolean + +DisplayMenu("Vineyard DAQ", -1) 'add submenu to main + SubMenu("Initial Setup") + SubMenu("Soil heat flux plate") + MenuItem("Enable?", SHFP_ENABLED) + MenuPick(Yes, No) + EndSubMenu + MenuRecompile("Apply now?", recompile) + MenuPick(No, Apply) + EndSubMenu + + SubMenu("Settings") + SubMenu("Sonic anemometer") + MenuItem("Azmiuth", set_sonic_azimuth) + DisplayLine(" degE of True North") + EndSubMenu + SubMenu("Net radiometer") + MenuItem("Sensitivity", set_NRLite2_sens) + DisplayLine(" uV/W/m^2") + EndSubMenu + SubMenu("PAR sensor") + MenuItem("Sensitivity", set_LI190SB_sens) + DisplayLine(" uA/mmol/m^s/s") + EndSubMenu + SubMenu("Cup & vane windset") + MenuItem("Enable WS?", set_cup_ws_enabled) + MenuPick(Yes, No) + MenuItem("Enable WD?", set_vane_wd_enabled) + MenuPick(Yes, No) + EndSubMenu + SubMenu("Rain gage") + MenuItem("Enable?", set_rain_enabled) + MenuPick(Yes, No) + EndSubMenu + #If (SHFP_ENABLED) Then + SubMenu("Soil heat flux plate") + DisplayLine("Plate #1 (DF 6):") + MenuItem("Sensitivity", set_hfp1_sens) + DisplayLine(" uV/W/m^2") + DisplayLine("Plate #2 (DF 7):") + MenuItem("Sensitivity", set_hfp2_sens) + DisplayLine(" uV/W/m^2") + EndSubMenu + #Else + DisplayLine("SHFP disabled") + #EndIf + SubMenu("Save changes") + MenuItem("Save now?", save_changes) + MenuPick(Cancel,Yes) + EndSubMenu + EndSubMenu + + SubMenu("Debug") + SubMenu("Monitor sensors") + DisplayValue("sonic Ux", sonic_irga_raw(1)) + DisplayValue("sonic Uy", sonic_irga_raw(2)) + DisplayValue("sonic Uz", sonic_irga_raw(3)) + DisplayValue("sonic Ts", sonic_irga_raw(4)) + DisplayValue("sonic diag", sonic_irga_raw(5)) + DisplayValue("irga CO2", sonic_irga_raw(6)) + DisplayValue("irga H2O", sonic_irga_raw(7)) + DisplayValue("irga diag", sonic_irga_raw(8)) + DisplayValue("irga tmpr", sonic_irga_raw(9)) + DisplayValue("irga press", sonic_irga_raw(10)) + DisplayValue("irga CO2 sig", sonic_irga_raw(11)) + DisplayValue("irga H2O sig", sonic_irga_raw(12)) + DisplayValue("HMP tmpr", T_hmp) + DisplayValue("HMP RH", RH_hmp) + DisplayValue("NR Rn", Rn) + DisplayValue("NR Rn meas", Rn_meas) + DisplayValue("PAR mV", PAR_mV) + DisplayValue("PAR flx dens", PAR_flxdens) + DisplayValue("PAR total flx", PAR_totflx) + DisplayValue("034B WS", WS_ms) + DisplayValue("034B WD", WindDir) + DisplayValue("Rain", Rain_mm) + DisplayValue("GPS lat deg", latitude_a) + DisplayValue("GPS lat min", latitude_b) + DisplayValue("GPS long deg", longitude_a) + DisplayValue("GPS long min", longitude_b) + DisplayValue("GPS speed", speed) + DisplayValue("GPS course", course) + DisplayValue("GPS mag var", magnetic_variation) + DisplayValue("GPS fix qual", fix_quality) + DisplayValue("GPS num sats", nmbr_satellites) + DisplayValue("GPS altitude", altitude) + DisplayValue("GPS pps", pps) + DisplayValue("GPS msg time", dt_since_gprmc) + DisplayValue("GPS ready", gps_ready) + DisplayValue("GPS max adj", max_clock_change) + DisplayValue("GPS num adj", nmbr_clock_change) + DisplayValue("SHFP 1 flux", soil_hfp1_heat_flux) + DisplayValue("SHFP 1 sens", soil_hfp1_sensitivity) + DisplayValue("SHFP 2 flux", soil_hfp2_heat_flux) + DisplayValue("SHFP 2 sens", soil_hfp2_sensitivity) + DisplayValue("TCAV tmpr", tcav_T) + EndSubMenu + MenuItem("Debug table", debug_on) + MenuPick(Disable,Enable) + EndSubMenu +EndMenu + + +'=============================== SUBROUTINES ========================================== +Sub set_default_choices() + set_sonic_azimuth = NAN + set_NRLite2_sens = 0 + set_LI190SB_sens = 0 + set_cup_ws_enabled = False + set_vane_wd_enabled = False + set_rain_enabled = False + set_hfp1_sens = 0 + set_hfp2_sens = 0 +EndSub + +Sub populate_choices() + Move(choice(1),NUM_SETTINGS,settings(1),NUM_SETTINGS) +EndSub + +Sub save_current_choices() + 'input validation + + Move(settings(1),NUM_SETTINGS,choice(1),NUM_SETTINGS) + Calfile(settings,NUM_SETTINGS,SETTINGS_FILE,WRITEFILE) + + 'update dependent variables + nrlite_mult = 1000/NRLite2_sens + li190_dens_mult = 1000/(LI190SB_sens*0.604) + li190_tot_mult = (1/(LI190SB_sens*0.604))*(SLOW_INTV/1) + + sensor_shfp = SHFP_ENABLED + #If (SHFP_ENABLED) Then + soil_hfp1_sensitivity = 1000/hfp1_sens + soil_hfp2_sensitivity = 1000/hfp2_sens + #Else + soil_hfp1_heat_flux = NAN + soil_hfp1_sensitivity = 0 + soil_hfp2_heat_flux = NAN + soil_hfp2_sensitivity = 0 + #EndIf +EndSub + +Sub setup() + filehandle = FileOpen(SETTINGS_FILE,"rb",0) ' attempt to open file + FileClose(filehandle) + If (filehandle = 0) Then 'if file not found + set_default_choices() + Else + Calfile(settings,NUM_SETTINGS,SETTINGS_FILE,READFILE) + populate_choices() + EndIf + save_current_choices() + + CallTable (site_info) + + SDMSpeed (SDM_PER) + self = Status.StationName +EndSub + + +'================================ PROGRAM ============================================= +BeginProg + setup() + + Scan (FAST_INTV,mSec,FAST_BUFFER_SIZE,0) + + '== 034B wind vane acquisition + BrHalf(WindDir,1,mV5000,oh34B_WD_SE,oh34B_WD_VX,1,5000,True,0,INTEG,oh34B_WD_MULT,oh34B_WD_OFFSET) + If (vane_wd_enabled) Then + If ((WindDir >= 360) OR (WindDir < 0)) Then (WindDir = 0) + Else + WindDir = NAN + EndIf + PulseCount(WS_ms,1,oh34B_WS_PULSE,2,1,oh34B_WS_MULT,oh34B_WS_OFFSET) + If (cup_ws_enabled) Then + If (WS_ms <= oh34B_WS_OFFSET) Then (WS_ms = 0) + Else + WS_ms = NAN + EndIf + + '== TE525 rain gage acquisition + PulseCount(Rain_mm,1,TE525_PULSE,2,0,TE525_MULT,0) + If (NOT rain_enabled) Then Rain_mm = NAN + + '== EC100/EC150/CSAT3A irga/sonic acquisition + EC100 (sonic_irga_raw(1),EC100_SDM_ADDR,2) + CallTable(work_delay_ec100) + CallTable(tsdata) + + '== NR-Lite2 correction factor calc + hor_wind_raw = SQR (sonic_irga_raw(1)*sonic_irga_raw(1)+sonic_irga_raw(2)*sonic_irga_raw(2)) + AvgRun (hor_wind,1,hor_wind_raw,NMBR_WND_SAMPLES) '3-sec running mean of horiz. WS + + If ( scan_count >= OFFSET ) Then 'IF HAVE ENUF SCANS TO DO STATS, + + '== EC100/EC150/CSAT3A lagged data retrieval + GetRecord (dly_data_out(1),work_delay_ec100,EC150_REC_BCK) + Move (Ux,5,dly_data_out(1),5) 'Ux, Uy, Uz, Ts, diag_sonic + Move (CO2,7,dly_data_out(6),8) '+H2O,diag_irga,amb_tmpr,amb_press,CO2_signal,H2O_signal,CO2_hf + If ( (diag_sonic <> NAN) AND (diag_sonic <> -1) ) Then + sonic_disable_f = diag_sonic AND &h3f '= 0011 1111 + Else + Move(Ux,5,NAN,1) + sonic_disable_f = TRUE + EndIf + Ts_absolute = IIF(sonic_disable_f, NAN, Ts+273.15) + If ( (diag_irga <> NAN) AND (diag_irga <> -1) ) Then + irga_disable_f = sonic_disable_f OR (diag_irga AND &h1) 'bit 0 always HI for warning + Else + Move(CO2,8,NAN,1) + irga_disable_f = TRUE + EndIf + If ( NOT irga_disable_f ) Then + Tc = Ts_absolute/(1+0.32*H2O*R*Ts_absolute/(amb_press*18)) - 273.15'Kaimal and Gaynor (1991) Eq. (3). + divisor = (amb_press/(R*(Tc+273.15)))-(H2O/18) '[divisor] = mol/m^3 + CO2_ppm = CO2/(MW_CO2/1000)/divisor + CO2_hf_ppm = CO2_hf/(MW_CO2/1000)/divisor + Xv = H2O/(MW_H2O/1000)/divisor + Else + Tc = NAN + CO2_ppm = NAN + CO2_hf_ppm = NAN + Xv = NAN + EndIf + + 'sonic cov for stats 1 + cov_array_sonic(1,1) = Ts + Move (cov_array_sonic(1,2),3,Ux,3) + + 'irga cov for stats 1 + cov_array_cs(1,1) = CO2 + cov_array_cs(2,1) = H2O + cov_array_cs(3,1) = Tc + cov_array_cs(4,1) = CO2_hf + Move (cov_array_cs(1,2),3,Ux,3) + Move (cov_array_cs(2,2),3,Ux,3) + Move (cov_array_cs(3,2),3,Ux,3) + Move(cov_array_cs(4,2),3,Ux,3) + + '+++++ 30 min statistics +++++ + CallTable (work_30min) + If ( work_30min.Output(1,1) ) Then + GetRecord(work_stats_out(1),work_30min,1) + + sonic_uptime = sonic_samples/samples_possible + irga_uptime = irga_samples/samples_possible + + 'add azimuth to calculated wind dir + rslt_wnd_dir = (360 + rslt_wnd_dir + sonic_azimuth) MOD 360 + tau = SQR ((Ux_Uz_cov*Ux_Uz_cov)+(Uy_Uz_cov*Uy_Uz_cov)) + u_star = SQR (tau) + Ts_Std = SQR (Ts_Std) + Ux_Std = SQR (Ux_Std) + Uy_Std = SQR (Uy_Std) + Uz_Std = SQR (Uz_Std) + + L=-u_star^3*(Tc_Avg+273.15)/(0.4*9.8*Ts_Uz_cov) 'obukohov length + rho_d_mean = (amb_press_Avg/((Tc_Avg+273.15)*RD))-(H2O_g_m3_Avg*MU_WPL) + rho_a_mean = (rho_d_mean+H2O_g_m3_Avg)/1000 + Fc_irga = CO2_Uz_cov 'online fluxes + LE_irga = LV*H2O_Uz_cov + CO2_mg_m3_Std = SQR (CO2_mg_m3_Std) 'stdevs + H2O_g_m3_Std = SQR (H2O_g_m3_Std) + Tc_stdev = SQR (Tc_stdev) + sigma_wpl = H2O_g_m3_Avg/rho_d_mean 'WPL term + + 'EC150 Webb et al. (1980) term for carbon dioxide Eq. (24). + CO2_wpl_LE = MU_WPL*CO2_mg_m3_Avg/rho_d_mean*H2O_Uz_cov + CO2_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov + Fc_wpl = Fc_irga+CO2_wpl_LE+CO2_wpl_H + + 'EC150 Webb et al. (1980) term for water vapor Eq. (25). + H2O_wpl_LE = MU_WPL*sigma_wpl*LE_irga + H2O_wpl_H = (1+(MU_WPL*sigma_wpl))*H2O_g_m3_Avg/(Tc_Avg+273.15)*LV*Tc_Uz_cov + LE_wpl = LE_irga+H2O_wpl_LE+H2O_wpl_H + + 'repeat using high-frequency tmpr CO2 value + Fc_hf_irga = CO2_hf_Uz_cov + CO2_hf_mg_m3_Std = SQR(CO2_hf_mg_m3_Std) + CO2_hf_wpl_LE = MU_WPL*CO2_hf_mg_m3_Avg/rho_d_mean*H2O_Uz_cov + CO2_hf_wpl_H = (1+(MU_WPL*sigma_wpl))*CO2_hf_mg_m3_Avg/(Tc_Avg+273.15)*Tc_Uz_cov + Fc_hf_wpl = Fc_hf_irga+CO2_hf_wpl_LE+CO2_hf_wpl_H + + RH_hmp_Avg = 100*e_hmp_Avg/e_sat_hmp_Avg + + Hs = rho_a_mean*CP*Ts_Uz_cov + tau = rho_a_mean*tau + Hc = rho_a_mean*CP*Tc_Uz_cov + EndIf + CallTable(stats30) '**************************************************** + + inbetween_1hz_scan = TRUE + If ( just_had_1hz_scan ) Then + just_had_1hz_scan = FALSE + inbetween_1hz_scan = FALSE + EndIf + + inbetween_5s_scan = TRUE + If ( just_had_soil_scan ) Then + just_had_soil_scan = FALSE + inbetween_5s_scan = FALSE + EndIf + Else + scan_count = scan_count+1 + EndIf + NextScan + + + '====================== SLOW SCAN INTERVAL ================================= + SlowSequence + Scan (SLOW_INTV,Sec,SLOW_BUFFER_SIZE,0) + PanelTemp (panel_tmpr,INTEG) + Battery (batt_volt) + + '== HMP-155A temp/RH + VoltDiff (T_hmp,1,mV1000,HMP_T_DIFF,TRUE,0,INTEG,HMP_T_MULT,HMP_T_OFFSET) + VoltDiff (RH_hmp,1,mV1000,HMP_RH_DIFF,TRUE,0,INTEG,HMP_RH_MULT,HMP_RH_OFFSET) + VaporPressure (e_hmp,T_hmp,RH_hmp) + SatVP (e_sat_hmp,T_hmp) + + '== NR-Lite2 net radiometer, expected range 0-15mV + VoltDiff (Rn_meas,1,mV20,NRLITE_DIFF,TRUE,0,INTEG,nrlite_mult,0) + If ( sonic_irga_raw(5)=0 AND hor_wind>5 ) Then 'sonic_irga_raw(5) = CSAT3 diag word + Rn = Rn_meas*(1+(0.021286*(hor_wind-5))) + Else + Rn = Rn_meas + EndIf + + '== LI190SB + VoltDiff (PAR_mV,1,mV20,LI190_DIFF,True,0,INTEG,1,0) 'MULT/OFF applied below + If (PAR_mV > 0) Then + PAR_flxdens = PAR_mV*li190_dens_mult + PAR_totflx = PAR_mV*li190_tot_mult + Else + PAR_flxdens = NAN + PAR_totflx = NAN + EndIf + + If (debug_on) Then CallTable debug + + If (save_changes) Then + save_changes = False 'reset b4 we forget + save_current_choices() + CallTable(site_info) + EndIf + + just_had_1hz_scan = TRUE + NextScan + + + '====================== SOIL SCAN INTERVAL ================================= + SlowSequence + Scan (SOIL_INTV,Sec,SOIL_BUFFER_SIZE,0) + + '== Garmin GPS + GPS (latitude_a,GPS_COM_ADDR,UTC_OFFSET*3600,0,nmea_sentence(1)) + CallTable(site_daily) + + #If (SHFP_ENABLED) Then + VoltDiff(soil_hfp1_heat_flux,1,mv200,HFP_1_SGNL_DIFF,TRUE,0,INTEG, _ + soil_hfp1_sensitivity,0) + VoltDiff(soil_hfp2_heat_flux,1,mv200,HFP_2_SGNL_DIFF,TRUE,0,INTEG, _ + soil_hfp2_sensitivity,0) + TCDiff(tcav_T,1,mV50,TCAV_DIFF,TypeE,panel_tmpr,1,0,INTEG,0,1) + #EndIf + + CallTable(soil) + just_had_soil_scan = TRUE + NextScan +EndProg From e0b512f88222608122401510e0c638fb41b3cdd4 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 16:17:43 -0700 Subject: [PATCH 03/20] Adopt changesets from EasyFlux v1.1 --- CHANGELOG.md | 5 +++++ src/default.cr3 | 13 ++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93a6ae0..acb60d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,11 @@ Next release instead of slow-response thermistor temperature; for more information, refer to http://dx.doi.org/10.1016/j.agrformet.2016.07.018 +### Changes w.r.t EasyFlux v1.0 + +* Incorporate updates from EasyFlux v1.1 release + * FIX: correct transposed values in constant used for dewpoint calculations + * Non-substantive formatting changes diff --git a/src/default.cr3 b/src/default.cr3 index 14d6464..f7be7eb 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -589,7 +589,6 @@ Dim slowsequence_disable_flg As Boolean 'Flag used to decimate statistics i Dim sys_conf_var_file As Long 'Filehandle for the file that contains the system configuration variables in the CPU. Dim i, i_slow As Long 'Index variables for the outmost loop. "i" in main scan and "i_slow" in slow scan sequence -Dim ii, ii_slow As Long 'Index variables inside outmost loop. "ii" in main scan and "ii_slow" in slow scan sequence Dim array_index As Long 'Used for array index that must be calculated using loop index (to simplify expression and reduce computation for array index) Dim n = 1 'Used for counting the number of samples @@ -2027,10 +2026,10 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) #EndIf #If (SENSOR_SI111) Then - '*** Beginning of LI190SB output data *** + '*** Beginning of SI111 output data *** Average (1, T_SI111_targeted, IEEE4, slowsequence_disable_flg) Average (1, T_SI111_body, IEEE4, slowsequence_disable_flg) - '*** End of LI190SB output data *** + '*** End of SI111 output data *** #EndIf #If (SENSOR_TCAV) Then @@ -2506,8 +2505,8 @@ Sub Displacement_roughness_heights (S_type, d_user, z0_user, h_canopy, h_measur displacement = 0 'Default w/o canopy roughness = 0.01 'Default w/o canopy Case Is >0 - displacement = 10^(0.979*LOG10(h_canopy)-0.154) 'Crop or grass canopy, Eq. 4.5, page 138 in Rosenberg et al. (1983) - roughness = 10^(0.977*LOG10(h_canopy)-0.883) 'Crop or grass canopy, Eq. 4.4, page 137 in Rosenberg et al. (1983) + displacement = 10.0^(0.979*LOG10(h_canopy)-0.154) 'Crop or grass canopy, Eq. 4.5, page 138 in Rosenberg et al. (1983) + roughness = 10.0^(0.977*LOG10(h_canopy)-0.883) 'Crop or grass canopy, Eq. 4.4, page 137 in Rosenberg et al. (1983) EndSelect EndIf @@ -4443,7 +4442,7 @@ BeginProg Select Case Td_gu 'Eq. 11 from Appendix A of flux program manual Case Is >= 0 - Td = 238.88*x_tmp/(17.386 - x_tmp) + Td = 238.88*x_tmp/(17.368 - x_tmp) Case Is < 0 Td = 247.15*x_tmp/(17.966 - x_tmp) EndSelect @@ -4920,7 +4919,7 @@ BeginProg Select Case Td_gu_probe 'Eq. 11 from Appendix A of flux program manual Case Is >= 0 - Td_probe = 238.88*x_tmp_probe/(17.386 - x_tmp_probe) + Td_probe = 238.88*x_tmp_probe/(17.368 - x_tmp_probe) Case Is < 0 Td_probe = 247.15*x_tmp_probe/(17.966 - x_tmp_probe) EndSelect From 2e88459f6c0556b24d13c174735a99a52648a842 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 16:20:03 -0700 Subject: [PATCH 04/20] Support additional tipping bucket rain models --- CHANGELOG.md | 4 ++++ src/default.cr3 | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acb60d2..4434b62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,10 @@ Next release * Incorporate updates from EasyFlux v1.1 release * FIX: correct transposed values in constant used for dewpoint calculations * Non-substantive formatting changes +* Increased instrumentation support + * Additional rain gage models (TE525, TE525WS, TE525 or TE525MM used with + 8" funnel adapter) + diff --git a/src/default.cr3 b/src/default.cr3 index f7be7eb..032e44d 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -97,7 +97,13 @@ Const SENSOR_LI190SB = FALSE 'Unique: LI190SB: Quantum, if Const SENSOR_SI111 = FALSE 'Unique: SI111: Infrared radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE Const SENSOR_NR01 = FALSE 'Unique: NR01: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_CNR4 must be set to FALSE Const SENSOR_CNR4 = FALSE 'Unique: CNR4: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_NR01 must be set to FALSE -Const SENSOR_TE525mm = FALSE 'Unique: TE525mm rain gauge + +'Select at most 1 rain sensor: +Const SENSOR_TE525 = FALSE 'Unique: TE525 (6") rain gage +Const SENSOR_TE525WS = TRUE 'Unique: TE525WS (8") rain gage +Const SENSOR_TE525MM = FALSE 'Unique: TE525MM (metric) rain gage +Const SENSOR_TE525_wf = FALSE 'Unique: TE525 or TE525MM rain gage with 8in funnel + Const SENSOR_TCAV = FALSE 'Unique: TCAV: type E thermocouple averaging soil temperature probes Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X must be set to FALSE Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 must be set to FALSE @@ -106,6 +112,7 @@ Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibr 'Composite boolean variables for variables above Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) +Const SENSOR_TE525x = ((SENSOR_TE525) OR (SENSOR_TE525WS) OR (SENSOR_TE525MM) OR (SENSOR_TE525_wf)) Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X)) @@ -434,12 +441,21 @@ Const TMPR_RH_T_OFFSET = -80 'Unique: offset for temperature; HC2S3 = -40 'G Power reference (gray/black) '*** End of HC2S3 or HMP wiring *** #EndIf -#If (SENSOR_TE525mm) Then +#If (SENSOR_TE525x) Then Const TE525_PULSE_INPUT = 1 'Pulse input channel rain gauge. -Const TE525_MULT = 0.1 'Unique: multiplier for TE525MM -'*** Beginning of TE525mm wiring *** +#If (SENSOR_TE525MM) Then +Const TE525_MULT = 0.1 'Unique: multiplier for TE525MM +#EndIf +#If (SENSOR_TE525 OR SENSOR_TE525WS) Then +Const TE525_MULT = 0.254 'Unique: multiplier for TE525 & TE525WS +#EndIf +#If (SENSOR_TE525_wf) Then +Const TE525_MULT = 0.1459 'Unique: multipler for TE525 or TE525MM w/ 8in funnel +#EndIf + +'*** Beginning of TE525x wiring *** 'P1 Precipitation (black) 'gnd Signal reference (white) 'gnd Shield (clear/clear) @@ -1574,7 +1590,7 @@ DataTable (stats_tmpr_rh,TRUE,1) EndTable '*** End of temperature and humidity probe constants, variables, and working data table *** #EndIf -#If (SENSOR_TE525mm) Then +#If (SENSOR_TE525x) Then '*** Beginning of TE525mm constants and variables *** Public Precipitation @@ -1995,7 +2011,7 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) Sample (1, rho_d_probe_Avg, IEEE4) 'Measured from temperaure and humidity probe: dry air density in kg/m^3 '*** End of temperature and humidity probe output data *** #EndIf - #If (SENSOR_TE525mm) Then + #If (SENSOR_TE525x) Then '*** Beginning of rain gauge output data *** Totalize (1, Precipitation, FP2, 0) @@ -4050,7 +4066,7 @@ BeginProg 'Datalogger panel temperature PanelTemp (panel_tmpr, 250) - #If (SENSOR_TE525mm) Then 'This is placed at beginning of scan because PulseCount() is not allowed in any conditional statements. + #If (SENSOR_TE525x) Then 'This is placed at beginning of scan because PulseCount() is not allowed in any conditional statements. '*** Beginning of Precipitation measurements *** PulseCount (Precipitation, 1, TE525_PULSE_INPUT, 2, 0, TE525_MULT, 0) '*** End of Precipitation measurements *** From df752e2fed5220be5d3b6a14ecad06fd5a02fa14 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 16:38:20 -0700 Subject: [PATCH 05/20] Support additional T/RH probes --- CHANGELOG.md | 1 + src/default.cr3 | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4434b62..ff728fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ Next release * Increased instrumentation support * Additional rain gage models (TE525, TE525WS, TE525 or TE525MM used with 8" funnel adapter) + * Additional temperature/humidity probes (HC2S3, HMP45C) diff --git a/src/default.cr3 b/src/default.cr3 index 032e44d..2794aa1 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -89,7 +89,12 @@ AngleDegrees 'Angles are in degrees throughout the program Const SENSOR_IRGASON = TRUE 'Unique: IRGASON, if TRUE, SENSOR_CSAT3AEC150 must be set to FALSE Const SENSOR_CSAT3AEC150 = FALSE 'Unique: CSAT3A + EC150, if TRUE, SENSOR_IRGASON must be set to FALSE. Const SENSOR_FW = FALSE 'Unique: FW05, FW1, FW3, or other fine wire thermocouple -Const SENSOR_TMPR_RH = FALSE 'Unique: HC2S3 or HMP155A: temperature and relative humidity probe + +'Select at most 1 temperature/RH probe: +Const SENSOR_HMP155A = TRUE 'Unique: Vaisala HMP155A +Const SENSOR_HC2S3 = FALSE 'Unique: Campbellsci HC2S3 +Const SENSOR_HMP45C = FALSE 'Unique: Vaisala HMP45C + Const SENSOR_NR_LITE = FALSE 'Unique: NR Lite2: net radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE Const SENSOR_CS300 = FALSE 'Unique: CS300: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE Const SENSOR_LI200X = FALSE 'Unique: LI200X: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE @@ -111,6 +116,7 @@ Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE 'Composite boolean variables for variables above +Const SENSOR_TMPR_RH = ((SENSOR_HMP155A) OR (SENSOR_HC2S3) OR (SENSOR_HMP45C)) Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) Const SENSOR_TE525x = ((SENSOR_TE525) OR (SENSOR_TE525WS) OR (SENSOR_TE525MM) OR (SENSOR_TE525_wf)) Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) @@ -426,8 +432,17 @@ Const CS65X_SDI12_Address_2 = 2 'Unique: SDI address for CS655 #2 #If (SENSOR_TMPR_RH) Then Const TMPR_RH_ANALOG_INPUT = 27 'Single-end analog input channel for temperature and humidity probe. -Const TMPR_RH_T_MULT = 0.14 'Unique: multiplier for temperature; HC2S3 = 0.1, HMP155A = 0.14, or HMP45C = 0.1. -Const TMPR_RH_T_OFFSET = -80 'Unique: offset for temperature; HC2S3 = -40, HMP155A = -80, or HMP45C = -40. +Const TMPR_RH_MULT = (100-0)/1000 'Unique: RH multiplier, all models = 0.1 +Const TMPR_RH_OFFSET = 0 'Unique: RH offset, all models = 0 + +#If (SENSOR_HMP155A) Then +Const TMPR_RH_T_MULT = (60 - -80)/1000 'Unique: temperature multiplier HMP155A = 0.14 +Const TMPR_RH_T_OFFSET = -80 'Unique: temperature offset HC2S3 = -40, HMP155A = -80, or HMP45C = -40. +#EndIf +#If (SENSOR_HC2S3 OR SENSOR_HMP45C) Then +Const TMPR_RH_T_MULT = (60 - -40)/1000 'Unique: temperature multiplier HC2S3 = 0.1 +Const TMPR_RH_T_OFFSET = -40 'Unique: temperature offset HC2S3 = -40 +#EndIf '*** Beginning of HC2S3 or HMP wiring *** '14H Temperature signal (brown/yellow) @@ -4909,7 +4924,7 @@ BeginProg '*** Beginning of temperature and humidity probe measurements *** VoltSe (T_probe, 2, mV1000, TMPR_RH_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) T_probe = T_probe*TMPR_RH_T_MULT + TMPR_RH_T_OFFSET - RH_probe = RH_probe*0.1 + RH_probe = RH_probe*TMPR_RH_MULT + TMPR_RH_OFFSET VaporPressure (e_probe, T_probe, RH_probe) 'Saturation water pressure at current temperature From f1adef4d937fcf0dafd1789f761d80283e390395 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 17:33:51 -0700 Subject: [PATCH 06/20] Add support for cup/vane wind set --- CHANGELOG.md | 1 + src/default.cr3 | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff728fe..bb52f60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ Next release * Additional rain gage models (TE525, TE525WS, TE525 or TE525MM used with 8" funnel adapter) * Additional temperature/humidity probes (HC2S3, HMP45C) + * Cup & vane wind set (MetOne 034B) diff --git a/src/default.cr3 b/src/default.cr3 index 2794aa1..32aafed 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -115,6 +115,8 @@ Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE +Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set + 'Composite boolean variables for variables above Const SENSOR_TMPR_RH = ((SENSOR_HMP155A) OR (SENSOR_HC2S3) OR (SENSOR_HMP45C)) Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) @@ -476,6 +478,29 @@ Const TE525_MULT = 0.1459 'Unique: multipler for TE525 or TE525MM w/ 8in fun 'gnd Shield (clear/clear) '*** End of TE525mm wiring *** #EndIf +#If (SENSOR_034B) Then + +Const o34B_WD_ANALOG_INPUT = 1 'Single-ended analog input channel for 034B wind direction +Const o34B_WD_EXCITATION = 1 'Voltage excitation channel for 034B wind direction +Const o34B_WS_PULSE_INPUT = 2 'Pulse input channel for 034B wind speed + +Const o34B_WD_MULT = 720 'Unique: multipler for wind direction +Const o34B_WD_OFFSET = 0 'Unique: offset for wind direction +Const o34B_WS_MULT = 0.7989 'Unique: multiplier for wind speed +Const o34B_WS_OFFSET = 0.28 'Unique: offset for wind speed + +'lower case'd in anticipation of future integration into settings array +Const cupvane_azimuth = 0 'Unique: orientation of windset w.r.t. true north + +'*** Beginning of 034B wiring *** +'1L Wind direction signal (green) +'VX1 Wind direction voltage excitation (blue) +'gnd Wind diretion reference (white) +'P1 Wind speed pulsed input (red) +'gnd Wind speed reference (black) +'gnd Shield (clear) +'*** End of 034B wiring *** +#EndIf 'POWER IN '12V datalogger (red) @@ -1820,6 +1845,32 @@ Units T_SI111_body = C Dim m_SI111, b_SI111 'Multipler and offset in equation to calculate temperature of targeted surface using measured voltage and SI111 body temperature '*** End of infrared radiometer constants and variables *** #EndIf +#If (SENSOR_034B) Then + +'*** Beginning of cup and vane wind set constants, variables and working data table *** +Public cupvane_WS +Public cupvane_WD +Units cupvane_WS = m/s +Units cupvane_WD = degrees + +Dim stats_out_cupvane(4) +Alias stats_out_cupvane(1) = cupvane_WS_Avg +Alias stats_out_cupvane(2) = cupvane_WS_rslt_Avg +Alias stats_out_cupvane(3) = cupvane_WD_rslt_Avg +Alias stats_out_cupvane(4) = cupvane_WD_csi_Std +Units cupvane_WS_Avg = m/s +Units cupvane_WS_rslt_Avg = m/s +Units cupvane_WD_rslt_Avg = degrees +Units cupvane_WD_csi_Std = degrees + +DataTable(stats_cupvane,TRUE,1) + TableHide + DataInterval (0,OUTPUT_INTERVAL,Min,1) + + WindVector(1,cupvane_WS,cupvane_WD,FP2,(cupvane_WS=NAN OR cupvane_WD=NAN),0,0,2) +EndTable +'*** End of cup and vane wind set constants, variables and working data table *** +#EndIf '*** Beginning display menu *** DisplayMenu ("System Control", TRUE) @@ -1848,6 +1899,10 @@ DisplayMenu ("System Control", TRUE) #EndIf MenuItem ("Sonic Azmth", sonic_azimuth) +'needs integration into settings array before reveal +' #If (SENSOR_034B) Then +' MenuItem ("Windset Azmth", cupvane_azimuth) +' #EndIf MenuItem ("Latitude", latitude) MenuItem ("Hemisph_Eq", hemisphere_NS) MenuPick (Hemisphere_North, Hemisphere_South) @@ -2062,6 +2117,12 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) Average (1, T_SI111_body, IEEE4, slowsequence_disable_flg) '*** End of SI111 output data *** #EndIf + #If (SENSOR_034B) Then + + '*** Beginning of 034B output data *** + Sample (4, stats_out_cupvane(1), FP2) + '*** End of 034B output data *** + #EndIf #If (SENSOR_TCAV) Then '*** Beginning of TCAV output data *** @@ -4087,6 +4148,17 @@ BeginProg '*** End of Precipitation measurements *** #EndIf + #If (SENSOR_034B) Then 'likewise, placed right here because PulseCount() + '*** Beginning of cup and vane measurements *** + BrHalf(cupvane_WD,1,mv5000,o34B_WD_ANALOG_INPUT,o34B_WD_EXCITATION,1,5000,True,0,250,o34B_WD_MULT,o34B_WD_OFFSET) + If ((cupvane_WD >= 360) OR (cupvane_WD < 0)) Then (cupvane_WD = 0) + PulseCount (cupvane_WS,1,o34B_WS_PULSE_INPUT,2,1,o34B_WS_MULT,o34B_WS_OFFSET) + If (cupvane_WS <= o34B_WS_OFFSET) Then (cupvane_WS = 0) + + CallTable stats_cupvane + '*** End of cup and vane measurements *** + #EndIf + #If (SENSOR_FW) Then '*** Beginning of FW measurements *** diag_FW_raw = 0 @@ -4838,7 +4910,16 @@ BeginProg EndIf #EndIf + #If (SENSOR_034B) Then + + '*** Beginning of cup and vane processing *** + If (stats_cupvane.Output(1,1)) Then + GetRecord (stats_out_cupvane(1), stats_cupvane, 1) + cupvane_WD_rslt_Avg = cupvane_WD_rslt_Avg + cupvane_azimuth + EndIf + '*** End of cup and vane processing *** + #EndIf #If (SENSOR_HFP) Then '*** Beginning of table for soil heat flux plate *** From 117e84c6a41e4d0dc68fe5dcadcfd6aae4bd99b5 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Wed, 12 Apr 2017 18:19:57 -0700 Subject: [PATCH 07/20] Add support for GPS receiver Integration limited to time synchronization --- CHANGELOG.md | 1 + src/default.cr3 | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb52f60..ba9449b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ Next release 8" funnel adapter) * Additional temperature/humidity probes (HC2S3, HMP45C) * Cup & vane wind set (MetOne 034B) + * GPS receiver (GPS16X-HVS) diff --git a/src/default.cr3 b/src/default.cr3 index 32aafed..181149f 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -116,6 +116,8 @@ Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set +Const SENSOR_GPS16X = TRUE 'Unique: Garmin GPS16x-HVS GPS receiver + 'Composite boolean variables for variables above Const SENSOR_TMPR_RH = ((SENSOR_HMP155A) OR (SENSOR_HC2S3) OR (SENSOR_HMP45C)) @@ -501,6 +503,24 @@ Const cupvane_azimuth = 0 'Unique: orientation of windset w.r.t. true north 'gnd Shield (clear) '*** End of 034B wiring *** #EndIf +#If (SENSOR_GPS16X) Then + +Const GPS16X_COM = Com4 'Serial port for GPS16X + +Const UTC_OFFSET = -8 'local time offset from UTC, in hours +Const MAX_CLOCK_DRIFT = 0 'max clock drift permitted before setting clock, in msec + +'*** Beginning of GPS16X wiring *** +'C7 pulse-per-second (PPS) output (gray) +'C8 serial output/message transmit (white) +'gnd serial input/receive data (blue) +'gnd shield (clear) +' +'12V power input (red) +'G power ground (black) +'G power switch (yellow) +'*** End of GPS16X wiring *** +#EndIf 'POWER IN '12V datalogger (red) @@ -1871,6 +1891,44 @@ DataTable(stats_cupvane,TRUE,1) EndTable '*** End of cup and vane wind set constants, variables and working data table *** #EndIf +#If (SENSOR_GPS16X) Then + +'*** Beginning of GPS receiver constants and variables *** +Dim nmea_sentence(2) As String * 90 + +Dim gps_data(15) +Alias gps_data(1) = latitude_deg 'Degrees latitude (+ = East; - = West) +Alias gps_data(2) = latitude_min 'Decimal minutes latitude +Alias gps_data(3) = longitude_deg 'Degress longitude (+ = East; - = West) +Alias gps_data(4) = longitude_min 'Decimal minutes longitude +Alias gps_data(5) = speed 'Speed +Alias gps_data(6) = course 'Course over ground +Alias gps_data(7) = magnetic_variation 'Magnetic variation from true north (+ = East; - = West) +Alias gps_data(8) = fix_quality 'GPS fix quality: 0 = invalid, 1 = GPS, 2 = 'differential GPS, 6 = estimated +Alias gps_data(9) = nmbr_satellites 'Number of satellites used for fix +Alias gps_data(10) = altitude 'Antenna altitude +Alias gps_data(11) = pps 'Elapsed ms since last pulse per second (PPS) from GPS +Alias gps_data(12) = dt_since_gprmc 'Time since last GPRMC string, normally less than '1 second +Alias gps_data(13) = gps_ready 'Counts from 0 to 10, 10 = ready +Alias gps_data(14) = max_clock_change 'Maximum value the clock was changed +Alias gps_data(15) = nmbr_clock_change 'Number of times the clock was changed +Units latitude_deg = degreesN +Units latitude_min = minutesN +Units longitude_deg = degreesE +Units longitude_min = minutesE +Units speed = m/s +Units course = degreesEofN +Units magnetic_variation = degreesEofN +Units fix_quality = unitless +Units nmbr_satellites = unitless +Units altitude = m +Units pps = ms +Units dt_since_gprmc = s +Units gps_ready = unitless +Units max_clock_change = ms +Units nmbr_clock_change = occurrences +'*** End of GPS receiver constants and variables *** +#EndIf '*** Beginning display menu *** DisplayMenu ("System Control", TRUE) @@ -5299,6 +5357,13 @@ BeginProg '*** End of SI111 measurements *** #EndIf + #If (SENSOR_GPS16X) Then + + '*** Beginning of GPS16X-HVS measurements *** + GPS (gps_data(1),GPS16X_COM,UTC_OFFSET*3600,MAX_CLOCK_DRIFT,nmea_sentence(1)) + '*** End of GPS16X-HVS measurements *** + #EndIf + '*** Beginning of updating files of station variables and planar fit angles *** 'Determing whether or not the planar fit is used. It is used as long as one planar fit angle is not zero. stn_var_check_count += 1 From a62e0bdd18bdea9907ca1cbe9205a893268dd354 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Fri, 14 Apr 2017 13:11:11 -0700 Subject: [PATCH 08/20] Add support for TDR-315 soil T/WC probe as drop-in replacement for CS616 or CS65x probes --- src/default.cr3 | 107 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 13 deletions(-) diff --git a/src/default.cr3 b/src/default.cr3 index 181149f..be65267 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -110,8 +110,9 @@ Const SENSOR_TE525MM = FALSE 'Unique: TE525MM (metric) rain gage Const SENSOR_TE525_wf = FALSE 'Unique: TE525 or TE525MM rain gage with 8in funnel Const SENSOR_TCAV = FALSE 'Unique: TCAV: type E thermocouple averaging soil temperature probes -Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X must be set to FALSE -Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 must be set to FALSE +Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X and sensor TDR315 must be set to FALSE +Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 and SENSOR_TDR315 must be set to FALSE +Const SENSOR_TDR315 = FALSE 'Unique: Acclima TDR-315L soil water content/temperature probes, if true, SENSOR_CS65X and SENSOR_CS616 must be false Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE @@ -124,7 +125,7 @@ Const SENSOR_TMPR_RH = ((SENSOR_HMP155A) OR (SENSOR_HC2S3) OR (SENSOR_HMP45C Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) Const SENSOR_TE525x = ((SENSOR_TE525) OR (SENSOR_TE525WS) OR (SENSOR_TE525MM) OR (SENSOR_TE525_wf)) Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) -Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X)) +Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X) OR (SENSOR_TDR315)) '***** Wiring Instruction ****** '*** Beginning of EC100 (IRGASON or EC150 w/ or w/o CSAT3A sonic head) wiring *** @@ -391,7 +392,7 @@ Const NMBR_TCAV = 2 'Unique: number of TCAV (Maximum is 2) #EndIf #If (SENSOR_CS6XX) Then -Const NMBR_CS6xx = 2 'Unique: number of CS616, CS650, or CS655 sensors (Maximum is 2) +Const NMBR_CS6xx = 2 'Unique: number of CS616, CS650, CS655, or TDR-315 sensors (Maximum is 2) #If (SENSOR_CS616) Then @@ -432,6 +433,22 @@ Const CS65X_SDI12_Address_2 = 2 'Unique: SDI address for CS655 #2 ' Shield #2 (clear) '*** End of CS65X wiring *** #EndIf +#If (SENSOR_TDR315) Then + +Const TDR315_SDI12_PORT = 5 'Control port for SDI-12 data +Const TDR315_SDI12_Address_1 = 1 'Unique: SDI address for TDR-315 #1 +#If (NMBR_CS6xx = 2) Then +Const TDR315_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 +#EndIf +'*** Beginning of TDR-315 wiring *** +'C5 SDI-12 data #1 (blue) +' SDI-12 data #2 (blue +'12V SDI-12 power #1 (red) +' SDI-12 power #2 (red) +'G SDI-12 ground #1 (white) +' SDI-12 ground #2 (white) +'*** End of TDR-315 wiring *** +#EndIf #EndIf #If (SENSOR_TMPR_RH) Then @@ -1804,7 +1821,24 @@ Units cs65x_ec = dS/m Units cs65x_tmpr = C '*** End of CS65X constants and variables *** #EndIf -#If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then +#If (SENSOR_TDR315) Then + +'*** Beginning of TDR315 constants and variables *** + +Public tdr315_wc(NMBR_CS6xx) 'volumetric water content, % +Public tdr315_tmpr(NMBR_CS6xx) 'soil temperature, degC +Public tdr315_E(NMBR_CS6xx) 'soil permittivity, unitless +Public tdr315_bulkEC(NMBR_CS6xx) 'bulk electrical conductivity, uS/cm +Public tdr315_poreEC(NMBR_CS6xx) 'soil pore water EC, uS/cm +Dim tdr315_raw(5) 'holds response from sensor #X +Units tdr315_wc = frac_v_wtr +Units tdr315_tmpr = C +Units tdr315_E = unitless +Units tdr315_bulkEC = uS/cm +Units tdr315_poreEC = uS/cm +'*** End of TDR315 constants and variables *** +#EndIf +#If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then '*** Beginning of variables for calculation of soil heat flux at soil surface *** Const NMBR_SOIL_T_WTR_DEL_SAMPLES = (60*1000)/SLOWSEQUENCE_SCAN_INTERVAL 'Unique: Number of measurements to compute a one-minute mean of soil temperature and water @@ -1832,7 +1866,7 @@ Dim realtime_array(9) 'Hold real time data Dim Offset_intv_Delta_ht_storage 'time interval offset '*** End of variables for calculation of soil heat flux at soil surface *** #EndIf -#If ((SENSOR_Rn) AND (SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then +#If ((SENSOR_Rn) AND (SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then '*** Beginning of energy balance constants and variables *** Public energy_closure '(LE + H)/(Rn-G_surface) @@ -1940,7 +1974,7 @@ DisplayMenu ("System Control", TRUE) MenuItem ("Meas height", height_measurement) MenuItem ("Canopy height", height_canopy) - #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then MenuItem ("Bulk density", soil_bulk_density) MenuItem ("C_dry_soil", Cds) MenuItem ("HFP depth", thick_abv_SHFP) @@ -2211,6 +2245,16 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) Average (NMBR_CS6xx, cs65x_tmpr(1),IEEE4, slowsequence_disable_flg) 'CS65X probe temperature. '*** End of CS65X output data *** #EndIf + #If (SENSOR_TDR315) Then + + '*** Beginning of TDR315 output data *** + Average (NMBR_CS6xx, tdr315_wc(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, tdr315_tmpr(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, tdr315_E(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, tdr315_bulkEC(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, tdr315_poreEC(1), IEEE4, slowsequence_disable_flg) + '*** End of TDR315 output data *** + #EndIf #If (SENSOR_HFP) Then '*** Beginning of HFP01 output data *** @@ -4186,7 +4230,7 @@ BeginProg Next i ' *** End of loading transfer function values of Dijk (2002) *** - #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then ' Variables used to calculate the number of seconds from the beginning of the program to the end of the first averaging interval (time interval offset) RealTime(realtime_array(1)) Offset_intv_Delta_ht_storage = ((3600*realtime_array(4) + 60*realtime_array(5) + realtime_array(6)) MOD (60*OUTPUT_INTERVAL)) @@ -4989,17 +5033,17 @@ BeginProg GetRecord (shf_plate_avg(1), stats_SHF, 1) - #If (((SENSOR_TCAV) OR (SENSOR_CS65X)) AND (SENSOR_CS6XX)) Then + #If (((SENSOR_TCAV) OR (SENSOR_CS65X)) AND (SENSOR_CS6XX) OR (SENSOR_TDR315)) Then AvgSpa(G_surface, NMBR_SHFP, shf_plate_avg(1)) 'G_surface is used as a temporary variable #If (SENSOR_TCAV) Then AvgSpa(Tsoil_current_Avg, NMBR_TCAV, Tsoil_current (1)) #EndIf - #If ((NOT SENSOR_TCAV) AND (SENSOR_CS65X)) Then - AvgSpa(Tsoil_current_Avg, NMBR_CS6xx, Tsoil_current (1)) + #If ((NOT SENSOR_TCAV) AND ((SENSOR_CS65X) OR (SENSOR_TDR315))) Then + AvgSpa(Tsoil_current_Avg, NMBR_CS6xx, Tsoil_current (1)) 'XXXX #EndIf - AvgSpa(soil_wtr_current_Avg, NMBR_CS6xx, soil_wtr_current (1)) + AvgSpa(soil_wtr_current_Avg, NMBR_CS6xx, soil_wtr_current (1)) 'XXXX Delta_soil_ht_storage = ((Tsoil_current_Avg - Tsoil_prev_Avg)*Cds*soil_bulk_density + _ (Tsoil_current_Avg*soil_wtr_current_Avg - Tsoil_prev_Avg*soil_wtr_prev_Avg)*1000*Cw)*thick_abv_SHFP/(60*OUTPUT_INTERVAL-Offset_intv_Delta_ht_storage) @@ -5236,7 +5280,7 @@ BeginProg '*** Beginning of TCAV measurements *** TCDiff (Tsoil(1), NMBR_TCAV, AutoRange, TCAV_ANALOG_INPUT, TypeE, panel_tmpr, TRUE, 0, ANALOG_INTEGRATION, 1, 0) - #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X))) Then + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then AvgRun (Tsoil_current(1), NMBR_TCAV, Tsoil(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) If (Tsoil_prev_Avg = NaN) Then 'As soon as program starts @@ -5319,6 +5363,43 @@ BeginProg #EndIf '*** End of CS65X measurements *** #EndIf + #If (SENSOR_TDR315) Then + + '*** Beginning of TDR-315 measurements *** + SDI12Recorder (tdr315_raw(1), TDR315_SDI12_PORT, TDR315_SDI12_Address_1, "M!", 1, 0) + tdr315_wc(1) = tdr315_raw(1) + tdr315_tmpr(1) = tdr315_raw(2) + tdr315_E(1) = tdr315_raw(3) + tdr315_bulkEC(1) = tdr315_raw(4) + tdr315_poreEC(1) = tdr315_raw(5) + + #If (NMBR_CS6xx = 2) Then + SDI12Recorder (tdr315_raw(1), TDR315_SDI12_PORT, TDR315_SDI12_Address_2, "M!", 1, 0) + tdr315_wc(2) = tdr315_raw(1) + tdr315_tmpr(2) = tdr315_raw(2) + tdr315_E(2) = tdr315_raw(3) + tdr315_bulkEC(2) = tdr315_raw(4) + tdr315_poreEC(2) = tdr315_raw(5) + #EndIf + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_TDR315))) Then + + AvgRun (soil_wtr_current(1), NMBR_CS6xx, tdr315_wc(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (soil_wtr_prev_Avg = NaN) Then + AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, tdr315_wc(1)) + EndIf + + #If ((SENSOR_TDR315) AND ( NOT SENSOR_TCAV)) Then + AvgRun (Tsoil_current(1), NMBR_CS6xx, tdr315_tmpr(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (Tsoil_prev_Avg = NaN) Then 'As soon as program starts + AvgSpa (Tsoil_prev_Avg, NMBR_CS6xx, tdr315_tmpr(1)) + EndIf + #EndIf + #EndIf + '*** End of TDR-315 measurements *** + #EndIf #If (SENSOR_LI200X) OR (SENSOR_CS300) Then From b3f3fc72ab4faac02ad3693330648c677cde1f23 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Fri, 14 Apr 2017 15:14:11 -0700 Subject: [PATCH 09/20] Update sensor wiring --- doc/wiring.xlsx | Bin 12206 -> 12225 bytes src/default.cr3 | 66 ++++++++++++++++++++++++------------------------ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/doc/wiring.xlsx b/doc/wiring.xlsx index bf9f38934ff4e9182cb0023b7eb36cee9cfeddf7..fbf72932e03293ed70a178de2318710aeab58a01 100644 GIT binary patch delta 3872 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 diff --git a/src/default.cr3 b/src/default.cr3 index be65267..e9ea604 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -86,22 +86,22 @@ PipeLineMode AngleDegrees 'Angles are in degrees throughout the program '*** SENSORS **** -Const SENSOR_IRGASON = TRUE 'Unique: IRGASON, if TRUE, SENSOR_CSAT3AEC150 must be set to FALSE -Const SENSOR_CSAT3AEC150 = FALSE 'Unique: CSAT3A + EC150, if TRUE, SENSOR_IRGASON must be set to FALSE. -Const SENSOR_FW = FALSE 'Unique: FW05, FW1, FW3, or other fine wire thermocouple +Const SENSOR_IRGASON = FALSE 'Unique: IRGASON, if TRUE, SENSOR_CSAT3AEC150 must be set to FALSE +Const SENSOR_CSAT3AEC150 = TRUE 'Unique: CSAT3A + EC150, if TRUE, SENSOR_IRGASON must be set to FALSE. +Const SENSOR_FW = FALSE 'Unique: FW05, FW1, FW3, or other fine wire thermocouple 'Select at most 1 temperature/RH probe: -Const SENSOR_HMP155A = TRUE 'Unique: Vaisala HMP155A -Const SENSOR_HC2S3 = FALSE 'Unique: Campbellsci HC2S3 -Const SENSOR_HMP45C = FALSE 'Unique: Vaisala HMP45C - -Const SENSOR_NR_LITE = FALSE 'Unique: NR Lite2: net radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE -Const SENSOR_CS300 = FALSE 'Unique: CS300: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE -Const SENSOR_LI200X = FALSE 'Unique: LI200X: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE -Const SENSOR_LI190SB = FALSE 'Unique: LI190SB: Quantum, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE -Const SENSOR_SI111 = FALSE 'Unique: SI111: Infrared radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE -Const SENSOR_NR01 = FALSE 'Unique: NR01: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_CNR4 must be set to FALSE -Const SENSOR_CNR4 = FALSE 'Unique: CNR4: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_NR01 must be set to FALSE +Const SENSOR_HMP155A = TRUE 'Unique: Vaisala HMP155A +Const SENSOR_HC2S3 = FALSE 'Unique: Campbellsci HC2S3 +Const SENSOR_HMP45C = FALSE 'Unique: Vaisala HMP45C + +Const SENSOR_NR_LITE = TRUE 'Unique: NR Lite2: net radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_CS300 = FALSE 'Unique: CS300: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_LI200X = FALSE 'Unique: LI200X: pyranometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_LI190SB = TRUE 'Unique: LI190SB: Quantum, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_SI111 = FALSE 'Unique: SI111: Infrared radiometer, if true, SENSOR_NR01 and SENSOR_CNR4 must be set to FALSE +Const SENSOR_NR01 = FALSE 'Unique: NR01: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_CNR4 must be set to FALSE +Const SENSOR_CNR4 = FALSE 'Unique: CNR4: 4-way net radiometer, if true, SENSOR_NR_LITE and SENSOR_NR01 must be set to FALSE 'Select at most 1 rain sensor: Const SENSOR_TE525 = FALSE 'Unique: TE525 (6") rain gage @@ -109,15 +109,15 @@ Const SENSOR_TE525WS = TRUE 'Unique: TE525WS (8") rain gage Const SENSOR_TE525MM = FALSE 'Unique: TE525MM (metric) rain gage Const SENSOR_TE525_wf = FALSE 'Unique: TE525 or TE525MM rain gage with 8in funnel -Const SENSOR_TCAV = FALSE 'Unique: TCAV: type E thermocouple averaging soil temperature probes -Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X and sensor TDR315 must be set to FALSE -Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 and SENSOR_TDR315 must be set to FALSE -Const SENSOR_TDR315 = FALSE 'Unique: Acclima TDR-315L soil water content/temperature probes, if true, SENSOR_CS65X and SENSOR_CS616 must be false -Const SENSOR_HFP01 = FALSE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE -Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE +Const SENSOR_TCAV = TRUE 'Unique: TCAV: type E thermocouple averaging soil temperature probes +Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X must be set to FALSE +Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 must be set to FALSE +Const SENSOR_TDR315 = TRUE 'Unique: Acclima TDR-315L soil water content/temperature probes, if true, SENSOR_CS65X and SENSOR_CS616 must be false +Const SENSOR_HFP01 = TRUE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE +Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE -Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set -Const SENSOR_GPS16X = TRUE 'Unique: Garmin GPS16x-HVS GPS receiver +Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set +Const SENSOR_GPS16X = TRUE 'Unique: Garmin GPS16x-HVS GPS receiver 'Composite boolean variables for variables above @@ -143,7 +143,7 @@ Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X) OR (SENSOR_TDR315)) #If (SENSOR_HFP) Then 'Soil heat flux plates Const SHF_ANALOG_INPUT = 1 'Starting differential analog input channel. -Const NMBR_SHFP = 4 'Unique: number of HFP01 or HFP01SC sensors to measure (Maximum is 4) . +Const NMBR_SHFP = 2 'Unique: number of HFP01 or HFP01SC sensors to measure (Maximum is 4) . Data 1000/62 'Unique: multiplier for HFP01xx #1 (1000/sensitivity). #If (NMBR_SHFP >1) Then 'This conditional statement can avoid the confliction with Data statements for the numerical wTs transfer function from Dijk (2002)) if NMBR_SHFP < 2 @@ -240,7 +240,7 @@ Const FW_ANALOG_INPUT = 5 'Differential analog input channel for FW (I #EndIf #If (SENSOR_Rn) Then ' Net radiations sensors -Const NR_ANALOG_INPUT = 6 'Starting differential analog input channel for a net radiation sensor. +Const NR_ANALOG_INPUT = 10 'Starting differential analog input channel for a net radiation sensor. #EndIf #If (SENSOR_NR_LITE) Then @@ -343,7 +343,7 @@ Const PYRAN_OFFSET = 0 'Unique: offset for LI200X [0 W/m^2] or CS300 #EndIf #If (SENSOR_LI190SB) Then -Const QUANTUM_ANALOG_INPUT = 8 'Differential analog input channel for quantum PAR sensor +Const QUANTUM_ANALOG_INPUT = 11 'Differential analog input channel for quantum PAR sensor Const QUANTUM_VOLTAGE_RANGE = mV20 'Unique: measurement range of voltage Const QUANTUM_MULT = 256 'Unique: multiplier (1000 C) for quantum PAR sensor. Const QUANTUM_OFFSET = 0 'Unique: offset for for quantum PAR sensor. @@ -377,8 +377,8 @@ Const b2_SI111 = 13114 'Unique: calbration b2 #EndIf #If (SENSOR_TCAV) Then -Const TCAV_ANALOG_INPUT = 11 'Staring differential analog input channel for TCAV. -Const NMBR_TCAV = 2 'Unique: number of TCAV (Maximum is 2) +Const TCAV_ANALOG_INPUT = 5 'Staring differential analog input channel for TCAV. +Const NMBR_TCAV = 1 'Unique: number of TCAV (Maximum is 2) '*** Beginning of TCAV wiring *** '11H Signal #1 (purple) @@ -392,7 +392,7 @@ Const NMBR_TCAV = 2 'Unique: number of TCAV (Maximum is 2) #EndIf #If (SENSOR_CS6XX) Then -Const NMBR_CS6xx = 2 'Unique: number of CS616, CS650, CS655, or TDR-315 sensors (Maximum is 2) +Const NMBR_CS6xx = 1 'Unique: number of CS616, CS650, CS655, or TDR-315 sensors (Maximum is 2) #If (SENSOR_CS616) Then @@ -436,7 +436,7 @@ Const CS65X_SDI12_Address_2 = 2 'Unique: SDI address for CS655 #2 #If (SENSOR_TDR315) Then Const TDR315_SDI12_PORT = 5 'Control port for SDI-12 data -Const TDR315_SDI12_Address_1 = 1 'Unique: SDI address for TDR-315 #1 +Const TDR315_SDI12_Address_1 = 0 'Unique: SDI address for TDR-315 #1 #If (NMBR_CS6xx = 2) Then Const TDR315_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 #EndIf @@ -452,7 +452,7 @@ Const TDR315_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 #EndIf #If (SENSOR_TMPR_RH) Then -Const TMPR_RH_ANALOG_INPUT = 27 'Single-end analog input channel for temperature and humidity probe. +Const TMPR_RH_ANALOG_INPUT = 8 'Starting differential analog input channel for temperature and humidity probe. Const TMPR_RH_MULT = (100-0)/1000 'Unique: RH multiplier, all models = 0.1 Const TMPR_RH_OFFSET = 0 'Unique: RH offset, all models = 0 @@ -479,7 +479,7 @@ Const TMPR_RH_T_OFFSET = -40 'Unique: temperature offset HC2S3 = -4 #EndIf #If (SENSOR_TE525x) Then -Const TE525_PULSE_INPUT = 1 'Pulse input channel rain gauge. +Const TE525_PULSE_INPUT = 2 'Pulse input channel rain gauge. #If (SENSOR_TE525MM) Then Const TE525_MULT = 0.1 'Unique: multiplier for TE525MM @@ -501,7 +501,7 @@ Const TE525_MULT = 0.1459 'Unique: multipler for TE525 or TE525MM w/ 8in fun Const o34B_WD_ANALOG_INPUT = 1 'Single-ended analog input channel for 034B wind direction Const o34B_WD_EXCITATION = 1 'Voltage excitation channel for 034B wind direction -Const o34B_WS_PULSE_INPUT = 2 'Pulse input channel for 034B wind speed +Const o34B_WS_PULSE_INPUT = 1 'Pulse input channel for 034B wind speed Const o34B_WD_MULT = 720 'Unique: multipler for wind direction Const o34B_WD_OFFSET = 0 'Unique: offset for wind direction @@ -5105,7 +5105,7 @@ BeginProg #If (SENSOR_TMPR_RH) Then '*** Beginning of temperature and humidity probe measurements *** - VoltSe (T_probe, 2, mV1000, TMPR_RH_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) + VoltDiff (T_probe, 2, mV1000, TMPR_RH_ANALOG_INPUT, TRUE, 0, ANALOG_INTEGRATION, 1, 0) T_probe = T_probe*TMPR_RH_T_MULT + TMPR_RH_T_OFFSET RH_probe = RH_probe*TMPR_RH_MULT + TMPR_RH_OFFSET VaporPressure (e_probe, T_probe, RH_probe) From 56b8850f257598de37241d1de5cf0d4821e3d679 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 10:52:53 -0700 Subject: [PATCH 10/20] Add missing changelog entries --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba9449b..1ca11d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Next release * Remove prototype NDVI/PRI sensors (Decagon Devices) * Change PAR sensor back to LI190SB with Campbell Scientific-specific cabling (versus Licor direct-purchase LI190R unit) +* Significant revisions to datalogger wiring scheme ### Other changes @@ -62,6 +63,7 @@ Next release * Additional temperature/humidity probes (HC2S3, HMP45C) * Cup & vane wind set (MetOne 034B) * GPS receiver (GPS16X-HVS) + * Additional soil temperature/water content probe (Acclima TDR-315L) From 715592a04c9440f93bc5a3b681540216d78eaa02 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 10:05:07 -0700 Subject: [PATCH 11/20] Minor wiring revisions --- doc/wiring.xlsx | Bin 12225 -> 12068 bytes src/default.cr3 | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/wiring.xlsx b/doc/wiring.xlsx index fbf72932e03293ed70a178de2318710aeab58a01..a9addca0118888d15d82b65c99b1926aba986f65 100644 GIT binary patch delta 5405 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 Date: Sun, 7 May 2017 10:09:03 -0700 Subject: [PATCH 12/20] Reintroduce old eddy covariance processing to facilitate evaluation of new flux processing code and provide trivial way of looking at CO2 vs CO2_hf in real-time --- src/default.cr3 | 195 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 186 insertions(+), 9 deletions(-) diff --git a/src/default.cr3 b/src/default.cr3 index 911889d..47231ba 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -867,7 +867,7 @@ Alias diag_bits_sonic(5) = sonic_aq_sig_f 'Sonic acquiring signals warning flag Alias diag_bits_sonic(6) = sonic_cal_err_f 'Signature error in reading sonic head calibration data Units diag_bits_sonic = unitless -Dim sonic_irga_raw(12) 'Hold the first 12 data of EC100 from sonic, IRGA, temperature sensor, and barometer (raw data before applying instrument scan lag). +Dim sonic_irga_raw(13) 'Hold the first 12 data of EC100 from sonic, IRGA, temperature sensor, and barometer (raw data before applying instrument scan lag). Dim diag_sonic_tmp As Long 'Working variable used to break out the sonic head diagnostic bits. Dim sonic_disable_f As Boolean 'TRUE when any sonic diagnostic warning flag is on, sonic has not sent data, or an SDM signature error is reported. @@ -1112,7 +1112,7 @@ Units separation_lag_dist_irga = m Units separation_lag_scan_irga = scans 'Data from IRGA -Public irga(14) 'Hold IRGA data +Public irga(15) 'Hold IRGA data Alias irga(1) = CO2 Alias irga(2) = H2O Alias irga(3) = diag_irga @@ -1120,15 +1120,16 @@ Alias irga(4) = amb_tmpr 'Temperature measured by temperature probe c Alias irga(5) = amb_press 'Pressure measured by a barometer connected to EC100 Alias irga(6) = CO2_sig_strgth Alias irga(7) = H2O_sig_strgth +Alias irga(8) = CO2_hf 'irga(1) calculated using sonic temp instead of temperature probe -Alias irga(8) = Tc 'Air temperature (C), found from IRGASON' sonic temperature, water vapor density, or in case of the EC150/CSAT3A Tc=amb_tmpr from EC100 T probe -Alias irga(9) = RH 'Relative humidity (%): derived from Tc, H2O, and amb_press -Alias irga(10) = e_sat 'Saturation vapor pressure (kPa): derived from Tc, H2O, and amb_press -Alias irga(11) = e 'Vapor pressure (kPa): derived from Tc, H2O. and amb_press -Alias irga(12) = Td 'Dew point temperature (C): derived from Tc, H2O, and amb_press +Alias irga(9) = Tc 'Air temperature (C), found from IRGASON' sonic temperature, water vapor density, or in case of the EC150/CSAT3A Tc=amb_tmpr from EC100 T probe +Alias irga(10) = RH 'Relative humidity (%): derived from Tc, H2O, and amb_press +Alias irga(11) = e_sat 'Saturation vapor pressure (kPa): derived from Tc, H2O, and amb_press +Alias irga(12) = e 'Vapor pressure (kPa): derived from Tc, H2O. and amb_press +Alias irga(13) = Td 'Dew point temperature (C): derived from Tc, H2O, and amb_press -Alias irga(13) = CO2_mixratio 'CO2 mixing ratio -Alias irga(14) = H2O_mixratio 'H2O mixing ratio +Alias irga(14) = CO2_mixratio 'CO2 mixing ratio +Alias irga(15) = H2O_mixratio 'H2O mixing ratio Units CO2 = mg/m^3 Units H2O = g/m^3 @@ -1137,6 +1138,7 @@ Units amb_tmpr = C Units amb_press = kPa Units CO2_sig_strgth = fraction Units H2O_sig_strgth = fraction +Units CO2_hf = mg/m^3 Units Tc = C Units RH = % Units e_sat = kPa @@ -1490,6 +1492,107 @@ DataTable (comp_mean, TRUE, 1) EndTable '*** End of IRGA constants, variables, and working data table *** +'*** Beginning of old eddy-covariance processing data table +Dim cov_array_sonic(1,4) 'used to hold input data for cov instructions +Dim cov_array_cs(4,4) + +Const old_Lv = 2440 'estimate of latent heat of vaporization, J/g +Const old_Cp = 1004.67 'estimate of heat capacity of air, J/(kg K) +'MU_WPL, Rd change <=0.1% by using new program variables +Dim old_tau +Dim old_L +Dim old_u_star +Dim old_rho_d_mean 'kg/m^3 +Dim old_rho_a_mean 'kg/m^3 +Dim old_sigma_wpl +Dim old_Fc_irga +Dim old_LE_irga +Dim old_CO2_wpl_LE +Dim old_CO2_wpl_H +Dim old_Fc_wpl +Dim old_H2O_wpl_LE +Dim old_H2O_wpl_H +Dim old_LE_wpl +Dim old_Fc_hf_irga +Dim old_CO2_hf_wpl_LE +Dim old_CO2_hf_wpl_H +Dim old_Fc_hf_wpl +Dim old_Hs +Dim old_Hc +Units old_L = m +Units old_u_star = m/s +Units old_Fc_irga = mg/(m^2 s) +Units old_LE_irga = W/m^2 +Units old_CO2_wpl_LE = mg/(m^2 s) +Units old_CO2_wpl_H = mg/(m^2 s) +Units old_Fc_wpl = mg/(m^2 s) +Units old_H2O_wpl_LE = W/m^2 +Units old_H2O_wpl_H = W/m^2 +Units old_LE_wpl = W/m^2 +Units old_Fc_hf_irga = mg/(m^2 s) +Units old_CO2_hf_wpl_LE = mg/(m^2 s) +Units old_CO2_hf_wpl_H = mg/(m^2 s) +Units old_Fc_hf_wpl = mg/(m^2 s) +Units old_Hs = W/m^2 +Units old_Hc = W/m^2 + +Dim old_work_out(31) +Alias old_work_out(1) = old_Ts_Ts_cov 'results of covariance instructions, 10 qntys +Alias old_work_out(2) = old_Ts_Ux_cov +Alias old_work_out(3) = old_Ts_Uy_cov +Alias old_work_out(4) = old_Ts_Uz_cov +Alias old_work_out(5) = old_Ux_Ux_cov +Alias old_work_out(6) = old_Ux_Uy_cov +Alias old_work_out(7) = old_Ux_Uz_cov +Alias old_work_out(8) = old_Uy_Uy_cov +Alias old_work_out(9) = old_Uy_Uz_cov +Alias old_work_out(10) = old_Uz_Std +Alias old_work_out(11) = old_CO2_mg_m3_Std 'results of 3 covariances, 12 #s +Alias old_work_out(12) = old_CO2_Ux_cov +Alias old_work_out(13) = old_CO2_Uy_cov +Alias old_work_out(14) = old_CO2_Uz_cov +Alias old_work_out(15) = old_H2O_g_m3_Std +Alias old_work_out(16) = old_H2O_Ux_cov +Alias old_work_out(17) = old_H2O_Uy_cov +Alias old_work_out(18) = old_H2O_Uz_cov +Alias old_work_out(19) = old_Tc_stdev +Alias old_work_out(20) = old_Tc_Ux_cov +Alias old_work_out(21) = old_Tc_Uy_cov +Alias old_work_out(22) = old_Tc_Uz_cov +Alias old_work_out(23) = old_CO2_mg_m3_Avg 'four averages +Alias old_work_out(24) = old_H2O_g_m3_Avg +Alias old_work_out(25) = old_amb_press_Avg +Alias old_work_out(26) = old_Tc_Avg +Alias old_work_out(27) = old_CO2_hf_mg_m3_Avg '1 average +Alias old_work_out(28) = old_CO2_hf_mg_m3_Std 'results of 1 covariance, 4#s +Alias old_work_out(29) = old_CO2_hf_Ux_cov +Alias old_work_out(30) = old_CO2_hf_Uy_cov +Alias old_work_out(31) = old_CO2_hf_Uz_cov +Units old_Uz_Std = m/s +Units old_CO2_mg_m3_Std = mg/m^3 +Units old_H2O_g_m3_Std = g/m^3 +Units old_CO2_mg_m3_Avg = mg/m^3 +Units old_H2O_g_m3_Avg = g/m^3 +Units old_amb_press_Avg = kPa +Units old_Tc_Avg = C +Units old_CO2_hf_mg_m3_Std = mg/m^3 + +DataTable(old_cov_work,TRUE,1) + TableHide + DataInterval(0,OUTPUT_INTERVAL,Min,1) + Covariance(4,cov_array_sonic(1,1),IEEE4,sonic_disable_f,10) + Covariance(4,cov_array_cs(1,1),IEEE4,irga_disable_f,4) + Covariance(4,cov_array_cs(2,1),IEEE4,irga_disable_f,4) + Covariance(4,cov_array_cs(3,1),IEEE4,irga_disable_f,4) + Average(1,CO2,IEEE4,irga_disable_f) + Average(1,H2O,IEEE4,irga_disable_f) + Average(1,amb_press,IEEE4,irga_disable_f) + Average(1,Tc,IEEE4,irga_disable_f) + Average(1,CO2_hf,IEEE4,irga_disable_f) + Covariance(4,cov_array_cs(4,1),IEEE4,irga_disable_f,4) +EndTable +'*** End of old eddy-covariance processing data table + #If (SENSOR_FW) Then '*** Beginning of FW constants, variables, and working data table *** Public time_const_FW = 0.001 'default value (seconds). It will be recalculated inside the program @@ -2065,6 +2168,24 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) DataInterval (0, OUTPUT_INTERVAL, Min, 10) TableFile ("CRD:"&Status.SerialNumber(1,1)&".Flux_", 64, -1, 0, NMBR_DAY_FLUX_CRD, Day, 0, 0) + '*** Beginning of old flux eddy covariance output *** + #If (SENSOR_CSAT3AEC150) Then + Sample(1,old_L,IEEE4) 'monin obukhov length, meters + Sample(1,old_u_star,IEEE4) 'friction velocity, m/s + Sample(1,old_Fc_wpl,IEEE4) 'density-corrected (WPL) CO2 flux, mg/m3 + Sample(1,old_Fc_hf_wpl,IEEE4) 'WPL-corrected CO2 flux using alt. CO2 value + Sample(1,old_LE_wpl,IEEE4) 'density-corrected (WPL) latent heat flux, W/m2 + Sample(1,old_Hc,IEEE4) 'density-corrected sensible heat flux, W/m2 + Sample(1,old_Uz_Std,IEEE4) 'stdev of vertical wind, m/s + Sample(1,old_CO2_mg_m3_Avg,IEEE4) 'mean of CO2 conc, mg/m3 + Sample(1,old_CO2_mg_m3_Std,IEEE4) 'stdev of CO2 conc, mg/m3 + Sample(1,old_CO2_hf_mg_m3_Avg,IEEE4) + Sample(1,old_CO2_hf_mg_m3_Std,IEEE4) + Sample(1,old_Tc_Avg,IEEE4) + Sample(1,old_amb_press_Avg,IEEE4) + #EndIf + '*** End of old eddy covariance output *** + '**** Beginning of flux and quality classification data *** Sample (1, Fc_molar, IEEE4) 'Carbon dioxide flux in umol/(m^2 s) after coordinate rotations, freq corrections, and WPL correction Sample (1, Fc_mass, IEEE4) 'Carbon dioxide flux in mg/(m^2 s) after coordinate rotations, freq corrections, and WPL correction @@ -4863,6 +4984,62 @@ BeginProg EndIf '*** End of IRGA processing *** + + + '*** Beginning of old eddy-covariance processing + #If (SENSOR_CSAT3AEC150) Then + cov_array_sonic(1,1) = Ts + Move (cov_array_sonic(1,2),3,Ux,3) + + cov_array_cs(1,1) = CO2 + cov_array_cs(2,1) = H2O + cov_array_cs(3,1) = Tc + cov_array_cs(4,1) = CO2_hf + Move (cov_array_cs(1,2),3,Ux,3) + Move (cov_array_cs(2,2),3,Ux,3) + Move (cov_array_cs(3,2),3,Ux,3) + Move (cov_array_cs(4,2),3,Ux,3) + + CallTable old_cov_work + If (old_cov_work.Output(1,1)) Then + GetRecord(old_work_out(1),old_cov_work,1) + + old_tau = SQR((old_Ux_Uz_cov*old_Ux_Uz_cov)+(old_Uy_Uz_cov*old_Uy_Uz_cov)) + old_L = -old_u_star^3*(old_Tc_Avg+273.15)/(0.4*9.8*old_Ts_Uz_cov) + old_rho_d_mean = (old_amb_press_Avg/((old_Tc_Avg+273.15)*Rd))-(old_H2O_g_m3_Avg*MU_WPL) + old_rho_a_mean = (old_rho_d_mean+old_H2O_g_m3_Avg)/1000 + old_Fc_irga = old_CO2_Uz_cov + old_LE_irga = old_Lv*old_H2O_Uz_cov + old_CO2_mg_m3_Std = SQR (old_CO2_mg_m3_Std) + old_H2O_g_m3_Std = SQR (old_H2O_g_m3_Std) + old_sigma_wpl = old_H2O_g_m3_Avg/old_rho_d_mean 'WPL term + + 'EC150 Webb et al. (1980) term for carbon dioxide Eq. (24). + old_CO2_wpl_LE = MU_WPL*old_CO2_mg_m3_Avg/old_rho_d_mean*old_H2O_Uz_cov + old_CO2_wpl_H = (1+(MU_WPL*old_sigma_wpl))*old_CO2_mg_m3_Avg/(old_Tc_Avg+273.15)*old_Tc_Uz_cov + old_Fc_wpl = old_Fc_irga+old_CO2_wpl_LE+old_CO2_wpl_H + + 'EC150 Webb et al. (1980) term for water vapor Eq. (25). + old_H2O_wpl_LE = MU_WPL*old_sigma_wpl*old_LE_irga + old_H2O_wpl_H = (1+(MU_WPL*old_sigma_wpl))*old_H2O_g_m3_Avg/(old_Tc_Avg+273.15)*old_Lv*old_Tc_Uz_cov + old_LE_wpl = old_LE_irga+old_H2O_wpl_LE+old_H2O_wpl_H + + 'repeat using high-frequency tmpr CO2 value + old_Fc_hf_irga = old_CO2_hf_Uz_cov + old_CO2_hf_mg_m3_Std = SQR(old_CO2_hf_mg_m3_Std) + old_CO2_hf_wpl_LE = MU_WPL*old_CO2_hf_mg_m3_Avg/old_rho_d_mean*old_H2O_Uz_cov + old_CO2_hf_wpl_H = (1+(MU_WPL*old_sigma_wpl))*old_CO2_hf_mg_m3_Avg/(old_Tc_Avg+273.15)*old_Tc_Uz_cov + old_Fc_hf_wpl = old_Fc_hf_irga+old_CO2_hf_wpl_LE+old_CO2_hf_wpl_H + + old_Hs = old_rho_a_mean*old_Cp*old_Ts_Uz_cov + old_tau = old_rho_a_mean*old_tau + old_Uz_Std = SQR(old_Uz_Std) + old_Hc = old_rho_a_mean*old_Cp*old_Tc_Uz_cov + EndIf + #EndIf + '*** End of old eddy-covariance processing + + #If (SENSOR_TMPR_RH) Then '*** Beginning of temperature and humidity processing *** From b0f35a8202aa03cb2296f58b3ae93e0db6a3f7cd Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 10:13:39 -0700 Subject: [PATCH 13/20] Record alt. hi-freq CO2 value (following up Helbig et al 2016) --- src/default.cr3 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/default.cr3 b/src/default.cr3 index 47231ba..54c0385 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -2658,10 +2658,15 @@ DataTable (Time_Series, TRUE, -1) #If (SENSOR_IRGASON) Then Sample (1, Tc, IEEE4) FieldNames ("Tc") - #EndIf Sample (4, amb_tmpr,IEEE4) FieldNames ("amb_tmpr,amb_press, CO2_sig_strgth, H2O_sig_strgth") + #EndIf + + #If (SENSOR_CSAT3AEC150) Then + Sample (5, amb_tmpr,IEEE4) + FieldNames ("amb_tmpr,amb_press, CO2_sig_strgth, H2O_sig_strgth,CO2_hf") + #EndIf '*** End of IRGA time series output *** #If (SENSOR_FW) Then From e62cf671c86f4e160e9951eb3846ab747ae35019 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 10:14:12 -0700 Subject: [PATCH 14/20] FIX: units misspelling --- src/default.cr3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/default.cr3 b/src/default.cr3 index 54c0385..7639786 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -1814,7 +1814,7 @@ Units R_SW_in = W/m^2 Units R_SW_out = W/m^2 Units R_LW_in = W/m^2 Units R_LW_out = W/m^2 -Units T_nr = Klvin +Units T_nr = Kelvin Units R_LW_in_meas = W/m^2 Units R_LW_out_meas = W/m^2 '*** End of NR01/CNR4 constants and variables *** From c7052d53600711d0705a1cd99a3d1d721c38b611 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 11:39:11 -0700 Subject: [PATCH 15/20] Reintroduce vertical profile of soil T/VWC probes (TDR-315L) --- CHANGELOG.md | 4 ++- src/default.cr3 | 69 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca11d8..29b152c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,8 @@ Next release ### Instrumentation Changes -* Remove soil temp/moisture probes (8x Decagon Devices 5TM) +* Change soil temp/moisture probes in vertical profile and in layer above soil + heat flux plates (8x Decagon Devices 5TM → 6x Acclima TDR-315L) * Change soil temperature probes in layer above soil heat flux plates (2x CSI model 109 probes → 1x CSI averaging thermocouple) * Remove prototype NDVI/PRI sensors (Decagon Devices) @@ -64,6 +65,7 @@ Next release * Cup & vane wind set (MetOne 034B) * GPS receiver (GPS16X-HVS) * Additional soil temperature/water content probe (Acclima TDR-315L) +* Reintroduce vertical profile of soil tmpr/VWC probes (Acclima TDR-315L) diff --git a/src/default.cr3 b/src/default.cr3 index 7639786..946e8a1 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -116,6 +116,8 @@ Const SENSOR_TDR315 = TRUE 'Unique: Acclima TDR-315L soil water content Const SENSOR_HFP01 = TRUE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE +Const PROFILE_TDR315 = TRUE 'Unique: soil profile composed of Acclima TDR-315L probes + Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set Const SENSOR_GPS16X = TRUE 'Unique: Garmin GPS16x-HVS GPS receiver @@ -126,6 +128,7 @@ Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) Const SENSOR_TE525x = ((SENSOR_TE525) OR (SENSOR_TE525WS) OR (SENSOR_TE525MM) OR (SENSOR_TE525_wf)) Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X) OR (SENSOR_TDR315)) +Const SENSOR_PROFILE = ((PROFILE_TDR315)) '***** Wiring Instruction ****** '*** Beginning of EC100 (IRGASON or EC150 w/ or w/o CSAT3A sonic head) wiring *** @@ -450,6 +453,26 @@ Const TDR315_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 '*** End of TDR-315 wiring *** #EndIf #EndIf +#If (SENSOR_PROFILE) Then + +Const NMBR_PROFILE = 6 'number of T/VWC probes in profile + +#If (PROFILE_TDR315) Then + +Const TDR315_SDI12_Address_P = 3 'Unique: first address in sequential series +#If (NOT SENSOR_TDR315) Then +Const TDR315_SDI12_PORT = 7 'Control port for SDI-12 data +'*** Beginning of TDR-315 wiring *** +'C5 SDI-12 data #1 (blue) +' SDI-12 data #2 (blue +'12V SDI-12 power #1 (red) +' SDI-12 power #2 (red) +'G SDI-12 ground #1 (white) +' SDI-12 ground #2 (white) +'*** End of TDR-315 wiring *** +#EndIf +#EndIf +#EndIf #If (SENSOR_TMPR_RH) Then Const TMPR_RH_ANALOG_INPUT = 8 'Starting differential analog input channel for temperature and humidity probe. @@ -1934,13 +1957,31 @@ Public tdr315_E(NMBR_CS6xx) 'soil permittivity, unitless Public tdr315_bulkEC(NMBR_CS6xx) 'bulk electrical conductivity, uS/cm Public tdr315_poreEC(NMBR_CS6xx) 'soil pore water EC, uS/cm Dim tdr315_raw(5) 'holds response from sensor #X -Units tdr315_wc = frac_v_wtr +Units tdr315_wc = % Units tdr315_tmpr = C Units tdr315_E = unitless Units tdr315_bulkEC = uS/cm Units tdr315_poreEC = uS/cm '*** End of TDR315 constants and variables *** #EndIf +#If (PROFILE_TDR315) Then + +'*** Beginning of TDR315 profile constants and variables *** +Public profile_tdr315_wc(NMBR_PROFILE) 'volumetric water content, % +Public profile_tdr315_tmpr(NMBR_PROFILE) 'soil temperature, degC +Public profile_tdr315_E(NMBR_PROFILE) 'soil permittivity, unitless +Public profile_tdr315_bulkEC(NMBR_PROFILE) 'bulk electrical conductivity, uS/cm +Public profile_tdr315_poreEC(NMBR_PROFILE) 'soil pore water EC, uS/cm +#If (NOT SENSOR_TDR315) Then +Dim tdr315_raw(5) 'holds response from sensor #X +#EndIf +Units profile_tdr315_wc = % +Units profile_tdr315_tmpr = C +Units profile_tdr315_E = unitless +Units profile_tdr315_bulkEC = uS/cm +Units profile_tdr315_poreEC = uS/cm +'*** End of TDR315 profile constants and variables *** +#EndIf #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then '*** Beginning of variables for calculation of soil heat flux at soil surface *** @@ -2389,6 +2430,16 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) '*** End of HFP01SC output data *** #EndIf + #If (PROFILE_TDR315) Then + + '*** Beginning of TDR315 profile output data *** + Average (NMBR_PROFILE, profile_tdr315_wc(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_tdr315_tmpr(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_tdr315_E(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_tdr315_bulkEC(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_tdr315_poreEC(1), IEEE4, slowsequence_disable_flg) + '*** End of TDR315 profile output data *** + #EndIf '*** Footprint characteristics **** Sample (1, upwnd_dist_intrst, IEEE4) 'User-entered upwind distance of interest for the average upwind direction in this averaging interval Sample (1, FP_dist_intrst, IEEE4) 'Percentage of measured scalar flux from upwind range of interest @@ -5583,6 +5634,22 @@ BeginProg '*** End of TDR-315 measurements *** #EndIf + #If (SENSOR_PROFILE) Then + + '*** Beginning of TDR-315 profile measurements *** + For i_slow = 1 To NMBR_PROFILE + #If (PROFILE_TDR315) Then + 'XXXX WARNING assumes no address above 9 (default: 6 sensors #3-8) + SDI12Recorder (tdr315_raw(1), TDR315_SDI12_PORT, TDR315_SDI12_Address_P+i_slow-1, "M!", 1, 0) + profile_tdr315_wc(i_slow) = tdr315_raw(1) + profile_tdr315_tmpr(i_slow) = tdr315_raw(2) + profile_tdr315_E(i_slow) = tdr315_raw(3) + profile_tdr315_bulkEC(i_slow) = tdr315_raw(4) + profile_tdr315_poreEC(i_slow) = tdr315_raw(5) + #EndIf + Next i_slow + '*** End of TDR-315 profile measurements *** + #EndIf #If (SENSOR_LI200X) OR (SENSOR_CS300) Then '*** Beginning of pyranometer measurements *** From 668cf1e342edf92ca61909f02198e35010b2723f Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 13:16:21 -0700 Subject: [PATCH 16/20] Re-integrate Decagon Devices 5TM tmpr/VWC probes as HFP/profile sensors --- CHANGELOG.md | 6 +- doc/_sources.txt | 2 + src/default.cr3 | 143 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 141 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b152c..770b51c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,8 +64,10 @@ Next release * Additional temperature/humidity probes (HC2S3, HMP45C) * Cup & vane wind set (MetOne 034B) * GPS receiver (GPS16X-HVS) - * Additional soil temperature/water content probe (Acclima TDR-315L) -* Reintroduce vertical profile of soil tmpr/VWC probes (Acclima TDR-315L) + * Additional soil temperature/water content probes + * Acclima TDR-315L + * Decagon Devices 5TM +* Reintroduce vertical profile of soil tmpr/VWC probes (TDR-315L or 5TM) diff --git a/doc/_sources.txt b/doc/_sources.txt index 9f5194b..bc0abeb 100644 --- a/doc/_sources.txt +++ b/doc/_sources.txt @@ -31,6 +31,8 @@ http://manuals.decagon.com/Integration%20Guides/SRS-N%20Integrators%20Guide.pdf http://manuals.decagon.com/Integration%20Guides/SRS-P%20Integrators%20Guide.pdf Decagon SRS-PRI Integrator Guide.pdf http://www.decagon.com/assets/Uploads/SRS-pair-example-program.CR1.zip Decagon SRS Example CR1K Program.zip http://www.acclima.com/poc7/prodlit/TDR-315%20User%20Manual.pdf Acclima TDR-315 User Manual.pdf +http://manuals.decagon.com/Manuals/13441_5TM_Web.pdf Decagon Devices 5TM Manual.pdf +http://manuals.decagon.com/Integration%20Guides/5TM%20Integrators%20Guide.pdf Decagon Devices 5TM Integrator Guide.pdf # software http://s.campbellsci.com/documents/us/manuals/loggernet.pdf CSI LoggerNet Instruction Manual.pdf diff --git a/src/default.cr3 b/src/default.cr3 index 946e8a1..a244617 100644 --- a/src/default.cr3 +++ b/src/default.cr3 @@ -110,13 +110,16 @@ Const SENSOR_TE525MM = FALSE 'Unique: TE525MM (metric) rain gage Const SENSOR_TE525_wf = FALSE 'Unique: TE525 or TE525MM rain gage with 8in funnel Const SENSOR_TCAV = TRUE 'Unique: TCAV: type E thermocouple averaging soil temperature probes -Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS65X must be set to FALSE -Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture, if true, SENSOR_CS616 must be set to FALSE -Const SENSOR_TDR315 = TRUE 'Unique: Acclima TDR-315L soil water content/temperature probes, if true, SENSOR_CS65X and SENSOR_CS616 must be false Const SENSOR_HFP01 = TRUE 'Unique: HFP01: soil heat flux plates, if true, SENSOR_HFP01SC must be set to FALSE Const SENSOR_HFP01SC = FALSE 'Unique: HFP01SC: self-calibrated soil heat flux plates, if true, SENSOR_HFP01 must be set to FALSE +'Select at most 1 soil T/VWC probe: +Const SENSOR_CS616 = FALSE 'Unique: CS616: water content reflectometers for volumetric soil moisture +Const SENSOR_CS65X = FALSE 'Unique: CS650 or CS655: water content reflectometers for volumetric soil moisture +Const SENSOR_TDR315 = TRUE 'Unique: Acclima TDR-315L soil water content/temperature probes +Const SENSOR_5TM = FALSE 'Unique: Decagon Devices 5TM soil water content/temperature probes -Const PROFILE_TDR315 = TRUE 'Unique: soil profile composed of Acclima TDR-315L probes +Const PROFILE_TDR315 = TRUE 'Unique: soil profile composed of Acclima TDR-315L probes, if true, PROFILE_5TM must be false +Const PROFILE_5TM = FALSE 'Unique: soil profile composed of Decagon Devices 5TM probes, if true, PROFILE_TDR315 must be false Const SENSOR_034B = TRUE 'Unique: MetOne 034B cup & vane wind set Const SENSOR_GPS16X = TRUE 'Unique: Garmin GPS16x-HVS GPS receiver @@ -127,8 +130,8 @@ Const SENSOR_TMPR_RH = ((SENSOR_HMP155A) OR (SENSOR_HC2S3) OR (SENSOR_HMP45C Const SENSOR_Rn = ((SENSOR_CNR4) OR (SENSOR_NR01) OR (SENSOR_NR_LITE)) Const SENSOR_TE525x = ((SENSOR_TE525) OR (SENSOR_TE525WS) OR (SENSOR_TE525MM) OR (SENSOR_TE525_wf)) Const SENSOR_HFP = ((SENSOR_HFP01) OR (SENSOR_HFP01SC)) -Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X) OR (SENSOR_TDR315)) -Const SENSOR_PROFILE = ((PROFILE_TDR315)) +Const SENSOR_CS6XX = ((SENSOR_CS616) OR (SENSOR_CS65X) OR (SENSOR_TDR315) OR (SENSOR_5TM)) +Const SENSOR_PROFILE = ((PROFILE_TDR315) OR (PROFILE_5TM)) '***** Wiring Instruction ****** '*** Beginning of EC100 (IRGASON or EC150 w/ or w/o CSAT3A sonic head) wiring *** @@ -452,6 +455,22 @@ Const TDR315_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 ' SDI-12 ground #2 (white) '*** End of TDR-315 wiring *** #EndIf +#If (SENSOR_5TM) Then + +Const fiveTM_SDI12_PORT = 7 'Control port for SDI-12 data +Const fiveTM_SDI12_Address_1 = 1 'Unique: SDI address for TDR-315 #1 +#If (NMBR_CS6xx = 2) Then +Const fiveTM_SDI12_Address_2 = 2 'Unique: SDI address for TDR-315 #2 +#EndIf +'*** Beginning of 5TM wiring *** +'C5 SDI-12 data #1 (red) +' SDI-12 data #2 (red) +'12V SDI-12 power #1 (white) +' SDI-12 power #2 (white) +'G SDI-12 ground #1 (bare) +' SDI-12 ground #2 (bare) +'*** End of 5TM wiring *** +#EndIf #EndIf #If (SENSOR_PROFILE) Then @@ -472,6 +491,21 @@ Const TDR315_SDI12_PORT = 7 'Control port for SDI-12 data '*** End of TDR-315 wiring *** #EndIf #EndIf +#If (PROFILE_5TM) Then + +Const fiveTM_SDI12_Address_P = 3 'Unique: first address in sequential series +#If (NOT SENSOR_5TM) Then +Const fiveTM_SDI12_PORT = 7 'Control port for SDI-12 data +#EndIf +'*** Beginning of 5TM wiring *** +'C5 SDI-12 data #1 (red) +' SDI-12 data #2 (red) +'12V SDI-12 power #1 (white) +' SDI-12 power #2 (white) +'G SDI-12 ground #1 (bare) +' SDI-12 ground #2 (bare) +'*** End of 5TM wiring *** +#EndIf #EndIf #If (SENSOR_TMPR_RH) Then @@ -1982,6 +2016,33 @@ Units profile_tdr315_bulkEC = uS/cm Units profile_tdr315_poreEC = uS/cm '*** End of TDR315 profile constants and variables *** #EndIf +#If (SENSOR_5TM) Then + +'*** Beginning of 5TM constants and variables *** +'XXXX HACK use `soil_` prefix to mitigate starting numeral in model name +Public soil_5TM_E(NMBR_CS6xx) 'soil permittivity, unitless +Public soil_5TM_tmpr(NMBR_CS6xx) 'soil temperature, degC +Public soil_5TM_wc(NMBR_CS6xx) 'volumetric water content, v/v +Dim fiveTM_raw(3) 'holds response from sensor #x +Units soil_5TM_E = unitless +Units soil_5TM_tmpr = C +Units soil_5TM_wc = frac_v_wtr +'*** End of 5TM constants and variables *** +#EndIf +#If (PROFILE_5TM) Then + +'*** Beginning of 5TM profile constants and variables *** +Public profile_5TM_E(NMBR_PROFILE) 'soil permittivity, unitless +Public profile_5TM_tmpr(NMBR_PROFILE) 'soil temperature, degC +Public profile_5TM_wc(NMBR_PROFILE) 'volumetric water content, v/v +#If (NOT SENSOR_5TM) Then +Dim fiveTM_raw(3) 'holds response from sensor #X +#EndIf +Units profile_5TM_E = unitless +Units profile_5TM_tmpr = C +Units profile_5TM_wc = frac_v_wtr +'*** End of 5TM profile constants and variables *** +#EndIf #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_CS65X) OR (SENSOR_TDR315))) Then '*** Beginning of variables for calculation of soil heat flux at soil surface *** @@ -2417,6 +2478,14 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) Average (NMBR_CS6xx, tdr315_poreEC(1), IEEE4, slowsequence_disable_flg) '*** End of TDR315 output data *** #EndIf + #If (SENSOR_5TM) Then + + '*** Beginning of 5TM output data *** + Average (NMBR_CS6xx, soil_5TM_E(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, soil_5TM_tmpr(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_CS6xx, soil_5TM_wc(1), IEEE4, slowsequence_disable_flg) + '*** End of 5TM output data *** + #EndIf #If (SENSOR_HFP) Then '*** Beginning of HFP01 output data *** @@ -2440,6 +2509,14 @@ DataTable (Flux, TRUE, FLUX_SIZE_CPU) Average (NMBR_PROFILE, profile_tdr315_poreEC(1), IEEE4, slowsequence_disable_flg) '*** End of TDR315 profile output data *** #EndIf + #If (PROFILE_5TM) Then + + '*** Beginning of 5TM output data *** + Average (NMBR_PROFILE, profile_5TM_E(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_5TM_tmpr(1), IEEE4, slowsequence_disable_flg) + Average (NMBR_PROFILE, profile_5TM_wc(1), IEEE4, slowsequence_disable_flg) + '*** End of 5TM output data *** + #EndIf '*** Footprint characteristics **** Sample (1, upwnd_dist_intrst, IEEE4) 'User-entered upwind distance of interest for the average upwind direction in this averaging interval Sample (1, FP_dist_intrst, IEEE4) 'Percentage of measured scalar flux from upwind range of interest @@ -4299,6 +4376,15 @@ Sub Separation_Lag_Lateral_Distances (wnd_dir, separation_x, separation_y, separ separation_lat_dis = -separation_x*SIN(wnd_dir) + separation_y*COS(wnd_dir) EndSub + +'*****************' +'*** FUNCTIONS ***' +'*****************' +Function Topp_equation( dielectric ) + Return 4.3e-6*dielectric^3 - 5.5e-4*dielectric^2 + 2.92e-2*dielectric - 5.3e-2 +EndFunction + + '********************' '*** MAIN PROGRAM ***' '*********************' @@ -5617,10 +5703,10 @@ BeginProg #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_TDR315))) Then - AvgRun (soil_wtr_current(1), NMBR_CS6xx, tdr315_wc(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + AvgRun (soil_wtr_current(1), NMBR_CS6xx, (tdr315_wc(1)/100), NMBR_SOIL_T_WTR_DEL_SAMPLES) 'HINT scale % -> v/v If (soil_wtr_prev_Avg = NaN) Then - AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, tdr315_wc(1)) + AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, (tdr315_wc(1)/100)) 'HINT scale % -> v/v EndIf #If ((SENSOR_TDR315) AND ( NOT SENSOR_TCAV)) Then @@ -5633,6 +5719,39 @@ BeginProg #EndIf '*** End of TDR-315 measurements *** #EndIf + #If (SENSOR_5TM) Then + + '*** Beginning of 5TM measurements *** + SDI12Recorder(fiveTM_raw(1), fiveTM_SDI12_PORT, fiveTM_SDI12_Address_1, "M!", 1, 0) + soil_5TM_E(1) = fiveTM_raw(1) + soil_5TM_tmpr(1) = fiveTM_raw(2) + soil_5TM_wc(1) = Topp_equation(fiveTM_raw(3)) + + #If (NMBR_CS6xx = 2) Then + SDI12Recorder(fiveTM_raw(1), fiveTM_SDI12_PORT, fiveTM_SDI12_Address_2, "M!", 1, 0) + soil_5TM_E(2) = fiveTM_raw(1) + soil_5TM_tmpr(2) = fiveTM_raw(2) + soil_5TM_wc(2) = Topp_equation(fiveTM_raw(3)) + #EndIf + + #If ((SENSOR_HFP) AND (SENSOR_CS6XX) AND ((SENSOR_TCAV) OR (SENSOR_5TM))) Then + + AvgRun (soil_wtr_current(1), NMBR_CS6xx, soil_5TM_wc(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (soil_wtr_prev_Avg = NaN) Then + AvgSpa (soil_wtr_prev_Avg, NMBR_CS6xx, soil_5TM_wc(1)) + EndIf + + #If ((SENSOR_5TM) AND ( NOT SENSOR_TCAV)) Then + AvgRun (Tsoil_current(1), NMBR_CS6xx, soil_5TM_tmpr(1), NMBR_SOIL_T_WTR_DEL_SAMPLES) + + If (Tsoil_prev_Avg = NaN) Then 'As soon as program starts + AvgSpa (Tsoil_prev_Avg, NMBR_CS6xx, soil_5TM_tmpr(1)) + EndIf + #EndIf + #EndIf + '*** End of 5TM measurements *** + #EndIf #If (SENSOR_PROFILE) Then @@ -5647,6 +5766,14 @@ BeginProg profile_tdr315_bulkEC(i_slow) = tdr315_raw(4) profile_tdr315_poreEC(i_slow) = tdr315_raw(5) #EndIf + + #If (PROFILE_5TM) Then + 'XXXX WARNING assumes no address above 9 (default: 6 sensors #3-8) + SDI12Recorder (fiveTM_raw(1), fiveTM_SDI12_PORT, fiveTM_SDI12_Address_P+i_slow-1, "M!", 1, 0) + profile_5TM_E(i_slow) = fiveTM_raw(1) + profile_5TM_tmpr(i_slow) = fiveTM_raw(2) + profile_5TM_wc(i_slow) = Topp_equation(fiveTM_raw(3)) + #EndIf Next i_slow '*** End of TDR-315 profile measurements *** #EndIf From 55d620e06ad0f5821c7ced2cd9d349014be9a3b4 Mon Sep 17 00:00:00 2001 From: Patrick O'Keeffe Date: Sun, 7 May 2017 14:09:45 -0700 Subject: [PATCH 17/20] Add support for enclosure door open sensor --- CHANGELOG.md | 2 ++ doc/wiring.xlsx | Bin 12068 -> 12178 bytes src/default.cr3 | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 770b51c..22d14b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ Next release * Change PAR sensor back to LI190SB with Campbell Scientific-specific cabling (versus Licor direct-purchase LI190R unit) * Significant revisions to datalogger wiring scheme +* Add door sensor switch ### Other changes @@ -68,6 +69,7 @@ Next release * Acclima TDR-315L * Decagon Devices 5TM * Reintroduce vertical profile of soil tmpr/VWC probes (TDR-315L or 5TM) +* Support for door sensor switch diff --git a/doc/wiring.xlsx b/doc/wiring.xlsx index a9addca0118888d15d82b65c99b1926aba986f65..fd963fca2b70efcef8ece615916656401dcc8ee9 100644 GIT binary patch delta 3821 zcmV_l(B-9KU@tG{yq$mFC*pTU&heeUt4m zXMg5g6)0)tQR$pn`qVq$6dKvq>=A7){3r-6{hV>>L8cDUlHbb@9vme9N}%U&8fLvS(7Fa9|~rcEH6&5ClzhIlhN2v#g2lG@|2s}JIaiC-y;n-{3wtrGwv{7h$L{0bSuxtc#wK`ezhEJvCE3zMD)Snl|CZw1cHiT6b7sv}$r`>aeaOI|V4wf@a$;`+w1* zW2HJr-#JHac3?F#Ik#|@KK$BgdR^ zoR{fAX;f)7yX%El!SZ*<>XweD>wnNoJNgVSA9~Z((y>eq1^mMD;u9R1L;$i5E`D+hF1DUMh2U+285W2y`3?wFUnR6pkWELL9;RJSWO5=?T9YOg_CD<9`8@ zp#v1N9uJQU3Rtum13(D?075F0w;LdT-;bj<5Pq-J{~_Z2k^q7H&}OSmXcDAWJ@xL| zXO@s%bV*2oy}j#S-?2S_JvIdTvSEkM9=H?oX=}(XU}2E|KYu`=h_O^w6aL0I(_{I%ww&pB=6Lgk z4fs*~R+QQ0Z}En6Q@3=mCH%hQdw*=trao);oD}6QWwvzca8U>RqK;*)q9}hb7f?H$ zVFUQBIyJQD+dUY{2M@o0sBJo4c;3uk%)7_#V?+4Gh7QosK^9Cd?+JeYH(9VIa2@d5 zkE|s&fZwW9d2VZh@6a_7F2g-Oh|1{kA<;_3)Vva2aXz#Ket`u+>3q1p@xo3_2{y+(5qS&kX~AtK5L3=Ef$IxJ9@OA(jRP z2$|;{LL_>WP6?X_T_YhdM1;(a-8iSh4y(YVeAXR!46L#vFXJ{@W3~vF*&(4A7$78y zb_kIv@kli81xAiHj~H_h5ZUi2YdXSjCQ~7e?NoY`#=t6R@}gmrp==Q@lSa~GV1Q84 z5aQP{z84aIg(5N;2LX{OB5Fe&;Wy5#Pz1G6e~K7br3fTV)RBqWBD^c=5F+QuIT`K_ zF%m~YB6H->wMjsf<%>*DC?JZzwvc4Q9=JbC9IevCL=8`5q1aXpx&pAmC`?grsz8cs zkYVo?TeR>q*h1sa0C8Ia&?aSg_p-&&K%6`!GeXvX20_Z?)8!s99T5^3Aajxuc9lKS zg3m-vAwdJPYS3P>ga(M;EP+aB+N6fRL!KyyooQ1pa0P2ip^Db1h>@wH^-W;H&^i?{ zu)VML0(&NEDqk9)RfCQNG(?P?yu7v$B}M-ovao2D$r2)kELxD-0@IP40)(`zDx%Cn zjN<2i9^q$?pw3)ru*W0u5*jdWOLfXNx&xLuQT8ehCqxQ|WR2SLPS%#PGSgbjfN^MH zj~F1aaX7tuPYY3j>FPc-bniFat1-$7+}-R3sM3fup4<5)Y1d?BCBbCDfw9h3}8=`%L;o!)Kv*=c_+l-Xr+dj zZuYQRZ}ww*C4v{Ul0~JRTp9KVEgJxS2HW4$uo{;qb4EgOqa5xyT2-Rg{4Pnf0XK@D zCDktDHyAZi1{LG%tcsMH{P?Qc{kp_4w^ai<<1IBM#3J2B2ut(RdMUh!2cyox~HjW}?EFRz zsiZXRi-c^COAjO}6`d=Xo|1ji%K`K>{>GoxaSb}GbM(`?O4OM=Dv+`YYO|z&Cvl(d z#6VFq8u4{k`I0m!aXWhAW}=Q2uE#+dD($lmbOt4EjwUA#bHdLCK}z(~T@7M7OLPOq zZP`}1gEBcstJ?|`b*@;5QR;pAeTvz!w)&irxr5RkdFLJ%ta^~U6SsQrkKJ(yc{yDCS_6-v?#%iB0 zG0n>u?E|KcnYSEgxpEf1Z!Kow<~(V`6g1Y-{L9s=TM_Lb3o(7x5x51=)YA8@#XKup zt5gCs6LIybwYKKSLTN8+2Kjt{1z&=6`O|Fm1YaZ!FKip$m{dL4^VO5s5oyNy@P=Qa)84r7 zhR>?@W(h+#6X^k6qCRY<1g`hx>9zdh#xE$2Uh?$#TY61cna)PR?*9EAA7@d<7 z%-wVh3qdZf&++Gy-QVF)&shmq;P9VUxJsEosSP>%lx3xOM2&DtoAB*6D&mM;Tbo0T zl;tU0z2lc8*VZk|%REX;xF-eje=~S-4sI!YI&hY=r9X$i7P}H!rl5eofIjk7dR$w1 zcof$X>)W4?{{fSs0~7@gOte>Iv)v>n0e?+P12Gtc?}Gnf$;Hz)$@bH*-GWLlDi*9L z-a_)W4c*NyNwn?1H~ZF zQ|?swo0__PwiLD4xsO(L#>3$-I1H;AzCXopj}On)siD&4Rsv8GOTmNz?sAi?xHC%Z zgQu%|fXxPC+!M!}`2Tv^*vcsFKqe8P(~yiqGF{UN8&4S-zsI=A zwI*Mx+MsR*GVoWidV^MZ9p2upm#E>5LNZ*_85>6|nt0x?e0gOJ%$oN9603$0W%Qbn zQIFUHlB)F2pOt(8lc56?lZ!48vw|me1q!J64>XDc0049flL0MK0x}PiEDt4&+C_TCmEGsnSmbbFi-n9K+p|$>=kT#DSs~dC=@(_!umNZ8&2K$?)oV7o&k4UmK>;) z(ON!(BFsrsi|-Ux(ji)piDo-NotohRoJwYBU!6Dn;9P0-NSsn2i8lr7rN{H!rCIuE z`txI;sy*~Cz`1{y;?5y`aV`cWup=~cOU@P! zd)79ferBfJcV8~5TAfFj=UT}PynlB#eVB*IU@+>&n0;we!ej*o6k2|ng)^M!)Ulk~ z^nlRPTFvgmR8?3^;8?WwSU9M5bsQ6gI22m4aZ%uN_*+wyI_e3kkUs^b|K(i&F1u7<_vS8GBXnz)p+ZN>P zuRs2LjT7T|BmZsAeG}6Z#6K}h$v7#Z)jDrmL1Rja@glrP1~aE3Q=o=C@xzJKoEjh> z65BbGd7S*WY3etf%!#r6_)jwy`Do=Z9+~7|dKKi#nY?Bo6AwJ=m!W<*i9IawjC>?b zle{g>zgxN01P`e%wB-MgUS{`4bYZYT`3kN@FARkd; zQ6ibMx$I$h*LyU^FAFYrJ6w}%rtq7J6n#5BmkN9{T(G*fFK!OyH!!wGZwKjM-6I-5 zyX*Y^RU<#VZPN%p-Lk&{lc56?vp^4z3=ZD~J^b|u001N@000;OlaMYNf1Fy|lHxWH zeNR>Xf%5wTzF-d&kQyL>tCGrAb~kzU7z3^WOl;52PQE@ZsclOw+t_&-Jnf@a>qvc( ztobiLu9w00D9z&JwlK`$*ce2&Fge7x)57@nb^Gbb7-V^HI|P^H7A=gAC^LRp{`}MY zJxO1)a}?zR&~VEZ#yQXLf3wjj3(wIt$cD*1y1|=cl3s%x{!LG#?4Cx!fj7EdM%H-j zj;=v`GlYg&+C@ilJjP+PNy4{lbjyX3G`a*i*q@!_dsb+>hF#QMgY@<7{wYkZcTn*X zU*i0OD>Vk!aOR(GNgBLdVB9}UCkPAO{2xvIH4f7xOOE*v)QyCpfBKlGqv;4VE$5tv z&*^f04^GjSDF1f3NU`FJGcd6z0)^sT#29dP$O32J}HRW)^S&QyGML{5@Jnm&?M~O<>0V;hn%^X#;Cm z*dzD06WpGgG#-uqFJy<9l~#I%Ai$dx^4q8#7y4 zb=ar_eo@D?RFUN$Yyqg9I@kbyi%x4=bnPAt<%5S`)HWVIe@!Ni`{cEc-NlCRiw!NH zp@l3D8^G`XCJQ10w-$c8ku}8z@LO~$&uvNY1G+|H$?)~Q3G!e$Pm}inL=BkR>>jWf zWX_-uw)9}}u<6gwarnAQ#QfJRMSB8n5HcOlObIA}2?cZp;_pk(osYi5nhz1PDly;{ zywzHhY&6NQf0|^gNp_lKuStAaGJ>I(xtK*jmiNmZO`>qGD>TXU`UsKz$gZYY;Rf@cv( zjvU5K5@Xf~m)Rk%xT%2kP|^_MmOj1{5``i%e;IoLktrf-eI4Oei&>!vYNPHHF|bMz zNE+kA8sTkThY&eOdStj;#7Gzhp-hSsTwf$e=!t?Zbns(h(~77bbgsE-&qc}<#Jlob6B$ikvoCQFDE zvS>kS3QS9K+90GMs)#ZRG0Hlh5Po(De`?K@HTF!1zxXv6yP-N|8{HmZPL#dMf)gTz zLlUFbypx5YL}prx)nF`I*dqo=tQMT!{X}z7fobdBuj$^cx>tRa6}X*C40ia%c9rt7 z6C#B&60z6VOtG03Xo%^Q&3aYZY?V@*g{Uq6uCZBL0^T5|lg+*AUv_Ficb*Pee~2sP zXv5NSvR?7pB+YD!Zln#lsKK~RfuL7a z2s>2GS`^7;k4?87MLRjA(miW|kp|{9Pz+wx!xcGNEz+2%xtJ{)v{kb;n5NyX)vGe% zXkx8Qn@N{%(V(rQtiuo|*#o8sf3LoHR!2opVd+HsvRs*1gKRiJrzcf93pKR))CX132QJeO=*CsM#rDk(e=vemdKA%T3w+? z84LAg#I%-?H5gZ0Z;mt;{;ZCrSGr}V{cOEeCBh0t^3I-a9oL9awzf3ge%-iEP zEq0FPi)VE#z0$B%9zIq6;%MjbvOPA5rRzdPYXs8|tz6Q}9`sb}jX$g7>XoW3{j91G zwI+`Oq(nh&mh>d<(tQXhsz$?~)zS1y+?JlWnW!bgbvQ;srCoMGRtrpcNYK>TkY1_*oq)UBj_e$p+O-vSF@>*+ZY}Q&+ zBc_why^^<$$y@H-p^Jrq%Ej)`W0^vQgrW6b4a95M@!N9N2Hx6t{2a|cMwMSvn5Z&V z`*??GUdCvj?{tjUaF}DuS@^NFn1!p;loeA@SxfUTSIawlbv$%Oh z-&ixa0a2sNn!){r8o4ur&x|#4ZwB8%bosM0dxrD)nir-CZ|YP%o8IhM?1(gDU3kMU zkZEshc*AE^dozWhi+gDm@o<4Hjc@rMcYXzLa7yFDZ}BZ+f5kYnmECUpJxEXSEgM{- zBh1iv2mvD%SH$>p&hDu2rP(P*6jKa7>b1JfcRpFZXsIWMROrW_eHv zC20)T%lI|Gg>g^PJPqO;?gD}Q-vnM) z2Qk3%e&g~#lkpZ61z9{9NMo}~B_;uXT}#6-7=`Zz|3k@*S8dwPZX>iEsO(0E11pMm zA$hxnwP{JB-Tu8IChLsR_oK?V+UFvkqy+yiz59HTJ1? zxTfqtcYs6RpW_k?<hq6Khg!I~oOR;pK58)Ha=JbdEw`YiLm5>H_8v4P)^&{6`WWk(73*tv_G46AN z$(Cw2=$Zj{>{X=OU{GFWw|ChZ^}K7>pJl<4L?H?1miHrnzOn Date: Sun, 7 May 2017 14:22:32 -0700 Subject: [PATCH 18/20] Revisions to wiring diagram --- doc/wiring.xlsx | Bin 12178 -> 133644 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/wiring.xlsx b/doc/wiring.xlsx index fd963fca2b70efcef8ece615916656401dcc8ee9..1a08e240b22776b404811fa5854a55e20dd7d910 100644 GIT binary patch literal 133644 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