mdf.F90 1.2 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127
  1. !#######################################################################
  2. !
  3. ! MDF - Multiple Data Format
  4. !
  5. ! NAME
  6. ! MDF - generic interface to a number of scientific data formats
  7. !
  8. !
  9. ! BACKGROUND
  10. !
  11. ! Single interface to multipe file formats.
  12. ! From 'multiple' it should evolve into 'many' and preferably 'most'.
  13. !
  14. ! This module is intended to replace an older f90 interface to HDF4
  15. ! called 'file_hdf'.
  16. !
  17. ! Creation of file follows the steps similar to writing a NetCDF file:
  18. ! o opening of the file
  19. ! o (global attributes)
  20. ! o definition of dimensions (plus attributes)
  21. ! o definition of variables (plus attributes)
  22. ! o end of definition phase
  23. ! o write one or more time records
  24. ! o close file
  25. !
  26. !
  27. ! PROCEDURES
  28. !
  29. ! !
  30. ! ! module initialisation
  31. ! !
  32. !
  33. ! subroutine MDF_Init( status )
  34. ! integer, intent(out) :: status
  35. !
  36. ! !
  37. ! ! write data
  38. ! !
  39. !
  40. ! ! create a new file for output:
  41. ! subroutine MDF_Create( filename, ftype, cmode, hid, status )
  42. ! character(len=*), intent(in) :: filename
  43. ! integer, intent(in) :: ftype
  44. ! integer, intent(in) :: cmode
  45. ! integer, intent(out) :: hid
  46. ! integer, intent(out) :: status
  47. !
  48. ! ! ... or create more than one with different formats;
  49. ! ! specify a single base name and an equal number of extensions and type:
  50. ! subroutine MDF_Create( basename, exts, ftypes, cmode, hid, status )
  51. ! character(len=*), intent(in) :: basename
  52. ! character(len=*), intent(in) :: exts(:)
  53. ! integer, intent(in) :: ftypes(:)
  54. ! integer, intent(in) :: cmode
  55. ! integer, intent(out) :: hid
  56. ! integer, intent(out) :: status
  57. !
  58. ! subroutine MDF_Def_Dim( hid, name, length, dimid, status )
  59. ! integer, intent(in) :: hid
  60. ! character(len=*), intent(in) :: name
  61. ! integer, intent(in) :: length
  62. ! integer, intent(out) :: dimid
  63. ! integer, intent(out) :: status
  64. !
  65. ! subroutine MDF_Def_Var( hid, name, xtype, dimids, varid, status, &
  66. ! compression, deflate_level )
  67. ! integer, intent(in) :: hid
  68. ! character(len=*), intent(in) :: name
  69. ! integer, intent(in) :: xtype
  70. ! integer, intent(in) :: dimids(:)
  71. ! integer, intent(out) :: varid
  72. ! integer, intent(out) :: status
  73. ! integer, intent(in), optional :: compression
  74. ! integer, intent(in), optional :: deflate_level ! 0-9
  75. !
  76. ! subroutine MDF_Put_Att( hid, varid, name, values, status )
  77. ! integer, intent(in) :: hid
  78. ! integer, intent(in) :: varid
  79. ! character(len=*), intent(in) :: name
  80. ! <type>, intent(in) :: value(s)
  81. ! integer, intent(out) :: status
  82. !
  83. ! subroutine MDF_EndDef( hid, status )
  84. ! integer, intent(in) :: hid
  85. ! integer, intent(out) :: status
  86. !
  87. ! ! put variable:
  88. ! subroutine MDF_Put_Var( hid, varid, values, status, &
  89. ! start, count, stride, map )
  90. ! integer, intent(in) :: hid
  91. ! integer, intent(in) :: varid
  92. ! <type>, intent(in) :: values(<shape>)
  93. ! integer, intent(out) :: status
  94. ! integer, intent(in), optional :: start(:) ! (/1,1,..,1/)
  95. ! integer, intent(in), optional :: count(:)
  96. ! integer, intent(in), optional :: stride(:)
  97. ! integer, intent(in), optional :: map(:)
  98. !
  99. ! ! close file(s):
  100. ! subroutine MDF_Close( hid, status )
  101. ! integer, intent(out) :: hid
  102. ! integer, intent(out) :: status
  103. !
  104. ! !
  105. ! ! read file
  106. ! !
  107. !
  108. ! ! open single file:
  109. ! subroutine MDF_Open( filename, ftype, mode, hid, status )
  110. ! character(len=*), intent(in) :: filename
  111. ! integer, intent(in) :: ftype
  112. ! integer, intent(in) :: mode
  113. ! integer, intent(out) :: hid
  114. ! integer, intent(out) :: status
  115. !
  116. ! subroutine MDF_Inquire( hid, status, &
  117. ! nDimensions, nVariables, nAttributes )
  118. ! integer, intent(in) :: hid
  119. ! integer, intent(out) :: status
  120. ! integer, intent(out), optional :: nDimensions
  121. ! integer, intent(out), optional :: nVariables
  122. ! integer, intent(out), optional :: nAttributes
  123. !
  124. ! subroutine MDF_Inq_DimID( hid, name, dimid, status )
  125. ! integer, intent(in) :: hid
  126. ! character(len=*), intent(in) :: name
  127. ! integer, intent(out) :: dimid
  128. ! integer, intent(out) :: status
  129. !
  130. ! subroutine MDF_Inquire_Dimension( hid, dimid, status, name, length, unlimited )
  131. ! integer, intent(in) :: hid
  132. ! integer, intent(in) :: dimid
  133. ! integer, intent(out) :: status
  134. ! character(len=*), intent(out), optional :: name
  135. ! integer, intent(out), optional :: length
  136. ! logical, intent(out), optional :: unlimited
  137. !
  138. ! subroutine MDF_Inq_VarID( hid, name, varid, status )
  139. ! integer, intent(in) :: hid
  140. ! character(len=*), intent(in) :: name
  141. ! integer, intent(out) :: varid
  142. ! integer, intent(out) :: status
  143. !
  144. ! subroutine MDF_Inquire_Variable( hid, varid, status, &
  145. ! name, xtype, ndims, dimids, natts )
  146. ! integer, intent(in) :: hid
  147. ! integer, intent(in) :: varid
  148. ! integer, intent(out) :: status
  149. ! character(len=*), intent(out), optional :: name
  150. ! integer, intent(out), optional :: xtype
  151. ! integer, intent(out), optional :: ndims
  152. ! integer, intent(out), optional :: dimids(:)
  153. ! integer, intent(out), optional :: natts
  154. !
  155. ! subroutine MDF_Get_Var( hid, varid, values, status, &
  156. ! start, count, stride, map )
  157. ! integer, intent(in) :: hid
  158. ! integer, intent(in) :: varid
  159. ! <type>, intent(out) :: values(<shape>)
  160. ! integer, intent(out) :: status
  161. ! integer, intent(in), optional :: start (:)
  162. ! integer, intent(in), optional :: count (:)
  163. ! integer, intent(in), optional :: stride(:)
  164. ! integer, intent(in), optional :: map (:)
  165. !
  166. ! subroutine MDF_Inq_AttName( hid, varid, attnum, name, status )
  167. ! integer, intent(in) :: hid
  168. ! integer, intent(in) :: varid
  169. ! integer, intent(in) :: attnum
  170. ! character(len=*), intent(out) :: name
  171. ! integer, intent(out) :: status
  172. !
  173. ! subroutine MDF_Inquire_Attribute( hid, varid, name, status, xtype, length )
  174. ! integer, intent(in) :: hid
  175. ! integer, intent(in) :: varid
  176. ! character(len=*), intent(out) :: name
  177. ! integer, intent(out) :: status
  178. ! integer, intent(out), optional :: xtype
  179. ! integer, intent(out), optional :: length
  180. !
  181. ! subroutine MDF_Get_Att( hid, varid, name, values, status )
  182. ! integer, intent(in) :: hid
  183. ! integer, intent(in) :: varid
  184. ! character(len=*), intent(in) :: name
  185. ! <type>, intent(out) :: value(s)
  186. ! integer, intent(out) :: status
  187. !
  188. ! ! close file:
  189. ! subroutine MDF_Close( hid, status )
  190. ! integer, intent(out) :: hid
  191. ! integer, intent(out) :: status
  192. !
  193. ! !
  194. ! ! parallel access
  195. ! !
  196. !
  197. ! ! create a new file for output:
  198. ! subroutine MDF_Create( filename, ftype, cmode, hid, status, &
  199. ! mpi_comm=comm, mpi_info=MPI_INFO_NULL )
  200. ! character(len=*), intent(in) :: filename
  201. ! integer, intent(in) :: cmode
  202. ! integer, intent(out) :: hid
  203. ! integer, intent(out) :: status
  204. ! integer, intent(in), optional :: mpi_comm
  205. ! integer, intent(in), optional :: mpi_info
  206. !
  207. ! ! ... or create more than one with different formats;
  208. ! ! specify a single base name and an equal number of extensions and type:
  209. ! subroutine MDF_Create( basename, exts, ftypes, cmode, hid, status, &
  210. ! mpi_comm=comm, mpi_info=MPI_INFO_NULL )
  211. ! character(len=*), intent(in) :: basename
  212. ! character(len=*), intent(in) :: exts(:)
  213. ! integer, intent(in) :: ftypes(:)
  214. ! integer, intent(in) :: cmode
  215. ! integer, intent(out) :: hid
  216. ! integer, intent(out) :: status
  217. ! integer, intent(in), optional :: mpi_comm
  218. ! integer, intent(in), optional :: mpi_info
  219. !
  220. ! ! open single file:
  221. ! subroutine MDF_Open( filename, ftype, mode, hid, status, &
  222. ! mpi_comm=comm, mpi_info=MPI_INFO_NULL )
  223. ! character(len=*), intent(in) :: filename
  224. ! integer, intent(in) :: ftype
  225. ! integer, intent(in) :: mode
  226. ! integer, intent(out) :: hid
  227. ! integer, intent(out) :: status
  228. ! integer, intent(in), optional :: mpi_comm
  229. ! integer, intent(in), optional :: mpi_info
  230. !
  231. ! ! parallel access mode (see NetCDF4 manual):
  232. ! subroutine MDF_Var_Par_Access( hid, varid, par_access_mode, status )
  233. ! integer, intent(in) :: hid
  234. ! integer, intent(out) :: varid
  235. ! integer, intent(in) :: par_access_mode
  236. ! integer, intent(out) :: status
  237. !
  238. ! !
  239. ! ! show file content
  240. ! !
  241. !
  242. ! ! show file headers similar to 'ncdump -h' ;
  243. ! ! file type is guessed from extension if not specified directly:
  244. ! subroutine MDF_Show( filename, status [,filetype=MDF_NETCDF4|MDF_HDF|...] )
  245. ! character(len=*), intent(in) :: filename
  246. ! integer, intent(out) :: status
  247. ! integer, intent(in), optional :: filetype
  248. ! integer, intent(out) :: status
  249. !
  250. ! !
  251. ! ! end module access
  252. ! !
  253. !
  254. ! ! done with module:
  255. ! subroutine MDF_Done( status )
  256. ! integer, intent(out) :: status
  257. !
  258. !
  259. ! CREATION AND OPEN MODES
  260. !
  261. ! MDF_NEW : new file, error if already present
  262. ! MDF_REPLACE : new file, overwrite older file if necessary
  263. ! MDF_READ : open existing file for reading
  264. ! MDF_WRITE : open existing file for writing
  265. !
  266. !
  267. ! FILE TYPES
  268. !
  269. ! MDF_HDF4 : HDF4
  270. ! MDF_NETCDF : NetCDF (clasical format ; via NetCDF-3 or NetCDF-4 library)
  271. ! MDF_NETCDF4 : NetCDF4 (HDF5 format ; via NetCDF-4 library with NetCDF-4 features enabled;
  272. ! requires linking with HDF5 library too)
  273. !
  274. !
  275. ! GLOBAL ATTRIBUTES
  276. !
  277. ! To write global attributes, use the constant 'MDF_GLOBAL' as variable id.
  278. !
  279. !
  280. ! UNLIMITED DIMENSION
  281. !
  282. ! To define an unlimited dimension, use the constant 'MDF_UNLIMITED'
  283. ! as dimension length.
  284. !
  285. !
  286. ! DATA TYPES
  287. !
  288. ! MDF_CHAR
  289. ! MDF_BYTE
  290. ! MDF_SHORT
  291. ! MDF_INT
  292. ! MDF_INT64
  293. ! MDF_FLOAT
  294. ! MDF_DOUBLE
  295. !
  296. !
  297. ! PARALLEL ACCESS MODES
  298. !
  299. ! MDF_INDEPENDENT ! independent data mode (one processor at a time can read/write)
  300. ! MDF_COLLECTIVE ! collective data mode (several processors can do I/O simultaneously )
  301. !
  302. !
  303. ! FPP MACRO'S
  304. !
  305. ! The following fpp macro's might be defined to compile only certain parts of the code:
  306. !
  307. ! with_hdf4 : compile with calls to HDF (=HDF4) library
  308. ! with_netcdf : compile with calls to NetCDF library
  309. ! with_netcdf4 : compile with calls to NetCDF-4 library with NetCDF-4 features enabled;
  310. ! automatically defines 'with_netcdf'
  311. ! with_netcdf4_par : compile with calls to NetCDF-4 library with NetCDF-4 and parallel
  312. ! features enabled; automatically defines 'with_netcdf4'
  313. !
  314. ! with_go : GO module is availble.
  315. ! If this macro is not set, the required parts of GO are simulated.
  316. !
  317. !
  318. ! PARALLEL I/O FOR DIFFERENT NETCDF4 VERSIONS
  319. !
  320. ! From NetCDF version 4.1.1 onwards it is necessary to use a special creation mode
  321. ! named 'MPIIO' to open a file for parallel I/O :
  322. !
  323. ! status = NF90_Create( 'test.nc', NF90_NETCDF4+NF90_MPIIO, ncid,&
  324. ! comm=MPI_COMM_WORLD, info=MPI_INFO_NULL )
  325. !
  326. !
  327. !### macro's ###########################################################
  328. !
  329. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
  330. !
  331. #define IF_NOT_OK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  332. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  333. !
  334. #define IF_NF90_NOT_OK_RETURN(action) if (status/=NF90_NOERR) then; gol=NF90_StrError(status); call goErr; TRACEBACK; action; return; end if
  335. !
  336. ! macro's:
  337. #include "mdf.inc"
  338. !
  339. !#######################################################################
  340. ! netcdf4_par interface includes netcdf4 ...
  341. #ifdef with_netcdf4_par
  342. #define with_netcdf4
  343. #endif
  344. ! netcdf4 interface includes netcdf3 ...
  345. #ifdef with_netcdf4
  346. #define with_netcdf
  347. #endif
  348. module MDF
  349. #ifdef with_go
  350. use GO, only : gol, goPr, goErr
  351. #endif
  352. #ifdef with_hdf5_beta
  353. use HDF5, only : HID_T, HSIZE_T
  354. #endif
  355. #ifdef with_netcdf
  356. use NETCDF, only : NF90_NOERR, NF90_StrError
  357. #endif
  358. implicit none
  359. ! --- in/out ---------------------------------------
  360. private
  361. public :: MDF_Init, MDF_Done
  362. public :: MDF_Create, MDF_Open, MDF_Close
  363. public :: MDF_EndDef
  364. public :: MDF_Inquire
  365. public :: MDF_Def_Dim
  366. public :: MDF_Inq_DimID
  367. public :: MDF_Inquire_Dimension
  368. public :: MDF_Def_Var
  369. public :: MDF_Var_Par_Access
  370. public :: MDF_Inq_VarID
  371. public :: MDF_Inquire_Variable
  372. public :: MDF_Put_Var
  373. public :: MDF_Get_Var
  374. public :: MDF_Put_Att
  375. public :: MDF_Get_Att
  376. public :: MDF_Show
  377. public :: MDF_NONE
  378. public :: MDF_NEW
  379. public :: MDF_REPLACE
  380. public :: MDF_READ
  381. public :: MDF_WRITE
  382. public :: MDF_HDF4
  383. public :: MDF_HDF5
  384. public :: MDF_NETCDF
  385. public :: MDF_NETCDF4
  386. public :: MDF_CHAR
  387. public :: MDF_BYTE
  388. public :: MDF_SHORT
  389. public :: MDF_INT
  390. public :: MDF_INT64
  391. public :: MDF_FLOAT
  392. public :: MDF_DOUBLE
  393. public :: MDF_DATATYPE_NAME
  394. public :: MDF_DEFLATE
  395. public :: MDF_INDEPENDENT, MDF_COLLECTIVE
  396. public :: MDF_GLOBAL
  397. public :: MDF_UNLIMITED
  398. ! --- const ----------------------------------------
  399. character(len=*), parameter :: mname = 'MDF'
  400. !
  401. ! creation modes
  402. !
  403. integer, parameter :: MDF_NEW = 1
  404. integer, parameter :: MDF_REPLACE = 2
  405. integer, parameter :: MDF_READ = 3
  406. integer, parameter :: MDF_WRITE = 4
  407. !
  408. integer, parameter :: MDF_CMODE_MAX = MDF_WRITE
  409. character(len=*), parameter :: MDF_CMODE_NAME(1:MDF_CMODE_MAX) = &
  410. (/ 'new ', 'replace', 'read ', 'write ' /)
  411. !
  412. ! file types
  413. !
  414. integer, parameter :: MDF_HDF4 = 1
  415. integer, parameter :: MDF_HDF5 = 2
  416. integer, parameter :: MDF_NETCDF = 3
  417. integer, parameter :: MDF_NETCDF4 = 4
  418. !
  419. integer, parameter :: MDF_FILETYPE_MAX = MDF_NETCDF4
  420. character(len=*), parameter :: MDF_FILETYPE_NAME(1:MDF_FILETYPE_MAX) = &
  421. (/ 'HDF4 ', 'HDF5 ', 'NetCDF ', 'NetCDF4' /)
  422. !
  423. ! data types
  424. !
  425. integer, parameter :: MDF_CHAR = 1 ! character
  426. integer, parameter :: MDF_BYTE = 2 ! integer(1)
  427. integer, parameter :: MDF_SHORT = 3 ! integer(2)
  428. integer, parameter :: MDF_INT = 4 ! integer(4)
  429. integer, parameter :: MDF_FLOAT = 5 ! real(4)
  430. integer, parameter :: MDF_DOUBLE = 6 ! real(8)
  431. integer, parameter :: MDF_INT64 = 7 ! INT64
  432. !
  433. integer, parameter :: MDF_DATATYPE_MAX = MDF_DOUBLE
  434. character(len=*), parameter :: MDF_DATATYPE_NAME(1:MDF_DATATYPE_MAX) = &
  435. (/ 'char ','byte ','short ','int ','float ', 'double' /)
  436. !
  437. ! compression
  438. !
  439. integer, parameter :: MDF_DEFLATE = 1
  440. !
  441. integer, parameter :: MDF_COMPRESSION_MAX = MDF_DEFLATE
  442. character(len=*), parameter :: MDF_COMPRESSION_NAME(1:MDF_COMPRESSION_MAX) = &
  443. (/ 'deflate' /)
  444. !
  445. ! parallel access
  446. !
  447. integer, parameter :: MDF_INDEPENDENT = 1
  448. integer, parameter :: MDF_COLLECTIVE = 2
  449. !
  450. integer, parameter :: MDF_PARALLEL_ACCESS_MAX = MDF_INDEPENDENT
  451. character(len=*), parameter :: MDF_PARALLEL_ACCESS_NAME(1:MDF_PARALLEL_ACCESS_MAX) = &
  452. (/ 'independent' /)
  453. !
  454. ! special parameters
  455. !
  456. ! dummy ...
  457. integer, parameter :: MDF_NONE = -100
  458. ! special 'variable id' to add global attributes:
  459. integer, parameter :: MDF_GLOBAL = -101
  460. ! special dimension 'length' to denote unlimited dimension:
  461. integer, parameter :: MDF_UNLIMITED = -102
  462. #ifdef with_hdf4
  463. !
  464. ! hdf4 parameters
  465. !
  466. ! library constants constants
  467. include "hdf.f90"
  468. ! working precision of hdf library, used for handles:
  469. integer, parameter :: hdf4_wpi = 4
  470. #endif
  471. !
  472. ! internal
  473. !
  474. ! maximum rank of Fortran arrays:
  475. integer, parameter :: MAX_RANK = 7
  476. ! maximum length for variable names etc:
  477. integer, parameter :: LEN_NAME = 64
  478. integer, parameter :: LEN_FILE = 512
  479. integer, parameter :: LEN_LINE = 4000
  480. ! --- types ----------------------------------------
  481. ! interface to MDF dimension
  482. type MDF_Dim
  483. ! standard fields:
  484. character(len=LEN_NAME) :: name
  485. integer :: length
  486. logical :: unlimited
  487. logical :: named
  488. ! dimension id's
  489. #ifdef with_netcdf
  490. integer :: netcdf_dimid
  491. #endif
  492. end type MDF_Dim
  493. ! Define a structure with a pointer to the type;
  494. ! this is necessary to create a list of pointers:
  495. type P_MDF_Dim
  496. type(MDF_Dim), pointer :: p
  497. end type P_MDF_Dim
  498. ! define storage type for list with pointers:
  499. type MDF_Dim_List
  500. ! array of pointers; flexible size, increased if necessary
  501. type(P_MDF_Dim), pointer :: item(:)
  502. ! maximum number of filled items:
  503. integer :: maxitem
  504. ! actual number of filled items:
  505. integer :: nitem
  506. end type MDF_Dim_List
  507. ! interface to MDF variable
  508. type MDF_Var
  509. ! standard fields:
  510. character(len=LEN_NAME) :: name
  511. integer :: xtype
  512. integer :: xkind
  513. integer :: ndim
  514. integer :: dimids(MAX_RANK)
  515. integer :: shp(MAX_RANK)
  516. integer :: natt
  517. #ifdef with_hdf4
  518. integer :: hdf4_sdid
  519. integer :: hdf4_xtype
  520. #endif
  521. #ifdef with_hdf5_beta
  522. integer(HID_T) :: hdf5_dataset_id
  523. character(len=LEN_NAME) :: hdf5_name
  524. integer(HSIZE_T) :: hdf5_dims (MAX_RANK)
  525. integer(HSIZE_T) :: hdf5_maxdims (MAX_RANK)
  526. integer(HSIZE_T) :: hdf5_chunkdims(MAX_RANK)
  527. logical :: hdf5_chunked
  528. #endif
  529. #ifdef with_netcdf
  530. integer :: netcdf_varid
  531. #endif
  532. end type MDF_Var
  533. ! Define a structure with a pointer to the type;
  534. ! this is necessary to create a list of pointers:
  535. type P_MDF_Var
  536. type(MDF_Var), pointer :: p
  537. end type P_MDF_Var
  538. ! define storage type for list with pointers:
  539. type MDF_Var_List
  540. ! array of pointers; flexible size, increased if necessary
  541. type(P_MDF_Var), pointer :: item(:)
  542. ! maximum number of filled items:
  543. integer :: maxitem
  544. ! actual number of filled items:
  545. integer :: nitem
  546. end type MDF_Var_List
  547. ! interface to io file
  548. type MDF_File
  549. ! name of the file or basename of multiple files:
  550. character(len=LEN_FILE) :: filename
  551. ! creation mode:
  552. integer :: cmode
  553. ! parallel i/o ?
  554. logical :: parallel
  555. ! dimensions:
  556. type(MDF_Dim_List) :: Dim_List
  557. ! variables:
  558. type(MDF_Var_List) :: Var_List
  559. ! number of global attributes:
  560. integer :: natt
  561. ! file types:
  562. integer :: nftype
  563. integer :: ftypes(1:MDF_FILETYPE_MAX)
  564. ! access to file types:
  565. #ifdef with_hdf4
  566. character(len=LEN_FILE) :: hdf4_fname
  567. integer :: hdf4_id
  568. #endif
  569. #ifdef with_hdf5_beta
  570. character(len=LEN_FILE) :: hdf5_fname
  571. integer(HID_T) :: hdf5_file_id
  572. #endif
  573. #ifdef with_netcdf
  574. character(len=LEN_FILE) :: netcdf_fname
  575. integer :: netcdf_id
  576. #endif
  577. end type MDF_File
  578. ! Define a structure with a pointer to the type;
  579. ! this is necessary to create a list of pointers:
  580. type P_MDF_File
  581. type(MDF_File), pointer :: p
  582. end type P_MDF_File
  583. ! define storage type for list with pointers:
  584. type MDF_File_List
  585. ! array of pointers; flexible size, increased if necessary
  586. type(P_MDF_File), pointer :: item(:)
  587. ! maximum number of filled items:
  588. integer :: maxitem
  589. ! actual number of filled items:
  590. integer :: nitem
  591. end type MDF_File_List
  592. ! --- interfaces -----------------------------------
  593. interface MDF_Create
  594. module procedure MDF_Create_one
  595. module procedure MDF_Create_more
  596. end interface MDF_Create
  597. interface MDF_Put_Var
  598. module procedure MDF_Put_Var_c1_1d
  599. module procedure MDF_Put_Var_c1_2d
  600. module procedure MDF_Put_Var_c1_3d
  601. module procedure MDF_Put_Var_c1_4d
  602. module procedure MDF_Put_Var_c1_5d
  603. module procedure MDF_Put_Var_c1_6d
  604. module procedure MDF_Put_Var_c1_7d
  605. !
  606. module procedure MDF_Put_Var_i1_1d
  607. module procedure MDF_Put_Var_i1_2d
  608. module procedure MDF_Put_Var_i1_3d
  609. module procedure MDF_Put_Var_i1_4d
  610. module procedure MDF_Put_Var_i1_5d
  611. module procedure MDF_Put_Var_i1_6d
  612. module procedure MDF_Put_Var_i1_7d
  613. !
  614. module procedure MDF_Put_Var_i2_1d
  615. module procedure MDF_Put_Var_i2_2d
  616. module procedure MDF_Put_Var_i2_3d
  617. module procedure MDF_Put_Var_i2_4d
  618. module procedure MDF_Put_Var_i2_5d
  619. module procedure MDF_Put_Var_i2_6d
  620. module procedure MDF_Put_Var_i2_7d
  621. !
  622. module procedure MDF_Put_Var_i4_1d
  623. module procedure MDF_Put_Var_i4_2d
  624. module procedure MDF_Put_Var_i4_3d
  625. module procedure MDF_Put_Var_i4_4d
  626. module procedure MDF_Put_Var_i4_5d
  627. module procedure MDF_Put_Var_i4_6d
  628. module procedure MDF_Put_Var_i4_7d
  629. !
  630. module procedure MDF_Put_Var_r4_1d
  631. module procedure MDF_Put_Var_r4_2d
  632. module procedure MDF_Put_Var_r4_3d
  633. module procedure MDF_Put_Var_r4_4d
  634. module procedure MDF_Put_Var_r4_5d
  635. module procedure MDF_Put_Var_r4_6d
  636. module procedure MDF_Put_Var_r4_7d
  637. !
  638. module procedure MDF_Put_Var_r8_1d
  639. module procedure MDF_Put_Var_r8_2d
  640. module procedure MDF_Put_Var_r8_3d
  641. module procedure MDF_Put_Var_r8_4d
  642. module procedure MDF_Put_Var_r8_5d
  643. module procedure MDF_Put_Var_r8_6d
  644. module procedure MDF_Put_Var_r8_7d
  645. end interface
  646. interface MDF_Get_Var
  647. module procedure MDF_Get_Var_c1_1d
  648. module procedure MDF_Get_Var_c1_2d
  649. module procedure MDF_Get_Var_c1_3d
  650. module procedure MDF_Get_Var_c1_4d
  651. module procedure MDF_Get_Var_c1_5d
  652. module procedure MDF_Get_Var_c1_6d
  653. module procedure MDF_Get_Var_c1_7d
  654. !
  655. module procedure MDF_Get_Var_i1_1d
  656. module procedure MDF_Get_Var_i1_2d
  657. module procedure MDF_Get_Var_i1_3d
  658. module procedure MDF_Get_Var_i1_4d
  659. module procedure MDF_Get_Var_i1_5d
  660. module procedure MDF_Get_Var_i1_6d
  661. module procedure MDF_Get_Var_i1_7d
  662. !
  663. module procedure MDF_Get_Var_i2_1d
  664. module procedure MDF_Get_Var_i2_2d
  665. module procedure MDF_Get_Var_i2_3d
  666. module procedure MDF_Get_Var_i2_4d
  667. module procedure MDF_Get_Var_i2_5d
  668. module procedure MDF_Get_Var_i2_6d
  669. module procedure MDF_Get_Var_i2_7d
  670. !
  671. module procedure MDF_Get_Var_i4_1d
  672. module procedure MDF_Get_Var_i4_2d
  673. module procedure MDF_Get_Var_i4_3d
  674. module procedure MDF_Get_Var_i4_4d
  675. module procedure MDF_Get_Var_i4_5d
  676. module procedure MDF_Get_Var_i4_6d
  677. module procedure MDF_Get_Var_i4_7d
  678. !
  679. module procedure MDF_Get_Var_r4_1d
  680. module procedure MDF_Get_Var_r4_2d
  681. module procedure MDF_Get_Var_r4_3d
  682. module procedure MDF_Get_Var_r4_4d
  683. module procedure MDF_Get_Var_r4_5d
  684. module procedure MDF_Get_Var_r4_6d
  685. module procedure MDF_Get_Var_r4_7d
  686. !
  687. module procedure MDF_Get_Var_r8_1d
  688. module procedure MDF_Get_Var_r8_2d
  689. module procedure MDF_Get_Var_r8_3d
  690. module procedure MDF_Get_Var_r8_4d
  691. module procedure MDF_Get_Var_r8_5d
  692. module procedure MDF_Get_Var_r8_6d
  693. module procedure MDF_Get_Var_r8_7d
  694. end interface
  695. interface MDF_Put_Att
  696. module procedure MDF_Put_Att_c1_0d
  697. module procedure MDF_Put_Att_i1_0d
  698. module procedure MDF_Put_Att_i1_1d
  699. module procedure MDF_Put_Att_i2_0d
  700. module procedure MDF_Put_Att_i2_1d
  701. module procedure MDF_Put_Att_i4_0d
  702. module procedure MDF_Put_Att_i4_1d
  703. module procedure MDF_Put_Att_r4_0d
  704. module procedure MDF_Put_Att_r4_1d
  705. module procedure MDF_Put_Att_r8_0d
  706. module procedure MDF_Put_Att_r8_1d
  707. end interface
  708. interface MDF_Get_Att
  709. module procedure MDF_Get_Att_c1_0d
  710. module procedure MDF_Get_Att_i1_0d
  711. module procedure MDF_Get_Att_i1_1d
  712. module procedure MDF_Get_Att_i2_0d
  713. module procedure MDF_Get_Att_i2_1d
  714. module procedure MDF_Get_Att_i4_0d
  715. module procedure MDF_Get_Att_i4_1d
  716. module procedure MDF_Get_Att_r4_0d
  717. module procedure MDF_Get_Att_r4_1d
  718. module procedure MDF_Get_Att_r8_0d
  719. module procedure MDF_Get_Att_r8_1d
  720. end interface
  721. ! --- var ------------------------------------------
  722. #ifndef with_go
  723. ! message line:
  724. character(len=1024) :: gol
  725. #endif
  726. ! define lists:
  727. type(MDF_File_List) :: File_List
  728. contains
  729. #ifndef with_go
  730. ! ********************************************************************
  731. ! ***
  732. ! *** GO surrogate
  733. ! ***
  734. ! ********************************************************************
  735. ! substitutes for message routines from GO modules
  736. ! display message:
  737. subroutine goPr
  738. write (*,'(a)') trim(gol)
  739. end subroutine goPr
  740. ! display error message:
  741. subroutine goErr
  742. write (*,'("ERROR - ",a)') trim(gol)
  743. end subroutine goErr
  744. ! free file unit:
  745. subroutine goGetFU( fu, status )
  746. integer, intent(out) :: fu
  747. integer, intent(out) :: status
  748. logical :: opened
  749. fu = 456
  750. do
  751. inquire( unit=fu, opened=opened )
  752. if ( .not. opened ) exit
  753. fu = fu + 1
  754. end do
  755. status = 0
  756. end subroutine goGetFU
  757. #endif
  758. ! ********************************************************************
  759. ! ***
  760. ! *** MDF_Dim procedures
  761. ! ***
  762. ! ********************************************************************
  763. !
  764. ! Initialise a list.
  765. !
  766. subroutine MDF_Dim_List_Init( list, status )
  767. ! --- in/out -------------------------------------
  768. type(MDF_Dim_List), intent(out) :: list
  769. integer, intent(out) :: status
  770. ! --- const --------------------------------------
  771. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_Init'
  772. ! --- begin --------------------------------------
  773. ! empty list:
  774. nullify( list%item )
  775. ! set counters:
  776. list%maxitem = 0
  777. list%nitem = 0
  778. ! ok
  779. status = 0
  780. end subroutine MDF_Dim_List_Init
  781. ! ***
  782. !
  783. ! Clear list, deallocate content.
  784. !
  785. subroutine MDF_Dim_List_Done( list, status )
  786. ! --- in/out -------------------------------------
  787. type(MDF_Dim_List), intent(inout) :: list
  788. integer, intent(out) :: status
  789. ! --- const --------------------------------------
  790. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_Done'
  791. ! --- local --------------------------------------
  792. integer :: i
  793. ! --- begin --------------------------------------
  794. ! list defined ?
  795. if ( associated(list%item) ) then
  796. ! loop over all possible indices:
  797. do i = 1, list%maxitem
  798. ! filled ?
  799. if ( associated(list%item(i)%p) ) then
  800. ! remove structure, reset to save value:
  801. deallocate( list%item(i)%p )
  802. nullify( list%item(i)%p )
  803. end if
  804. end do
  805. ! clear, reset to save value:
  806. deallocate( list%item )
  807. nullify( list%item )
  808. end if
  809. ! set counters:
  810. list%maxitem = 0
  811. list%nitem = 0
  812. ! ok
  813. status = 0
  814. end subroutine MDF_Dim_List_Done
  815. ! ***
  816. !
  817. ! Add new item to list, return id number.
  818. !
  819. subroutine MDF_Dim_List_New_Item( list, hid, status )
  820. ! --- in/out -------------------------------------
  821. type(MDF_Dim_List), intent(inout) :: list
  822. integer, intent(out) :: hid
  823. integer, intent(out) :: status
  824. ! --- const --------------------------------------
  825. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_New_Item'
  826. ! --- local --------------------------------------
  827. integer :: i
  828. type(P_MDF_Dim), pointer :: item_new(:)
  829. ! --- begin --------------------------------------
  830. ! free item available ?
  831. if ( list%nitem < list%maxitem ) then
  832. ! search first empty item:
  833. hid = -1
  834. do i = 1, list%maxitem
  835. if ( .not. associated(list%item(i)%p) ) then
  836. hid = i
  837. exit
  838. end if
  839. end do
  840. ! not found ?
  841. if ( hid < 0 ) then
  842. write (gol,'("all items seem to be associated while counters suggest something else ...")'); call goErr
  843. write (gol,'(" maxitem : ",i6)') list%maxitem; call goErr
  844. write (gol,'(" nitem : ",i6)') list%nitem; call goErr
  845. TRACEBACK; status=1; return
  846. end if
  847. else
  848. ! allocate extra space:
  849. allocate( item_new(1:list%maxitem+100) )
  850. ! copy old pointers:
  851. do i = 1, list%maxitem
  852. item_new(i)%p => list%item(i)%p
  853. end do
  854. ! init new pointers:
  855. do i = list%maxitem+1, size(item_new)
  856. nullify(item_new(i)%p)
  857. end do
  858. ! first empty item:
  859. hid = list%maxitem+1
  860. ! clear old list if necessary:
  861. if ( associated(list%item) ) deallocate( list%item )
  862. ! point to new list:
  863. list%item => item_new
  864. ! reset size counter:
  865. list%maxitem = size(list%item)
  866. ! clear:
  867. nullify( item_new )
  868. end if
  869. ! allocate structure:
  870. allocate( list%item(hid)%p )
  871. ! increase counter:
  872. list%nitem = list%nitem + 1
  873. ! ok
  874. status = 0
  875. end subroutine MDF_Dim_List_New_Item
  876. ! ***
  877. !
  878. ! Remove item with given id from list.
  879. !
  880. subroutine MDF_Dim_List_Clear_Item( list, hid, status )
  881. ! --- in/out -------------------------------------
  882. type(MDF_Dim_List), intent(inout) :: list
  883. integer, intent(inout) :: hid
  884. integer, intent(out) :: status
  885. ! --- const --------------------------------------
  886. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_Clear_Item'
  887. ! --- local --------------------------------------
  888. ! --- begin --------------------------------------
  889. ! check index in list ...
  890. if ( (hid < 0) .or. (hid > list%maxitem) ) then
  891. write (gol,'("handle outside range:")'); call goErr
  892. write (gol,'(" handle : ",i6)') hid; call goErr
  893. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  894. TRACEBACK; status=1; return
  895. end if
  896. ! check ...
  897. if ( .not. associated(list%item(hid)%p) ) then
  898. write (gol,'("handle not in use: ",i6)') hid; call goErr
  899. TRACEBACK; status=1; return
  900. end if
  901. ! clear structure:
  902. deallocate( list%item(hid)%p )
  903. ! reset pointer to save value:
  904. nullify( list%item(hid)%p )
  905. ! reset counter:
  906. list%nitem = list%nitem - 1
  907. ! ok
  908. status = 0
  909. end subroutine MDF_Dim_List_Clear_Item
  910. ! ***
  911. !
  912. ! Return pointer to user type given id.
  913. ! Status -1 if id is not in use.
  914. !
  915. subroutine MDF_Dim_List_Get_Pointer( list, hid, p, status, silent )
  916. ! --- in/out -------------------------------------
  917. type(MDF_Dim_List), intent(inout) :: list
  918. integer, intent(in) :: hid
  919. type(MDF_Dim), pointer :: p
  920. integer, intent(out) :: status
  921. logical, intent(in), optional :: silent
  922. ! --- const --------------------------------------
  923. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_Get_Pointer'
  924. ! --- local --------------------------------------
  925. logical :: shout
  926. ! --- begin --------------------------------------
  927. ! messages ?
  928. shout = .true.
  929. if ( present(silent) ) shout = .not. silent
  930. ! check index in list ...
  931. if ( (hid < 1) .or. (hid > list%maxitem) ) then
  932. write (gol,'("handle outside range:")'); call goErr
  933. write (gol,'(" handle : ",i6)') hid; call goErr
  934. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  935. TRACEBACK; status=1; return
  936. end if
  937. ! check if handle is in use ...
  938. if ( .not. associated(list%item(hid)%p) ) then
  939. ! error or warning ?
  940. if ( shout ) then
  941. ! error status:
  942. write (gol,'("handle not in use: ",i6)') hid; call goErr
  943. TRACEBACK; status=1; return
  944. else
  945. ! warning status; this routine is used to test if a handle is in use:
  946. nullify( p )
  947. status = -1 ; return
  948. end if
  949. end if
  950. ! set shorthand:
  951. p => list%item(hid)%p
  952. ! ok
  953. status = 0
  954. end subroutine MDF_Dim_List_Get_Pointer
  955. ! ***
  956. !
  957. ! Return information:
  958. ! n
  959. ! Number of elements in use.
  960. ! maxid
  961. ! Current possible upper value for id's.
  962. ! Not all id's in {1,..,maxid} are in use.
  963. ! Usefull to implement a loop over all possible items.
  964. !
  965. subroutine MDF_Dim_List_Inquire( list, status, &
  966. n, maxid )
  967. ! --- in/out -------------------------------------
  968. type(MDF_Dim_List), intent(inout) :: list
  969. integer, intent(out) :: status
  970. integer, intent(out), optional :: n
  971. integer, intent(out), optional :: maxid
  972. ! --- const --------------------------------------
  973. character(len=*), parameter :: rname = mname//'/MDF_Dim_List_Inquire'
  974. ! --- begin --------------------------------------
  975. ! set values ?
  976. if ( present(n ) ) n = list%nitem
  977. if ( present(maxid) ) maxid = list%maxitem
  978. ! ok
  979. status = 0
  980. end subroutine MDF_Dim_List_Inquire
  981. ! ********************************************************************
  982. ! ***
  983. ! *** MDF_Var procedures
  984. ! ***
  985. ! ********************************************************************
  986. !
  987. ! Initialise a list.
  988. !
  989. subroutine MDF_Var_List_Init( list, status )
  990. ! --- in/out -------------------------------------
  991. type(MDF_Var_List), intent(out) :: list
  992. integer, intent(out) :: status
  993. ! --- const --------------------------------------
  994. character(len=*), parameter :: rname = mname//'/MDF_Var_List_Init'
  995. ! --- begin --------------------------------------
  996. ! empty list:
  997. nullify( list%item )
  998. ! set counters:
  999. list%maxitem = 0
  1000. list%nitem = 0
  1001. ! ok
  1002. status = 0
  1003. end subroutine MDF_Var_List_Init
  1004. ! ***
  1005. !
  1006. ! Clear list, deallocate content.
  1007. !
  1008. subroutine MDF_Var_List_Done( list, status )
  1009. ! --- in/out -------------------------------------
  1010. type(MDF_Var_List), intent(inout) :: list
  1011. integer, intent(out) :: status
  1012. ! --- const --------------------------------------
  1013. character(len=*), parameter :: rname = mname//'/MDF_Var_List_Done'
  1014. ! --- local --------------------------------------
  1015. integer :: i
  1016. ! --- begin --------------------------------------
  1017. ! list defined ?
  1018. if ( associated(list%item) ) then
  1019. ! loop over all possible indices:
  1020. do i = 1, list%maxitem
  1021. ! filled ?
  1022. if ( associated(list%item(i)%p) ) then
  1023. ! remove structure, reset to save value:
  1024. deallocate( list%item(i)%p )
  1025. nullify( list%item(i)%p )
  1026. end if
  1027. end do
  1028. ! clear, reset to save value:
  1029. deallocate( list%item )
  1030. nullify( list%item )
  1031. end if
  1032. ! set counters:
  1033. list%maxitem = 0
  1034. list%nitem = 0
  1035. ! ok
  1036. status = 0
  1037. end subroutine MDF_Var_List_Done
  1038. ! ***
  1039. !
  1040. ! Add new item to list, return id number.
  1041. !
  1042. subroutine MDF_Var_List_New_Item( list, hid, status )
  1043. ! --- in/out -------------------------------------
  1044. type(MDF_Var_List), intent(inout) :: list
  1045. integer, intent(out) :: hid
  1046. integer, intent(out) :: status
  1047. ! --- const --------------------------------------
  1048. character(len=*), parameter :: rname = mname//'/MDF_Var_List_New_Item'
  1049. ! --- local --------------------------------------
  1050. integer :: i
  1051. type(P_MDF_Var), pointer :: item_new(:)
  1052. ! --- begin --------------------------------------
  1053. ! free item available ?
  1054. if ( list%nitem < list%maxitem ) then
  1055. ! search first empty item:
  1056. hid = -1
  1057. do i = 1, list%maxitem
  1058. if ( .not. associated(list%item(i)%p) ) then
  1059. hid = i
  1060. exit
  1061. end if
  1062. end do
  1063. ! not found ?
  1064. if ( hid < 0 ) then
  1065. write (gol,'("all items seem to be associated while counters suggest something else ...")'); call goErr
  1066. write (gol,'(" maxitem : ",i6)') list%maxitem; call goErr
  1067. write (gol,'(" nitem : ",i6)') list%nitem; call goErr
  1068. TRACEBACK; status=1; return
  1069. end if
  1070. else
  1071. ! allocate extra space:
  1072. allocate( item_new(1:list%maxitem+100) )
  1073. ! copy old pointers:
  1074. do i = 1, list%maxitem
  1075. item_new(i)%p => list%item(i)%p
  1076. end do
  1077. ! init new pointers:
  1078. do i = list%maxitem+1, size(item_new)
  1079. nullify(item_new(i)%p)
  1080. end do
  1081. ! first empty item:
  1082. hid = list%maxitem+1
  1083. ! clear old list if necessary:
  1084. if ( associated(list%item) ) deallocate( list%item )
  1085. ! point to new list:
  1086. list%item => item_new
  1087. ! reset size counter:
  1088. list%maxitem = size(list%item)
  1089. ! clear:
  1090. nullify( item_new )
  1091. end if
  1092. ! allocate structure:
  1093. allocate( list%item(hid)%p )
  1094. ! increase counter:
  1095. list%nitem = list%nitem + 1
  1096. ! ok
  1097. status = 0
  1098. end subroutine MDF_Var_List_New_Item
  1099. ! ***
  1100. !
  1101. ! Remove item with given id from list.
  1102. !
  1103. subroutine MDF_Var_List_Clear_Item( list, hid, status )
  1104. ! --- in/out -------------------------------------
  1105. type(MDF_Var_List), intent(inout) :: list
  1106. integer, intent(inout) :: hid
  1107. integer, intent(out) :: status
  1108. ! --- const --------------------------------------
  1109. character(len=*), parameter :: rname = mname//'/MDF_Var_List_Clear_Item'
  1110. ! --- local --------------------------------------
  1111. ! --- begin --------------------------------------
  1112. ! check index in list ...
  1113. if ( (hid < 0) .or. (hid > list%maxitem) ) then
  1114. write (gol,'("handle outside range:")'); call goErr
  1115. write (gol,'(" handle : ",i6)') hid; call goErr
  1116. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  1117. TRACEBACK; status=1; return
  1118. end if
  1119. ! check ...
  1120. if ( .not. associated(list%item(hid)%p) ) then
  1121. write (gol,'("handle not in use: ",i6)') hid; call goErr
  1122. TRACEBACK; status=1; return
  1123. end if
  1124. ! clear structure:
  1125. deallocate( list%item(hid)%p )
  1126. ! reset pointer to save value:
  1127. nullify( list%item(hid)%p )
  1128. ! reset counter:
  1129. list%nitem = list%nitem - 1
  1130. ! ok
  1131. status = 0
  1132. end subroutine MDF_Var_List_Clear_Item
  1133. ! ***
  1134. !
  1135. ! Return pointer to user type given id.
  1136. ! Status -1 if id is not in use.
  1137. !
  1138. subroutine MDF_Var_List_Get_Pointer( list, hid, p, status, silent )
  1139. ! --- in/out -------------------------------------
  1140. type(MDF_Var_List), intent(inout) :: list
  1141. integer, intent(in) :: hid
  1142. type(MDF_Var), pointer :: p
  1143. integer, intent(out) :: status
  1144. logical, intent(in), optional :: silent
  1145. ! --- const --------------------------------------
  1146. character(len=*), parameter :: rname = mname//'/MDF_Var_List_Get_Pointer'
  1147. ! --- local --------------------------------------
  1148. logical :: shout
  1149. ! --- begin --------------------------------------
  1150. ! messages ?
  1151. shout = .true.
  1152. if ( present(silent) ) shout = .not. silent
  1153. ! check index in list ...
  1154. if ( (hid < 1) .or. (hid > list%maxitem) ) then
  1155. write (gol,'("handle outside range:")'); call goErr
  1156. write (gol,'(" handle : ",i6)') hid; call goErr
  1157. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  1158. TRACEBACK; status=1; return
  1159. end if
  1160. ! check if handle is in use ...
  1161. if ( .not. associated(list%item(hid)%p) ) then
  1162. ! error or warning ?
  1163. if ( shout ) then
  1164. ! error status:
  1165. write (gol,'("handle not in use: ",i6)') hid; call goErr
  1166. TRACEBACK; status=1; return
  1167. else
  1168. ! warning status; this routine is used to test if a handle is in use:
  1169. nullify( p )
  1170. status = -1 ; return
  1171. end if
  1172. end if
  1173. ! set shorthand:
  1174. p => list%item(hid)%p
  1175. ! ok
  1176. status = 0
  1177. end subroutine MDF_Var_List_Get_Pointer
  1178. ! ***
  1179. !
  1180. ! Return information:
  1181. ! n
  1182. ! Number of elements in use.
  1183. ! maxid
  1184. ! Current possible upper value for id's.
  1185. ! Not all id's in {1,..,maxid} are in use.
  1186. ! Usefull to implement a loop over all possible items.
  1187. !
  1188. subroutine MDF_Var_List_Inquire( list, status, &
  1189. n, maxid )
  1190. ! --- in/out -------------------------------------
  1191. type(MDF_Var_List), intent(inout) :: list
  1192. integer, intent(out) :: status
  1193. integer, intent(out), optional :: n
  1194. integer, intent(out), optional :: maxid
  1195. ! --- const --------------------------------------
  1196. character(len=*), parameter :: rname = mname//'/MDF_Var_List_Inquire'
  1197. ! --- begin --------------------------------------
  1198. ! set values ?
  1199. if ( present(n ) ) n = list%nitem
  1200. if ( present(maxid) ) maxid = list%maxitem
  1201. ! ok
  1202. status = 0
  1203. end subroutine MDF_Var_List_Inquire
  1204. ! ********************************************************************
  1205. ! ***
  1206. ! *** MDF procedures
  1207. ! ***
  1208. ! ********************************************************************
  1209. !
  1210. ! Initialise a list.
  1211. !
  1212. subroutine MDF_File_List_Init( list, status )
  1213. ! --- in/out -------------------------------------
  1214. type(MDF_File_List), intent(out) :: list
  1215. integer, intent(out) :: status
  1216. ! --- const --------------------------------------
  1217. character(len=*), parameter :: rname = mname//'/MDF_File_List_Init'
  1218. ! --- begin --------------------------------------
  1219. ! empty list:
  1220. nullify( list%item )
  1221. ! set counters:
  1222. list%maxitem = 0
  1223. list%nitem = 0
  1224. ! ok
  1225. status = 0
  1226. end subroutine MDF_File_List_Init
  1227. ! ***
  1228. !
  1229. ! Clear list, deallocate content.
  1230. !
  1231. subroutine MDF_File_List_Done( list, status )
  1232. ! --- in/out -------------------------------------
  1233. type(MDF_File_List), intent(inout) :: list
  1234. integer, intent(out) :: status
  1235. ! --- const --------------------------------------
  1236. character(len=*), parameter :: rname = mname//'/MDF_File_List_Done'
  1237. ! --- local --------------------------------------
  1238. integer :: i
  1239. ! --- begin --------------------------------------
  1240. ! list defined ?
  1241. if ( associated(list%item) ) then
  1242. ! loop over all possible indices:
  1243. do i = 1, list%maxitem
  1244. ! filled ?
  1245. if ( associated(list%item(i)%p) ) then
  1246. ! remove structure, reset to save value:
  1247. deallocate( list%item(i)%p )
  1248. nullify( list%item(i)%p )
  1249. end if
  1250. end do
  1251. ! clear, reset to save value:
  1252. deallocate( list%item )
  1253. nullify( list%item )
  1254. end if
  1255. ! set counters:
  1256. list%maxitem = 0
  1257. list%nitem = 0
  1258. ! ok
  1259. status = 0
  1260. end subroutine MDF_File_List_Done
  1261. ! ***
  1262. !
  1263. ! Add new item to list, return id number.
  1264. !
  1265. subroutine MDF_File_List_New_Item( list, hid, status )
  1266. ! --- in/out -------------------------------------
  1267. type(MDF_File_List), intent(inout) :: list
  1268. integer, intent(out) :: hid
  1269. integer, intent(out) :: status
  1270. ! --- const --------------------------------------
  1271. character(len=*), parameter :: rname = mname//'/MDF_File_List_New_Item'
  1272. ! --- local --------------------------------------
  1273. integer :: i
  1274. type(P_MDF_File), pointer :: item_new(:)
  1275. ! --- begin --------------------------------------
  1276. ! free item available ?
  1277. if ( list%nitem < list%maxitem ) then
  1278. ! search first empty item:
  1279. hid = -1
  1280. do i = 1, list%maxitem
  1281. if ( .not. associated(list%item(i)%p) ) then
  1282. hid = i
  1283. exit
  1284. end if
  1285. end do
  1286. ! not found ?
  1287. if ( hid < 0 ) then
  1288. write (gol,'("all items seem to be associated while counters suggest something else ...")'); call goErr
  1289. write (gol,'(" maxitem : ",i6)') list%maxitem; call goErr
  1290. write (gol,'(" nitem : ",i6)') list%nitem; call goErr
  1291. TRACEBACK; status=1; return
  1292. end if
  1293. else
  1294. ! allocate extra space:
  1295. allocate( item_new(1:list%maxitem+100) )
  1296. ! copy old pointers:
  1297. do i = 1, list%maxitem
  1298. item_new(i)%p => list%item(i)%p
  1299. end do
  1300. ! init new pointers:
  1301. do i = list%maxitem+1, size(item_new)
  1302. nullify(item_new(i)%p)
  1303. end do
  1304. ! first empty item:
  1305. hid = list%maxitem+1
  1306. ! clear old list if necessary:
  1307. if ( associated(list%item) ) deallocate( list%item )
  1308. ! point to new list:
  1309. list%item => item_new
  1310. ! reset size counter:
  1311. list%maxitem = size(list%item)
  1312. ! clear:
  1313. nullify( item_new )
  1314. end if
  1315. ! allocate structure:
  1316. allocate( list%item(hid)%p )
  1317. ! increase counter:
  1318. list%nitem = list%nitem + 1
  1319. ! ok
  1320. status = 0
  1321. end subroutine MDF_File_List_New_Item
  1322. ! ***
  1323. !
  1324. ! Remove item with given id from list.
  1325. !
  1326. subroutine MDF_File_List_Clear_Item( list, hid, status )
  1327. ! --- in/out -------------------------------------
  1328. type(MDF_File_List), intent(inout) :: list
  1329. integer, intent(inout) :: hid
  1330. integer, intent(out) :: status
  1331. ! --- const --------------------------------------
  1332. character(len=*), parameter :: rname = mname//'/MDF_File_List_Clear_Item'
  1333. ! --- local --------------------------------------
  1334. ! --- begin --------------------------------------
  1335. ! check index in list ...
  1336. if ( (hid < 0) .or. (hid > list%maxitem) ) then
  1337. write (gol,'("handle outside range:")'); call goErr
  1338. write (gol,'(" handle : ",i6)') hid; call goErr
  1339. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  1340. TRACEBACK; status=1; return
  1341. end if
  1342. ! check ...
  1343. if ( .not. associated(list%item(hid)%p) ) then
  1344. write (gol,'("handle not in use: ",i6)') hid; call goErr
  1345. TRACEBACK; status=1; return
  1346. end if
  1347. ! clear structure:
  1348. deallocate( list%item(hid)%p )
  1349. ! reset pointer to save value:
  1350. nullify( list%item(hid)%p )
  1351. ! reset counter:
  1352. list%nitem = list%nitem - 1
  1353. ! ok
  1354. status = 0
  1355. end subroutine MDF_File_List_Clear_Item
  1356. ! ***
  1357. !
  1358. ! Return pointer to user type given id.
  1359. ! Status -1 if id is not in use.
  1360. !
  1361. subroutine MDF_File_List_Get_Pointer( list, hid, p, status, silent )
  1362. ! --- in/out -------------------------------------
  1363. type(MDF_File_List), intent(inout) :: list
  1364. integer, intent(in) :: hid
  1365. type(MDF_File), pointer :: p
  1366. integer, intent(out) :: status
  1367. logical, intent(in), optional :: silent
  1368. ! --- const --------------------------------------
  1369. character(len=*), parameter :: rname = mname//'/MDF_File_List_Get_Pointer'
  1370. ! --- local --------------------------------------
  1371. logical :: shout
  1372. ! --- begin --------------------------------------
  1373. ! messages ?
  1374. shout = .true.
  1375. if ( present(silent) ) shout = .not. silent
  1376. ! check index in list ...
  1377. if ( (hid < 1) .or. (hid > list%maxitem) ) then
  1378. write (gol,'("handle outside range:")'); call goErr
  1379. write (gol,'(" handle : ",i6)') hid; call goErr
  1380. write (gol,'(" range : ",2i6)') 1, list%maxitem; call goErr
  1381. TRACEBACK; status=1; return
  1382. end if
  1383. ! check if handle is in use ...
  1384. if ( .not. associated(list%item(hid)%p) ) then
  1385. ! error or warning ?
  1386. if ( shout ) then
  1387. ! error status:
  1388. write (gol,'("handle not in use: ",i6)') hid; call goErr
  1389. TRACEBACK; status=1; return
  1390. else
  1391. ! warning status; this routine is used to test if a handle is in use:
  1392. nullify( p )
  1393. status = -1 ; return
  1394. end if
  1395. end if
  1396. ! set shorthand:
  1397. p => list%item(hid)%p
  1398. ! ok
  1399. status = 0
  1400. end subroutine MDF_File_List_Get_Pointer
  1401. ! ***
  1402. !
  1403. ! Return information:
  1404. ! n
  1405. ! Number of elements in use.
  1406. ! maxid
  1407. ! Current possible upper value for id's.
  1408. ! Not all id's in {1,..,maxid} are in use.
  1409. ! Usefull to implement a loop over all possible items.
  1410. !
  1411. subroutine MDF_File_List_Inquire( list, status, &
  1412. n, maxid )
  1413. ! --- in/out -------------------------------------
  1414. type(MDF_File_List), intent(inout) :: list
  1415. integer, intent(out) :: status
  1416. integer, intent(out), optional :: n
  1417. integer, intent(out), optional :: maxid
  1418. ! --- const --------------------------------------
  1419. character(len=*), parameter :: rname = mname//'/MDF_File_List_Inquire'
  1420. ! --- begin --------------------------------------
  1421. ! set values ?
  1422. if ( present(n ) ) n = list%nitem
  1423. if ( present(maxid) ) maxid = list%maxitem
  1424. ! ok
  1425. status = 0
  1426. end subroutine MDF_File_List_Inquire
  1427. ! ********************************************************************
  1428. ! ***
  1429. ! *** tools
  1430. ! ***
  1431. ! ********************************************************************
  1432. subroutine MDF_Get_Kind( xtype, xkind, status )
  1433. ! --- in/out -------------------------------------
  1434. integer, intent(in) :: xtype
  1435. integer, intent(out) :: xkind
  1436. integer, intent(out) :: status
  1437. ! --- const --------------------------------------
  1438. character(len=*), parameter :: rname = mname//'/MDF_Get_Kind'
  1439. ! --- begin --------------------------------------
  1440. ! set kind value given type:
  1441. select case ( xtype )
  1442. case ( MDF_CHAR ) ; xkind = 1
  1443. case ( MDF_BYTE ) ; xkind = 1
  1444. case ( MDF_SHORT ) ; xkind = 2
  1445. case ( MDF_INT ) ; xkind = 4
  1446. case ( MDF_INT64 ) ; xkind = 8
  1447. case ( MDF_FLOAT ) ; xkind = 4
  1448. case ( MDF_DOUBLE ) ; xkind = 8
  1449. case default
  1450. write (gol,'("do not know kind for variable type : ",i6)') xtype; call goPr
  1451. TRACEBACK; status=1; return
  1452. end select
  1453. ! ok
  1454. status = 0
  1455. end subroutine MDF_Get_Kind
  1456. ! ***
  1457. #ifdef with_hdf5_beta
  1458. subroutine HDF5_Get_MDF_Type( hdf5_type_id, mdf_type, status )
  1459. use HDF5, only : HID_T
  1460. use HDF5, only : H5TGet_Class_f, H5TGet_Size_f, H5TClose_f
  1461. use HDF5, only : H5T_STRING_F, H5T_INTEGER_F, H5T_FLOAT_F
  1462. ! --- in/out -------------------------------------
  1463. integer(HID_T), intent(in) :: hdf5_type_id
  1464. integer, intent(out) :: mdf_type
  1465. integer, intent(out) :: status
  1466. ! --- const --------------------------------------
  1467. character(len=*), parameter :: rname = mname//'/HDF5_Get_MDF_Type'
  1468. ! --- local --------------------------------------
  1469. integer :: hdf5_typeclass, hdf5_typesize
  1470. ! --- begin --------------------------------------
  1471. ! get class:
  1472. call H5TGet_Class_f( hdf5_type_id, hdf5_typeclass, status )
  1473. IF_NOT_OK_RETURN(status=1)
  1474. ! split:
  1475. if ( hdf5_typeclass == H5T_STRING_F ) then
  1476. mdf_type = MDF_CHAR
  1477. else if ( hdf5_typeclass == H5T_INTEGER_F ) then
  1478. call H5TGet_Size_f( hdf5_type_id, hdf5_typesize, status )
  1479. IF_NOT_OK_RETURN(status=1)
  1480. select case ( hdf5_typesize )
  1481. case ( 1 ) ; mdf_type = MDF_BYTE
  1482. case ( 2 ) ; mdf_type = MDF_SHORT
  1483. case ( 4 ) ; mdf_type = MDF_INT
  1484. case default
  1485. write (gol,'("unsupported hdf5 type integer class size : ",i6)') hdf5_typesize; call goErr
  1486. TRACEBACK; status=1; return
  1487. end select
  1488. else if ( hdf5_typeclass == H5T_FLOAT_F ) then
  1489. call H5TGet_Size_f( hdf5_type_id, hdf5_typesize, status )
  1490. IF_NOT_OK_RETURN(status=1)
  1491. select case ( hdf5_typesize )
  1492. case ( 4 ) ; mdf_type = MDF_FLOAT
  1493. case ( 8 ) ; mdf_type = MDF_DOUBLE
  1494. case default
  1495. write (gol,'("unsupported hdf5 type float class size : ",i6)') hdf5_typesize; call goErr
  1496. TRACEBACK; status=1; return
  1497. end select
  1498. else
  1499. write (gol,'("unsupported hdf5 type class : ",i6)') hdf5_typeclass; call goErr
  1500. TRACEBACK; status=1; return
  1501. end if
  1502. ! ok
  1503. status = 0
  1504. end subroutine HDF5_Get_MDF_Type
  1505. #endif
  1506. #ifdef with_netcdf
  1507. subroutine NetCDF_Get_FileType( fname, ncformat, status )
  1508. use NetCDF, only : NF90_Open, NF90_Close, NF90_Inquire
  1509. use NetCDF, only : NF90_NOWRITE
  1510. use NetCDF, only : NF90_FORMAT_CLASSIC, NF90_FORMAT_64BIT, NF90_FORMAT_NETCDF4, NF90_FORMAT_NETCDF4_CLASSIC
  1511. ! --- in/out ---------------------------------
  1512. character(len=*), intent(in) :: fname
  1513. character(len=*), intent(out) :: ncformat
  1514. integer, intent(out) :: status
  1515. ! --- const --------------------------------------
  1516. character(len=*), parameter :: rname = mname//'/NetCDF_Get_FileType'
  1517. ! --- local ----------------------------------
  1518. logical :: exist
  1519. integer :: ncid
  1520. integer :: formatNum
  1521. ! --- begin ----------------------------------
  1522. ! check ...
  1523. inquire( file=trim(fname), exist=exist )
  1524. if ( .not. exist ) then
  1525. write (gol,'("file to be opened not found : ",a)') trim(fname); call goErr
  1526. TRACEBACK; status=1; return
  1527. end if
  1528. ! open file for reading:
  1529. status = NF90_Open( trim(fname), NF90_NOWRITE, ncid )
  1530. IF_NF90_NOT_OK_RETURN(status=1)
  1531. ! get format number:
  1532. status = NF90_Inquire( ncid, formatNum=formatNum )
  1533. IF_NF90_NOT_OK_RETURN(status=1)
  1534. ! translate ...
  1535. select case ( formatNum )
  1536. case ( NF90_FORMAT_CLASSIC ) ; ncformat = 'netcdf_classic'
  1537. case ( NF90_FORMAT_64BIT ) ; ncformat = 'netcdf_64bit'
  1538. case ( NF90_FORMAT_NETCDF4 ) ; ncformat = 'netcdf4'
  1539. case ( NF90_FORMAT_NETCDF4_CLASSIC ) ; ncformat = 'netcdf4_classic'
  1540. case default ; ncformat = 'netcdf_unknown'
  1541. end select
  1542. ! close file:
  1543. status = NF90_Close( ncid )
  1544. IF_NF90_NOT_OK_RETURN(status=1)
  1545. ! ok
  1546. status = 0
  1547. end subroutine NetCDF_Get_FileType
  1548. #endif
  1549. ! ********************************************************************
  1550. ! ***
  1551. ! *** module init/done
  1552. ! ***
  1553. ! ********************************************************************
  1554. subroutine MDF_Init( status, loglevel )
  1555. #ifdef with_hdf5_beta
  1556. use HDF5, only : H5Open_f
  1557. #endif
  1558. ! --- in/out -------------------------------------
  1559. integer, intent(out) :: status
  1560. integer, intent(in), optional :: loglevel
  1561. ! --- const --------------------------------------
  1562. character(len=*), parameter :: rname = mname//'/MDF_Init'
  1563. ! --- local --------------------------------------
  1564. integer :: loglev
  1565. ! --- begin --------------------------------------
  1566. ! log level ...
  1567. loglev = 0 ! no messages
  1568. if ( present(loglevel) ) loglev = loglevel
  1569. ! info ...
  1570. if (loglev>0) then; write (gol,'("initialize MDF module ...")'); call goPr; end if
  1571. #ifdef with_hdf4
  1572. ! info ...
  1573. if (loglev>0) then; write (gol,'(" HDF4 interface enabled ...")'); call goPr; end if
  1574. #else
  1575. ! info ...
  1576. if (loglev>0) then; write (gol,'(" HDF4 interface disabled ...")'); call goPr; end if
  1577. #endif
  1578. #ifdef with_hdf5_beta
  1579. ! initialize Fortran interface:
  1580. call H5Open_f( status )
  1581. IF_NOT_OK_RETURN(status=1)
  1582. ! info ...
  1583. if (loglev>0) then; write (gol,'(" HDF5 interface enabled ...")'); call goPr; end if
  1584. #endif
  1585. #ifdef with_netcdf
  1586. ! info ...
  1587. if (loglev>0) then; write (gol,'(" NetCDF interface enabled ...")'); call goPr; end if
  1588. #ifdef with_netcdf4
  1589. if (loglev>0) then; write (gol,'(" NetCDF4 interface enabled ...")'); call goPr; end if
  1590. #else
  1591. if (loglev>0) then; write (gol,'(" NetCDF4 interface disabled ...")'); call goPr; end if
  1592. #endif
  1593. #else
  1594. ! info ...
  1595. if (loglev>0) then; write (gol,'(" NetCDF interface disabled ...")'); call goPr; end if
  1596. #endif
  1597. ! setup empty list:
  1598. call MDF_File_List_Init( File_List, status )
  1599. IF_NOT_OK_RETURN(status=1)
  1600. ! ok
  1601. status = 0
  1602. end subroutine MDF_Init
  1603. ! ***
  1604. subroutine MDF_Done( status )
  1605. #ifdef with_hdf5_beta
  1606. use HDF5, only : H5Close_f
  1607. #endif
  1608. ! --- in/out -------------------------------------
  1609. integer, intent(out) :: status
  1610. ! --- const --------------------------------------
  1611. character(len=*), parameter :: rname = mname//'/MDF_Done'
  1612. ! --- local --------------------------------------
  1613. integer :: maxid
  1614. integer :: id
  1615. type(MDF_File), pointer :: filep
  1616. integer :: nerror
  1617. ! --- begin --------------------------------------
  1618. ! no errors yet ...
  1619. nerror = 0
  1620. ! get maximum id number:
  1621. call MDF_File_List_Inquire( File_List, status, maxid=maxid )
  1622. IF_NOT_OK_RETURN(status=1)
  1623. ! loop over all possible id's:
  1624. do id = 1, maxid
  1625. ! get pointer to file structure; status -1 if not in use:
  1626. call MDF_File_List_Get_Pointer( File_List, id, filep, status, silent=.true. )
  1627. if ( status == -1 ) cycle
  1628. IF_NOT_OK_RETURN(status=1)
  1629. ! error ...
  1630. write (gol,'("Called MDF_Done but file still in use: ",a)') trim(filep%filename); call goErr
  1631. nerror = nerror + 1
  1632. !! done with variables:
  1633. !call MDF_Var_List_Done( filep%Var_List, status )
  1634. !IF_NOT_OK_RETURN(status=1)
  1635. !! done with dimensions:
  1636. !call MDF_Dim_List_Done( filep%Dim_List, status )
  1637. !IF_NOT_OK_RETURN(status=1)
  1638. end do
  1639. ! clear list:
  1640. call MDF_File_List_Done( File_List, status )
  1641. IF_NOT_OK_RETURN(status=1)
  1642. #ifdef with_hdf5_beta
  1643. ! done with Fortran interface:
  1644. call H5Close_f( status )
  1645. IF_NOT_OK_RETURN(status=1)
  1646. #endif
  1647. ! ok
  1648. status = nerror
  1649. end subroutine MDF_Done
  1650. ! ********************************************************************
  1651. ! ***
  1652. ! *** file create/close
  1653. ! ***
  1654. ! ********************************************************************
  1655. subroutine MDF_Create_one( filename, ftype, cmode, hid, status, mpi_comm, mpi_info )
  1656. ! --- in/out -------------------------------------
  1657. character(len=*), intent(in) :: filename
  1658. integer, intent(in) :: ftype
  1659. integer, intent(in) :: cmode
  1660. integer, intent(out) :: hid
  1661. integer, intent(out) :: status
  1662. integer, intent(in), optional :: mpi_comm
  1663. integer, intent(in), optional :: mpi_info
  1664. ! --- const --------------------------------------
  1665. character(len=*), parameter :: rname = mname//'/MDF_Create_one'
  1666. ! --- local --------------------------------------
  1667. ! --- begin --------------------------------------
  1668. ! special case of more than one ....
  1669. call MDF_Create_more( filename, (/''/), (/ftype/), cmode, hid, status, &
  1670. mpi_comm, mpi_info )
  1671. IF_NOT_OK_RETURN(status=1)
  1672. ! ok
  1673. status = 0
  1674. end subroutine MDF_Create_one
  1675. ! ***
  1676. subroutine MDF_Create_more( basename, exts, ftypes, cmode, hid, status, &
  1677. mpi_comm, mpi_info )
  1678. #ifdef with_hdf5_beta
  1679. use HDF5, only : H5F_ACC_EXCL_F, H5F_ACC_TRUNC_F
  1680. use HDF5, only : H5FCreate_f
  1681. #endif
  1682. #ifdef with_netcdf
  1683. use NetCDF, only : NF90_CLOBBER, NF90_NOCLOBBER
  1684. use NetCDF, only : NF90_Create
  1685. #ifdef with_netcdf4
  1686. use NetCDF, only : NF90_CLASSIC_MODEL, NF90_NETCDF4
  1687. use NetCDF, only : NF90_Inq_LibVers
  1688. ! This parameter does not exist for library versions prior to 4.1 ;
  1689. ! Please use netcdf 4.1.1 or newer
  1690. use NetCDF, only : NF90_MPIIO
  1691. #endif
  1692. #endif
  1693. ! --- in/out -------------------------------------
  1694. character(len=*), intent(in) :: basename
  1695. character(len=*), intent(in) :: exts(:)
  1696. integer, intent(in) :: ftypes(:)
  1697. integer, intent(in) :: cmode
  1698. integer, intent(out) :: hid
  1699. integer, intent(out) :: status
  1700. integer, intent(in), optional :: mpi_comm
  1701. integer, intent(in), optional :: mpi_info
  1702. ! --- const --------------------------------------
  1703. character(len=*), parameter :: rname = mname//'/MDF_Create_more'
  1704. ! --- external ----------------------------
  1705. #ifdef with_hdf4
  1706. integer(hdf4_wpi), external :: sfStart
  1707. #endif
  1708. ! --- local --------------------------------------
  1709. type(MDF_File), pointer :: filep
  1710. integer :: iftype
  1711. integer :: ftype
  1712. #ifdef with_hdf4
  1713. integer :: hdf4_amode
  1714. #endif
  1715. #ifdef with_hdf5_beta
  1716. integer :: hdf5_amode
  1717. #endif
  1718. #ifdef with_netcdf
  1719. integer :: netcdf_cmode
  1720. character(len=80) :: netcdf_version
  1721. #endif
  1722. ! --- begin --------------------------------------
  1723. ! new file:
  1724. call MDF_File_List_New_Item( File_List, hid, status )
  1725. IF_NOT_OK_RETURN(status=1)
  1726. ! pointer to file structure:
  1727. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  1728. IF_NOT_OK_RETURN(status=1)
  1729. ! store filename stuff:
  1730. filep%filename = trim(basename)
  1731. ! store creation mode:
  1732. filep%cmode = cmode
  1733. ! parallel i/o ?
  1734. filep%parallel = present(mpi_comm) .or. present(mpi_info)
  1735. ! check ...
  1736. if ( filep%parallel ) then
  1737. if ( .not. all((/present(mpi_comm),present(mpi_info)/)) ) then
  1738. write (gol,'("Only one of the arguments `mpi_comm` or `mpi_info` provided, that is not enough!")'); call goErr
  1739. TRACEBACK; status=1; return
  1740. end if
  1741. end if
  1742. ! check ...
  1743. if ( size(exts) /= size(ftypes) ) then
  1744. write (gol,'("number of specified extensions should equal number of specfied file types:")'); call goErr
  1745. write (gol,'(" number of specified extensions : ",i6)') size(exts); call goErr
  1746. write (gol,'(" number of specified file types : ",i6)') size(ftypes); call goErr
  1747. TRACEBACK; status=1; return
  1748. end if
  1749. ! check ...
  1750. if ( size(ftypes) > MDF_FILETYPE_MAX ) then
  1751. write (gol,'("more file types specified than supported")'); call goErr
  1752. write (gol,'(" maximum number : ",i6)') MDF_FILETYPE_MAX; call goErr
  1753. write (gol,'(" specified : ",i6)') size(ftypes); call goErr
  1754. TRACEBACK; status=1; return
  1755. end if
  1756. ! store file types:
  1757. filep%nftype = size(ftypes)
  1758. filep%ftypes(1:filep%nftype) = ftypes
  1759. ! loop over file types:
  1760. do iftype = 1, filep%nftype
  1761. ! current type:
  1762. ftype = filep%ftypes(iftype)
  1763. ! select appropriate routine for each type:
  1764. select case ( ftype )
  1765. #ifdef with_hdf4
  1766. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1767. case ( MDF_HDF4 )
  1768. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1769. ! check ...
  1770. if ( filep%parallel ) then
  1771. write (gol,'("HDF4 files could not be created in parallel")'); call goErr
  1772. TRACEBACK; status=1; return
  1773. end if
  1774. ! full file name:
  1775. filep%hdf4_fname = trim(filep%filename)//trim(exts(iftype))
  1776. ! write to an new file (remove if exist)
  1777. hdf4_amode = DFACC_CREATE
  1778. ! open file:
  1779. filep%hdf4_id = sfStart( trim(filep%hdf4_fname), hdf4_amode )
  1780. if ( filep%hdf4_id == FAIL ) then
  1781. write (gol,'("from creating hdf4 file:")'); call goErr
  1782. write (gol,'(" ",a)') trim(filep%hdf4_fname); call goErr
  1783. write (gol,'(" does directory exist ?")'); call goErr
  1784. TRACEBACK; status=1; return
  1785. end if
  1786. #endif
  1787. #ifdef with_hdf5_beta
  1788. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1789. case ( MDF_HDF5 )
  1790. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1791. ! check ...
  1792. if ( filep%parallel ) then
  1793. write (gol,'("MDF/HDF5 not implemented for parallel creation yet")'); call goErr
  1794. TRACEBACK; status=1; return
  1795. end if
  1796. ! full file name:
  1797. filep%hdf5_fname = trim(filep%filename)//trim(exts(iftype))
  1798. ! initial access mode:
  1799. hdf5_amode = 0
  1800. ! set access mode:
  1801. select case ( cmode )
  1802. case ( MDF_NEW )
  1803. hdf5_amode = hdf5_amode + H5F_ACC_EXCL_F ! complain if already present
  1804. case ( MDF_REPLACE )
  1805. hdf5_amode = hdf5_amode + H5F_ACC_TRUNC_F ! overwrite if necessary
  1806. case default
  1807. write (gol,'("unsupported creation mode : ",i6)') cmode; call goErr
  1808. TRACEBACK; status=1; return
  1809. end select
  1810. ! open file:
  1811. call H5FCreate_f( trim(filep%hdf5_fname), hdf5_amode, filep%hdf5_file_id, status )
  1812. if (status/=0) then
  1813. write (gol,'("from creating hdf5 file:")'); call goErr
  1814. write (gol,'(" ",a)') trim(filep%hdf5_fname); call goErr
  1815. write (gol,'(" does directory exist ?")'); call goErr
  1816. TRACEBACK; status=1; return
  1817. end if
  1818. #endif
  1819. #ifdef with_netcdf
  1820. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1821. case ( MDF_NETCDF, MDF_NETCDF4 )
  1822. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1823. ! full file name:
  1824. filep%netcdf_fname = trim(filep%filename)//trim(exts(iftype))
  1825. ! initial creation mode:
  1826. netcdf_cmode = 0
  1827. ! set creation mode:
  1828. select case ( cmode )
  1829. case ( MDF_NEW )
  1830. netcdf_cmode = netcdf_cmode + NF90_NOCLOBBER ! complain if already present
  1831. case ( MDF_REPLACE )
  1832. netcdf_cmode = netcdf_cmode + NF90_CLOBBER ! overwrite if necessary
  1833. case default
  1834. write (gol,'("unsupported creation mode : ",i6)') cmode; call goErr
  1835. TRACEBACK; status=1; return
  1836. end select
  1837. ! latest format ?
  1838. #ifdef with_netcdf4
  1839. if ( ftype == MDF_NETCDF4 ) then
  1840. !netcdf_cmode = netcdf_cmode + NF90_HDF5
  1841. netcdf_cmode = netcdf_cmode + NF90_NETCDF4
  1842. else
  1843. netcdf_cmode = netcdf_cmode + NF90_CLASSIC_MODEL
  1844. end if
  1845. #else
  1846. if ( ftype == MDF_NETCDF4 ) then
  1847. write (gol,'("could not write NetCDF-4 file without `with_netcdf4` defined ...")'); call goErr
  1848. TRACEBACK; status=1; return
  1849. end if
  1850. #endif
  1851. ! create in parallel ?
  1852. if ( filep%parallel ) then
  1853. ! check ...
  1854. if ( ftype /= MDF_NETCDF4 ) then
  1855. write (gol,'("Creation of NetCDF file in parallel requires NETCDF4 file type.")'); call goErr
  1856. TRACEBACK; status=1; return
  1857. end if
  1858. #ifdef with_netcdf4_par
  1859. ! Creation mode MPIIO is needed for parallel i/o for NetCDF library 4.1.1 onwards
  1860. ! add value of NF90_MPIIO to creation mode:
  1861. netcdf_cmode = netcdf_cmode + NF90_MPIIO
  1862. ! create file, provide communicator and info:
  1863. status = NF90_Create( trim(filep%netcdf_fname), netcdf_cmode, filep%netcdf_id, &
  1864. comm=mpi_comm, info=mpi_info )
  1865. if (status/=NF90_NOERR) then
  1866. gol = trim(NF90_StrError(status)); call goErr
  1867. write (gol,'("from creating netcdf4 file :")'); call goErr
  1868. write (gol,'(" ",a)') trim(filep%netcdf_fname); call goErr
  1869. write (gol,'(" does directory exist ?")'); call goErr
  1870. TRACEBACK; status=1; return
  1871. end if
  1872. #else
  1873. write (gol,'("Parallel creation of NetCDF requires compilation with `with_netcdf4_par` macro defined.")'); call goErr
  1874. TRACEBACK; status=1; return
  1875. #endif
  1876. else
  1877. ! create file:
  1878. status = NF90_Create( trim(filep%netcdf_fname), netcdf_cmode, filep%netcdf_id )
  1879. if (status/=NF90_NOERR) then
  1880. gol = trim(NF90_StrError(status)); call goErr
  1881. write (gol,'("from creating netcdf4 file :")'); call goErr
  1882. write (gol,'(" ",a)') trim(filep%netcdf_fname); call goErr
  1883. write (gol,'(" ",a)') netcdf_cmode; call goErr
  1884. write (gol,'(" does directory exist ?")'); call goErr
  1885. TRACEBACK; status=1; return
  1886. end if
  1887. end if
  1888. #endif
  1889. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1890. case default
  1891. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1892. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  1893. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  1894. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  1895. TRACEBACK; status=1; return
  1896. end select
  1897. end do ! file types
  1898. ! init dimension list:
  1899. call MDF_Dim_List_Init( filep%Dim_List, status )
  1900. IF_NOT_OK_RETURN(status=1)
  1901. ! init variable list:
  1902. call MDF_Var_List_Init( filep%Var_List, status )
  1903. IF_NOT_OK_RETURN(status=1)
  1904. ! no global attributes yet:
  1905. filep%natt = 0
  1906. ! ok
  1907. status = 0
  1908. end subroutine MDF_Create_more
  1909. ! ***
  1910. subroutine MDF_Open( filename, ftype, mode, hid, status, &
  1911. mpi_comm, mpi_info )
  1912. #ifdef with_hdf5_beta
  1913. use HDF5, only : SIZE_T, HSIZE_T
  1914. use HDF5, only : H5FOpen_f
  1915. use HDF5, only : H5F_ACC_RDONLY_F
  1916. use HDF5, only : H5AGet_Num_Attrs_f
  1917. use HDF5, only : H5GOpen_f, H5GClose_f, H5GN_Members_f, H5GGet_Obj_Info_Idx_f
  1918. use HDF5, only : H5G_DATASET_F, H5G_LINK_F, H5G_GROUP_F, H5G_TYPE_F
  1919. use HDF5, only : H5DOpen_f, H5DGet_Type_f, H5DGet_Space_f
  1920. use HDF5, only : H5TClose_f
  1921. use HDF5, only : H5SClose_f, H5SGet_Simple_Extent_Dims_f
  1922. use HDF5, only : H5S_UNLIMITED_F
  1923. #endif
  1924. #ifdef with_netcdf
  1925. use NetCDF, only : NF90_WRITE, NF90_NOWRITE
  1926. use NetCDF, only : NF90_Open
  1927. use NetCDF, only : NF90_Inquire
  1928. use NetCDF, only : NF90_Inquire_Dimension
  1929. use NetCDF, only : NF90_Inquire_Variable
  1930. use NetCDF, only : NF90_CHAR, NF90_BYTE, NF90_SHORT, NF90_INT, NF90_INT64, NF90_FLOAT, NF90_DOUBLE
  1931. #ifdef with_netcdf4_par
  1932. use NetCDF, only : NF90_Open_Par,NF90_Inq_LibVers
  1933. ! This parameter does not exist for library versions prior to 4.1 ;
  1934. ! Please update to netCDF 4.1.1 or newer
  1935. use NetCDF, only : NF90_MPIIO
  1936. #endif
  1937. #endif
  1938. ! --- in/out -------------------------------------
  1939. character(len=*), intent(in) :: filename
  1940. integer, intent(in) :: ftype
  1941. integer, intent(in) :: mode
  1942. integer, intent(out) :: hid
  1943. integer, intent(out) :: status
  1944. integer, intent(in), optional :: mpi_comm
  1945. integer, intent(in), optional :: mpi_info
  1946. ! --- const --------------------------------------
  1947. character(len=*), parameter :: rname = mname//'/MDF_Open'
  1948. ! --- external ----------------------------
  1949. #ifdef with_hdf4
  1950. integer(hdf4_wpi), external :: sfStart
  1951. integer(hdf4_wpi), external :: sfFInfo
  1952. integer(hdf4_wpi), external :: sfGInfo
  1953. integer(hdf4_wpi), external :: sfGDInfo
  1954. integer(hdf4_wpi), external :: sfSelect
  1955. integer(hdf4_wpi), external :: sfDimID
  1956. #endif
  1957. ! --- local --------------------------------------
  1958. type(MDF_File), pointer :: filep
  1959. type(MDF_Dim), pointer :: dimp
  1960. type(MDF_Var), pointer :: varp
  1961. logical :: exist
  1962. #ifdef with_hdf4
  1963. integer :: hdf4_amode
  1964. integer :: hdf4_varind
  1965. integer :: hdf4_xtype
  1966. integer :: hdf4_dimind
  1967. integer :: hdf4_dimid
  1968. #endif
  1969. #ifdef with_hdf5_beta
  1970. integer :: hdf5_amode
  1971. integer(HID_T) :: hdf5_grp_id
  1972. character(len=LEN_NAME) :: hdf5_obj_name
  1973. integer :: hdf5_obj_type
  1974. integer(HID_T) :: hdf5_type_id
  1975. integer(HID_T) :: hdf5_space_id
  1976. character(len=6) :: snr
  1977. #endif
  1978. #ifdef with_netcdf
  1979. integer :: netcdf_mode
  1980. integer :: netcdf_xtype
  1981. integer :: unlimid
  1982. #endif
  1983. integer :: ndim, idim, dimid
  1984. integer :: nvar, ivar, varid
  1985. integer :: natt
  1986. character(len=LEN_NAME) :: name
  1987. integer :: length
  1988. integer :: dimids(MAX_RANK)
  1989. integer :: shp(MAX_RANK)
  1990. integer :: k, n
  1991. character(len=80) :: netcdf_version
  1992. ! --- begin --------------------------------------
  1993. ! new file:
  1994. call MDF_File_List_New_Item( File_List, hid, status )
  1995. IF_NOT_OK_RETURN(status=1)
  1996. ! pointer to file structure:
  1997. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  1998. IF_NOT_OK_RETURN(status=1)
  1999. ! init dimension list:
  2000. call MDF_Dim_List_Init( filep%Dim_List, status )
  2001. IF_NOT_OK_RETURN(status=1)
  2002. ! init variable list:
  2003. call MDF_Var_List_Init( filep%Var_List, status )
  2004. IF_NOT_OK_RETURN(status=1)
  2005. ! store filename stuff:
  2006. filep%filename = trim(filename)
  2007. ! store dummy creation mode:
  2008. filep%cmode = -1
  2009. ! parallel i/o ?
  2010. filep%parallel = present(mpi_comm) .or. present(mpi_info)
  2011. ! check ...
  2012. if ( filep%parallel ) then
  2013. if ( .not. all((/present(mpi_comm),present(mpi_info)/)) ) then
  2014. write (gol,'("Only one of the arguments `mpi_comm` or `mpi_info` provided, that is not enough!")'); call goErr
  2015. TRACEBACK; status=1; return
  2016. end if
  2017. end if
  2018. ! store file type:
  2019. filep%nftype = 1
  2020. filep%ftypes(1) = ftype
  2021. ! select appropriate routine for each type:
  2022. select case ( ftype )
  2023. #ifdef with_hdf4
  2024. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2025. case ( MDF_HDF4 )
  2026. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2027. ! check ...
  2028. if ( filep%parallel ) then
  2029. write (gol,'("HDF4 files could not be opened in parallel")'); call goErr
  2030. TRACEBACK; status=1; return
  2031. end if
  2032. ! full file name:
  2033. filep%hdf4_fname = trim(filep%filename)
  2034. ! check ...
  2035. inquire( file=trim(filep%hdf4_fname), exist=exist )
  2036. if ( .not. exist ) then
  2037. write (gol,'("file to be opened not found : ",a)') trim(filep%hdf4_fname); call goErr
  2038. TRACEBACK; status=1; return
  2039. end if
  2040. ! set access mode:
  2041. select case ( mode )
  2042. case ( MDF_READ )
  2043. hdf4_amode = DFACC_READ
  2044. case ( MDF_WRITE )
  2045. hdf4_amode = DFACC_WRITE
  2046. case default
  2047. write (gol,'("unsupported open mode : ",i6)') mode; call goErr
  2048. TRACEBACK; status=1; return
  2049. end select
  2050. ! open file:
  2051. filep%hdf4_id = sfStart( trim(filep%hdf4_fname), hdf4_amode )
  2052. if ( filep%hdf4_id == FAIL ) then
  2053. write (gol,'("from starting access to hdf file:")'); call goErr
  2054. write (gol,'(" file name : ",a)') trim(filep%hdf4_fname); call goErr
  2055. write (gol,'(" access mode : CREATE")'); call goErr
  2056. TRACEBACK; status=1; return
  2057. end if
  2058. ! get number of data sets and number of global attributes:
  2059. status = sfFInfo( filep%hdf4_id, nvar, filep%natt )
  2060. if ( status == FAIL ) then
  2061. write (gol,'("from sfFInfo :")'); call goErr
  2062. write (gol,'(" hdf file : ",a)') trim(filep%hdf4_fname); call goErr
  2063. TRACEBACK; status=1; return
  2064. end if
  2065. ! loop over variables:
  2066. do ivar = 1, nvar
  2067. ! new variable:
  2068. call MDF_Var_List_New_Item( filep%Var_List, varid, status )
  2069. IF_NOT_OK_RETURN(status=1)
  2070. ! pointer to variable structure:
  2071. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  2072. IF_NOT_OK_RETURN(status=1)
  2073. ! hdf variable index in 0,..,nvar-1
  2074. hdf4_varind = ivar - 1
  2075. ! get variable id:
  2076. varp%hdf4_sdid = sfSelect( filep%hdf4_id, hdf4_varind )
  2077. if ( varp%hdf4_sdid == FAIL ) then
  2078. write (gol,'("unable to locate data set with index ",i6)') hdf4_varind; call goErr
  2079. write (gol,'(" hdf file name : ",a)') trim(filep%hdf4_fname); call goErr
  2080. TRACEBACK; status=1; return
  2081. end if
  2082. ! get info:
  2083. status = sfGInfo( varp%hdf4_sdid, name, ndim, shp, varp%hdf4_xtype, varp%natt )
  2084. if ( status /= SUCCEED ) then
  2085. write (gol,'("getting info")'); call goErr
  2086. TRACEBACK; status=1; return
  2087. end if
  2088. ! store name:
  2089. varp%name = trim(name)
  2090. ! convert type:
  2091. select case ( varp%hdf4_xtype )
  2092. case ( DFNT_CHAR ) ; varp%xtype = MDF_CHAR
  2093. case ( DFNT_INT8 ) ; varp%xtype = MDF_BYTE
  2094. case ( DFNT_INT16 ) ; varp%xtype = MDF_SHORT
  2095. case ( DFNT_INT32 ) ; varp%xtype = MDF_INT
  2096. case ( DFNT_FLOAT32 ) ; varp%xtype = MDF_FLOAT
  2097. case ( DFNT_FLOAT64 ) ; varp%xtype = MDF_DOUBLE
  2098. case default
  2099. write (gol,'("unsupported data type : ",i6)') varp%hdf4_xtype; call goErr
  2100. TRACEBACK; status=1; return
  2101. end select
  2102. ! set kind given type:
  2103. call MDF_Get_Kind( varp%xtype, varp%xkind, status )
  2104. IF_NOT_OK_RETURN(status=1)
  2105. ! store number of dimensions:
  2106. varp%ndim = ndim
  2107. ! init arrays:
  2108. varp%dimids = -1
  2109. varp%shp = -1
  2110. ! loop over dimensions:
  2111. do idim = 1, ndim
  2112. ! hdf4 dimension index in 0,..,ndim-1
  2113. hdf4_dimind = idim - 1
  2114. ! get hdf4 dimension id:
  2115. hdf4_dimid = sfDimID( varp%hdf4_sdid, hdf4_dimind )
  2116. if ( hdf4_dimid == FAIL ) then
  2117. write (gol,'("error selecting dimension id :")'); call goErr
  2118. write (gol,'(" index : ",i6)') hdf4_dimind; call goErr
  2119. write (gol,'(" variable name : ",a)') trim(varp%name); call goErr
  2120. write (gol,'(" hdf name : ",a)') trim(filep%hdf4_fname); call goErr
  2121. TRACEBACK; status=1; return
  2122. end if
  2123. ! extract dimension info;
  2124. ! data type is only usefull if a 'scale' is assigned to the dimension
  2125. ! length might be SD_UNLIMITED, so use shp from sfGInfo for actual length
  2126. status = sfGDInfo( hdf4_dimid, name, length, hdf4_xtype, natt )
  2127. if ( hdf4_dimid == FAIL ) then
  2128. write (gol,'("error getting dimension info :")'); call goErr
  2129. write (gol,'(" index : ",i6)') hdf4_dimind; call goErr
  2130. write (gol,'(" variable name : ",a)') trim(varp%name); call goErr
  2131. write (gol,'(" hdf name : ",a)') trim(filep%hdf4_fname); call goErr
  2132. TRACEBACK; status=1; return
  2133. end if
  2134. ! check if dimension is already defined ...;
  2135. ! current number of defined dimensions:
  2136. call MDF_Dim_List_Inquire( filep%Dim_List, status, n=n )
  2137. IF_NOT_OK_RETURN(status=1)
  2138. ! loop over current dimensions:
  2139. dimid = -1
  2140. do k = 1, n
  2141. ! pointer to dimension structure:
  2142. call MDF_Dim_List_Get_Pointer( filep%Dim_List, k, dimp, status )
  2143. IF_NOT_OK_RETURN(status=1)
  2144. ! compare:
  2145. if ( trim(dimp%name) == trim(name) ) then
  2146. ! check ...
  2147. if ( dimp%length /= shp(idim) ) then
  2148. write (gol,'("length of dimension is different from previous defined length:")'); call goErr
  2149. write (gol,'(" file name : ",a)') trim(filep%hdf4_fname); call goErr
  2150. write (gol,'(" variable name : ",a)') trim(varp%name); call goErr
  2151. write (gol,'(" dimension name : ",a)') trim(name); call goErr
  2152. write (gol,'(" length : ",i6)') shp(idim); call goErr
  2153. write (gol,'(" defined length : ",i6)') dimp%length; call goErr
  2154. TRACEBACK; status=1; return
  2155. end if
  2156. ! ok; stop searching:
  2157. dimid = k
  2158. exit
  2159. end if
  2160. end do
  2161. ! not found ? then new dimension should be defined:
  2162. if ( dimid < 0 ) then
  2163. ! new dimension:
  2164. call MDF_Dim_List_New_Item( filep%Dim_List, dimid, status )
  2165. IF_NOT_OK_RETURN(status=1)
  2166. ! pointer to dimension structure:
  2167. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  2168. IF_NOT_OK_RETURN(status=1)
  2169. ! fill mdf dimension info:
  2170. dimp%named = name(1:7) /= 'fakeDim'
  2171. dimp%name = trim(name)
  2172. dimp%unlimited = length == SD_UNLIMITED
  2173. dimp%length = shp(idim) ! shp extraced via sfGInfo
  2174. end if
  2175. ! fill variable dimension info:
  2176. varp%dimids(idim) = dimid
  2177. varp%shp (idim) = dimp%length
  2178. end do ! dimensions
  2179. end do ! variables
  2180. #endif
  2181. #ifdef with_hdf5_beta
  2182. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2183. case ( MDF_HDF5 )
  2184. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2185. ! check ...
  2186. if ( filep%parallel ) then
  2187. write (gol,'("MDF/HDF5 not implemented for parallel open yet")'); call goErr
  2188. TRACEBACK; status=1; return
  2189. end if
  2190. ! full file name:
  2191. filep%hdf5_fname = trim(filep%filename)
  2192. ! check ...
  2193. inquire( file=trim(filep%hdf5_fname), exist=exist )
  2194. if ( .not. exist ) then
  2195. write (gol,'("file to be opened not found : ",a)') trim(filep%hdf5_fname); call goErr
  2196. TRACEBACK; status=1; return
  2197. end if
  2198. ! set access mode:
  2199. select case ( mode )
  2200. case ( MDF_READ )
  2201. hdf5_amode = H5F_ACC_RDONLY_F ! read-only
  2202. case default
  2203. write (gol,'("unsupported open mode : ",i6)') mode; call goErr
  2204. TRACEBACK; status=1; return
  2205. end select
  2206. ! open file:
  2207. call H5FOpen_f( trim(filep%hdf5_fname), hdf5_amode, filep%hdf5_file_id, status )
  2208. IF_NOT_OK_RETURN(status=1)
  2209. ! get number of global attributes:
  2210. call H5AGet_Num_Attrs_f( filep%hdf5_file_id, filep%natt, status )
  2211. IF_NOT_OK_RETURN(status=1)
  2212. ! open group:
  2213. call H5GOpen_f( filep%hdf5_file_id, '/', hdf5_grp_id, status )
  2214. IF_NOT_OK_RETURN(status=1)
  2215. ! get number of members:
  2216. call H5GN_Members_f( hdf5_grp_id, '.', nvar, status )
  2217. IF_NOT_OK_RETURN(status=1)
  2218. ! loop over group members:
  2219. do ivar = 1, nvar
  2220. ! get group info:
  2221. call H5GGet_Obj_Info_Idx_f( hdf5_grp_id, '.', ivar-1, hdf5_obj_name, hdf5_obj_type, status )
  2222. IF_NOT_OK_RETURN(status=1)
  2223. ! what ?
  2224. if ( hdf5_obj_type == H5G_DATASET_F ) then
  2225. ! new variable:
  2226. call MDF_Var_List_New_Item( filep%Var_List, varid, status )
  2227. IF_NOT_OK_RETURN(status=1)
  2228. ! pointer to variable structure:
  2229. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  2230. IF_NOT_OK_RETURN(status=1)
  2231. ! store full hdf5 name:
  2232. varp%hdf5_name = trim(hdf5_obj_name)
  2233. ! store variable name:
  2234. varp%name = trim(hdf5_obj_name)
  2235. ! open data set:
  2236. call H5DOpen_f( hdf5_grp_id, trim(hdf5_obj_name), varp%hdf5_dataset_id, status )
  2237. IF_NOT_OK_RETURN(status=1)
  2238. ! get type id:
  2239. call H5DGet_Type_f( varp%hdf5_dataset_id, hdf5_type_id, status )
  2240. IF_NOT_OK_RETURN(status=1)
  2241. ! convert to mdf type code:
  2242. call HDF5_Get_MDF_Type( hdf5_type_id, varp%xtype, status )
  2243. IF_NOT_OK_RETURN(status=1)
  2244. ! release:
  2245. call H5TClose_f( hdf5_type_id, status )
  2246. IF_NOT_OK_RETURN(status=1)
  2247. ! get data space id:
  2248. call H5DGet_Space_f( varp%hdf5_dataset_id, hdf5_space_id, status )
  2249. IF_NOT_OK_RETURN(status=1)
  2250. ! get dimensions:
  2251. call H5SGet_Simple_Extent_Dims_f( hdf5_space_id, varp%hdf5_dims, varp%hdf5_maxdims, status )
  2252. if ( status < 0 ) then
  2253. ! something went wrong ...
  2254. write (gol,'("could not extract dimensions for attribute : ",a)') trim(name); call goErr
  2255. TRACEBACK; status=1; return
  2256. else
  2257. ! number of dimensions:
  2258. ndim = status
  2259. end if
  2260. ! store number of dimensions in variable structure:
  2261. varp%ndim = status
  2262. ! init arrays:
  2263. varp%dimids = -1
  2264. varp%shp = -1
  2265. ! loop over dimensions:
  2266. do idim = 1, ndim
  2267. ! current length:
  2268. length = varp%hdf5_dims(idim)
  2269. ! new dimension:
  2270. call MDF_Dim_List_New_Item( filep%Dim_List, dimid, status )
  2271. IF_NOT_OK_RETURN(status=1)
  2272. ! pointer to dimension structure:
  2273. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  2274. IF_NOT_OK_RETURN(status=1)
  2275. ! store current length:
  2276. dimp%length = length
  2277. ! unlimitted ?
  2278. dimp%unlimited = varp%hdf5_maxdims(idim) == H5S_UNLIMITED_F
  2279. ! dummy name ...
  2280. dimp%named = .false.
  2281. write (snr,'(i6)') length
  2282. dimp%name = 'fakeDime'//adjustl(snr)
  2283. ! fill variable dimension info:
  2284. varp%dimids(idim) = dimid
  2285. varp%shp (idim) = dimp%length
  2286. end do ! dimensions
  2287. ! release:
  2288. call H5SClose_f( hdf5_space_id, status )
  2289. IF_NOT_OK_RETURN(status=1)
  2290. ! get number of global attributes:
  2291. call H5AGet_Num_Attrs_f( varp%hdf5_dataset_id, varp%natt, status )
  2292. IF_NOT_OK_RETURN(status=1)
  2293. else if ( hdf5_obj_type == H5G_LINK_F ) then
  2294. write (gol,'("WARNING - HDF5 links not supported yet: ",a)') trim(hdf5_obj_name); call goPr
  2295. else if ( hdf5_obj_type == H5G_GROUP_F ) then
  2296. write (gol,'("WARNING - HDF5 groups not supported yet: ",a)') trim(hdf5_obj_name); call goPr
  2297. else if ( hdf5_obj_type == H5G_TYPE_F ) then
  2298. write (gol,'("WARNING - HDF5 types not supported yet: ",a)') trim(hdf5_obj_name); call goPr
  2299. else
  2300. write (gol,'("unsupported hdf5_obj_type ",i6)') hdf5_obj_type; call goErr
  2301. TRACEBACK; status=1; return
  2302. end if
  2303. end do ! group members
  2304. ! release group:
  2305. call H5GClose_f( hdf5_grp_id, status )
  2306. IF_NOT_OK_RETURN(status=1)
  2307. #endif
  2308. #ifdef with_netcdf
  2309. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2310. case ( MDF_NETCDF, MDF_NETCDF4 )
  2311. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2312. ! full file name:
  2313. filep%netcdf_fname = trim(filep%filename)
  2314. ! check ...
  2315. inquire( file=trim(filep%netcdf_fname), exist=exist )
  2316. if ( .not. exist ) then
  2317. write (gol,'("file to be opened not found : ",a)') trim(filep%netcdf_fname); call goErr
  2318. TRACEBACK; status=1; return
  2319. end if
  2320. ! set open mode:
  2321. select case ( mode )
  2322. case ( MDF_READ )
  2323. netcdf_mode = NF90_NOWRITE
  2324. case ( MDF_WRITE )
  2325. netcdf_mode = NF90_WRITE
  2326. case default
  2327. write (gol,'("unsupported creation mode : ",i6)') mode; call goErr
  2328. TRACEBACK; status=1; return
  2329. end select
  2330. ! open in parallel ?
  2331. if ( filep%parallel ) then
  2332. ! open file in parallel:
  2333. #ifdef with_netcdf4_par
  2334. ! Creation mode MPIIO is needed for parallel i/o for NetCDF library 4.1.1 onwards
  2335. ! add value of NF90_MPIIO to creation mode:
  2336. netcdf_mode = netcdf_mode + NF90_MPIIO
  2337. status = NF90_Open_Par( trim(filep%netcdf_fname), netcdf_mode, &
  2338. mpi_comm, mpi_info, filep%netcdf_id )
  2339. IF_NF90_NOT_OK_RETURN(status=1)
  2340. #else
  2341. write (gol,'("Parallel open of NetCDF requires compilation with `with_netcdf4_par` macro defined.")'); call goErr
  2342. TRACEBACK; status=1; return
  2343. #endif
  2344. else
  2345. ! open file:
  2346. status = NF90_Open( trim(filep%netcdf_fname), netcdf_mode, filep%netcdf_id )
  2347. IF_NF90_NOT_OK_RETURN(status=1)
  2348. end if
  2349. ! get number of global attributes:
  2350. status = NF90_Inquire( filep%netcdf_id, nAttributes=filep%natt )
  2351. IF_NF90_NOT_OK_RETURN(status=1)
  2352. ! get number of dimensions and (dummy) id of unlimitted dimension:
  2353. status = NF90_Inquire( filep%netcdf_id, nDimensions=ndim, unlimitedDimID=unlimid )
  2354. IF_NF90_NOT_OK_RETURN(status=1)
  2355. ! loop over dimensions:
  2356. do idim = 1, ndim
  2357. ! new dimension:
  2358. call MDF_Dim_List_New_Item( filep%Dim_List, dimid, status )
  2359. IF_NOT_OK_RETURN(status=1)
  2360. ! pointer to dimension structure:
  2361. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  2362. IF_NOT_OK_RETURN(status=1)
  2363. ! netcdf dimension id is number from 1..ndim
  2364. dimp%netcdf_dimid = idim
  2365. ! get info:
  2366. status = NF90_Inquire_Dimension( filep%netcdf_id, dimp%netcdf_dimid, &
  2367. name=name, len=length )
  2368. IF_NF90_NOT_OK_RETURN(status=1)
  2369. ! store:
  2370. dimp%named = .true.
  2371. dimp%name = trim(name)
  2372. dimp%length = length
  2373. dimp%unlimited = dimp%netcdf_dimid == unlimid
  2374. end do
  2375. ! get number of variables:
  2376. status = NF90_Inquire( filep%netcdf_id, nVariables=nvar )
  2377. IF_NF90_NOT_OK_RETURN(status=1)
  2378. ! loop over variables:
  2379. do ivar = 1, nvar
  2380. ! new variable:
  2381. call MDF_Var_List_New_Item( filep%Var_List, varid, status )
  2382. IF_NOT_OK_RETURN(status=1)
  2383. ! pointer to variable structure:
  2384. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  2385. IF_NOT_OK_RETURN(status=1)
  2386. ! netcdf variable id is number from 1..nvar
  2387. varp%netcdf_varid = ivar
  2388. ! get info:
  2389. status = NF90_Inquire_Variable( filep%netcdf_id, varp%netcdf_varid, &
  2390. name=name, xtype=netcdf_xtype, ndims=ndim )
  2391. IF_NF90_NOT_OK_RETURN(status=1)
  2392. ! store name:
  2393. varp%name = trim(name)
  2394. ! convert type:
  2395. select case ( netcdf_xtype )
  2396. case ( NF90_CHAR ) ; varp%xtype = MDF_CHAR
  2397. case ( NF90_BYTE ) ; varp%xtype = MDF_BYTE
  2398. case ( NF90_SHORT ) ; varp%xtype = MDF_SHORT
  2399. case ( NF90_INT ) ; varp%xtype = MDF_INT
  2400. case ( NF90_INT64 ) ; varp%xtype = MDF_INT64
  2401. case ( NF90_FLOAT ) ; varp%xtype = MDF_FLOAT
  2402. case ( NF90_DOUBLE ) ; varp%xtype = MDF_DOUBLE
  2403. case default
  2404. write (gol,'("unsupported data type : ",i6)') netcdf_xtype; call goErr
  2405. TRACEBACK; status=1; return
  2406. end select
  2407. ! set kind given type:
  2408. call MDF_Get_Kind( varp%xtype, varp%xkind, status )
  2409. IF_NOT_OK_RETURN(status=1)
  2410. ! store number of dimensions:
  2411. varp%ndim = ndim
  2412. ! get netcdf dimension id's now that number is known:
  2413. status = NF90_Inquire_Variable( filep%netcdf_id, varp%netcdf_varid, dimids=dimids(1:ndim) )
  2414. IF_NF90_NOT_OK_RETURN(status=1)
  2415. ! init arrays:
  2416. varp%dimids = -1
  2417. varp%shp = -1
  2418. ! loop over dimensions:
  2419. do idim = 1, ndim
  2420. ! mdf dimension id is the same as the netcdf dimension id,
  2421. ! both are numbers 1,..,maxdim :
  2422. dimid = dimids(idim)
  2423. ! pointer to dimension structure:
  2424. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  2425. IF_NOT_OK_RETURN(status=1)
  2426. ! store:
  2427. varp%dimids(idim) = dimid
  2428. varp%shp (idim) = dimp%length
  2429. end do
  2430. ! get number of variable attributes:
  2431. status = NF90_Inquire_Variable( filep%netcdf_id, varp%netcdf_varid, nAtts=varp%natt )
  2432. IF_NF90_NOT_OK_RETURN(status=1)
  2433. end do ! variables
  2434. #endif
  2435. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2436. case default
  2437. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2438. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  2439. if ((ftype>=1).and.(ftype<=MDF_FILETYPE_MAX)) then
  2440. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  2441. end if
  2442. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  2443. TRACEBACK; status=1; return
  2444. end select
  2445. ! ok
  2446. status = 0
  2447. end subroutine MDF_Open
  2448. ! ***
  2449. subroutine MDF_Close( hid, status )
  2450. #ifdef with_hdf5_beta
  2451. use HDF5, only : H5FClose_f
  2452. use HDF5, only : H5DClose_f
  2453. #endif
  2454. #ifdef with_netcdf
  2455. use NetCDF, only : NF90_Close
  2456. #endif
  2457. ! --- in/out -------------------------------------
  2458. integer, intent(inout) :: hid
  2459. integer, intent(out) :: status
  2460. ! --- const --------------------------------------
  2461. character(len=*), parameter :: rname = mname//'/MDF_Close'
  2462. ! --- external ----------------------------
  2463. #ifdef with_hdf4
  2464. integer(hdf4_wpi), external :: sfEnd
  2465. #endif
  2466. ! --- local --------------------------------------
  2467. type(MDF_File), pointer :: filep
  2468. integer :: iftype
  2469. integer :: ftype
  2470. integer :: ivar, nvar
  2471. type(MDF_Var), pointer :: varp
  2472. ! --- begin --------------------------------------
  2473. ! pointer to file structure:
  2474. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  2475. IF_NOT_OK_RETURN(status=1)
  2476. ! loop over file types:
  2477. do iftype = 1, filep%nftype
  2478. ! current type:
  2479. ftype = filep%ftypes(iftype)
  2480. ! select appropriate routine for each type:
  2481. select case ( ftype )
  2482. #ifdef with_hdf4
  2483. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2484. case ( MDF_HDF4 )
  2485. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2486. ! close file:
  2487. status = sfEnd( filep%hdf4_id )
  2488. if ( status == FAIL ) then
  2489. write (gol,'("while closing HDF4 file:")'); call goErr
  2490. write (gol,'(" file name : ",a)') trim(filep%hdf4_fname); call goErr
  2491. TRACEBACK; status=1; return
  2492. end if
  2493. #endif
  2494. #ifdef with_hdf5_beta
  2495. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2496. case ( MDF_HDF5 )
  2497. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2498. ! get number of elements in variable list:
  2499. call MDF_Var_List_Inquire( filep%Var_List, status, n=nvar )
  2500. IF_NOT_OK_RETURN(status=1)
  2501. ! list variables ?
  2502. if ( nvar > 0 ) then
  2503. ! loop over variables:
  2504. do ivar = 1, nvar
  2505. ! pointer to variable structure:
  2506. call MDF_Var_List_Get_Pointer( filep%Var_List, ivar, varp, status )
  2507. IF_NOT_OK_RETURN(status=1)
  2508. ! close data set:
  2509. call H5DClose_f( varp%hdf5_dataset_id, status )
  2510. IF_NOT_OK_RETURN(status=1)
  2511. end do ! variables
  2512. end if ! nvar > 0
  2513. ! close file:
  2514. call H5FClose_f( filep%hdf5_file_id, status )
  2515. if ( status /= 0 ) then
  2516. write (gol,'("while closing HDF5 file:")'); call goErr
  2517. write (gol,'(" file name : ",a)') trim(filep%hdf5_fname); call goErr
  2518. TRACEBACK; status=1; return
  2519. end if
  2520. #endif
  2521. #ifdef with_netcdf
  2522. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2523. case ( MDF_NETCDF, MDF_NETCDF4 )
  2524. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2525. ! close file:
  2526. status = NF90_Close( filep%netcdf_id )
  2527. if ( status /= NF90_NOERR ) then
  2528. write (gol,'("while closing NetCDF4 file:")'); call goErr
  2529. write (gol,'(" file name : ",a)') trim(filep%netcdf_fname); call goErr
  2530. TRACEBACK; status=1; return
  2531. end if
  2532. #endif
  2533. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2534. case default
  2535. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2536. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  2537. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  2538. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  2539. TRACEBACK; status=1; return
  2540. end select
  2541. end do ! file types
  2542. ! done with variable list:
  2543. call MDF_Var_List_Done( filep%Var_List, status )
  2544. IF_NOT_OK_RETURN(status=1)
  2545. ! done with dimension list:
  2546. call MDF_Dim_List_Done( filep%Dim_List, status )
  2547. IF_NOT_OK_RETURN(status=1)
  2548. ! remove item:
  2549. call MDF_File_List_Clear_Item( File_List, hid, status )
  2550. IF_NOT_OK_RETURN(status=1)
  2551. ! ok
  2552. status = 0
  2553. end subroutine MDF_Close
  2554. ! ********************************************************************
  2555. ! ***
  2556. ! *** end of definition phase
  2557. ! ***
  2558. ! ********************************************************************
  2559. subroutine MDF_EndDef( hid, status )
  2560. #ifdef with_netcdf
  2561. use NetCDF, only : NF90_EndDef
  2562. #endif
  2563. ! --- in/out -------------------------------------
  2564. integer, intent(in) :: hid
  2565. integer, intent(out) :: status
  2566. ! --- const --------------------------------------
  2567. character(len=*), parameter :: rname = mname//'/MDF_EndDef'
  2568. ! --- local --------------------------------------
  2569. type(MDF_File), pointer :: filep
  2570. integer :: iftype
  2571. integer :: ftype
  2572. ! --- begin --------------------------------------
  2573. ! pointer to file structure:
  2574. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  2575. IF_NOT_OK_RETURN(status=1)
  2576. ! loop over file types:
  2577. do iftype = 1, filep%nftype
  2578. ! current type:
  2579. ftype = filep%ftypes(iftype)
  2580. ! select appropriate routine for each type:
  2581. select case ( ftype )
  2582. #ifdef with_hdf4
  2583. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2584. case ( MDF_HDF4 )
  2585. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2586. ! nothing required for this format ...
  2587. #endif
  2588. #ifdef with_hdf5_beta
  2589. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2590. case ( MDF_HDF5 )
  2591. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2592. ! nothing required for this format ...
  2593. #endif
  2594. #ifdef with_netcdf
  2595. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2596. case ( MDF_NETCDF, MDF_NETCDF4 )
  2597. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2598. ! end of definition phase:
  2599. status = NF90_EndDef( filep%netcdf_id )
  2600. IF_NF90_NOT_OK_RETURN(status=1)
  2601. #endif
  2602. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2603. case default
  2604. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2605. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  2606. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  2607. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  2608. TRACEBACK; status=1; return
  2609. end select
  2610. end do ! file types
  2611. ! ok
  2612. status = 0
  2613. end subroutine MDF_EndDef
  2614. ! ********************************************************************
  2615. ! ***
  2616. ! *** dimensions
  2617. ! ***
  2618. ! ********************************************************************
  2619. subroutine MDF_Def_Dim( hid, name, length, dimid, status )
  2620. #ifdef with_netcdf
  2621. use NetCDF, only : NF90_Def_Dim, NF90_UNLIMITED
  2622. #endif
  2623. ! --- in/out -------------------------------------
  2624. integer, intent(in) :: hid
  2625. character(len=*), intent(in) :: name
  2626. integer, intent(in) :: length
  2627. integer, intent(out) :: dimid
  2628. integer, intent(out) :: status
  2629. ! --- const --------------------------------------
  2630. character(len=*), parameter :: rname = mname//'/MDF_Def_Dim'
  2631. ! --- local --------------------------------------
  2632. type(MDF_File), pointer :: filep
  2633. type(MDF_Dim), pointer :: dimp
  2634. integer :: iftype
  2635. integer :: ftype
  2636. #ifdef with_netcdf
  2637. integer :: netcdf_length
  2638. #endif
  2639. ! --- begin --------------------------------------
  2640. ! pointer to file structure:
  2641. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  2642. IF_NOT_OK_RETURN(status=1)
  2643. ! new dimension:
  2644. call MDF_Dim_List_New_Item( filep%Dim_List, dimid, status )
  2645. IF_NOT_OK_RETURN(status=1)
  2646. ! pointer to dimension structure:
  2647. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  2648. IF_NOT_OK_RETURN(status=1)
  2649. ! store:
  2650. dimp%name = trim(name)
  2651. dimp%length = length
  2652. ! unlimited length ?
  2653. dimp%unlimited = length == MDF_UNLIMITED
  2654. ! loop over file types:
  2655. do iftype = 1, filep%nftype
  2656. ! current type:
  2657. ftype = filep%ftypes(iftype)
  2658. ! select appropriate routine for each type:
  2659. select case ( ftype )
  2660. #ifdef with_hdf4
  2661. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2662. case ( MDF_HDF4 )
  2663. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2664. ! Dimensions in HDF4 are no special entities in the file,
  2665. ! but part of each variable .
  2666. ! The arguments stored in the dimension structure will
  2667. ! be used to define the shape of new variables.
  2668. #endif
  2669. #ifdef with_hdf5_beta
  2670. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2671. case ( MDF_HDF5 )
  2672. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2673. ! Dimensions in HDF5 are no special entities in the file,
  2674. ! but stored in the 'data space' part of each variable .
  2675. ! The arguments stored in the dimension structure will
  2676. ! be used to define the shape of new variables.
  2677. #endif
  2678. #ifdef with_netcdf
  2679. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2680. case ( MDF_NETCDF, MDF_NETCDF4 )
  2681. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2682. ! set dimension length:
  2683. if ( dimp%unlimited ) then
  2684. netcdf_length = NF90_UNLIMITED
  2685. else
  2686. netcdf_length = length
  2687. end if
  2688. ! define dimension:
  2689. status = NF90_Def_Dim( filep%netcdf_id, trim(name), netcdf_length, dimp%netcdf_dimid )
  2690. IF_NF90_NOT_OK_RETURN(status=1)
  2691. #endif
  2692. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2693. case default
  2694. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2695. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  2696. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  2697. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  2698. TRACEBACK; status=1; return
  2699. end select
  2700. end do ! file types
  2701. ! ok
  2702. status = 0
  2703. end subroutine MDF_Def_Dim
  2704. ! ********************************************************************
  2705. ! ***
  2706. ! *** variables
  2707. ! ***
  2708. ! ********************************************************************
  2709. subroutine MDF_Def_Var( hid, name, xtype, dimids, varid, status, &
  2710. compression, deflate_level )
  2711. #ifdef with_hdf5_beta
  2712. use HDF5, only : HID_T, HSIZE_T
  2713. use HDF5, only : H5TCopy_f, H5TClose_f!, H5TSet_Size_f
  2714. use HDF5, only : H5T_NATIVE_CHARACTER
  2715. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  2716. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  2717. use HDF5, only : H5SCreate_Simple_f, H5SClose_f
  2718. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_UNLIMITED_F
  2719. use HDF5, only : H5PCreate_f, H5PClose_f, H5P_DATASET_CREATE_F
  2720. use HDF5, only : H5PSet_Chunk_f, H5PSet_Deflate_f
  2721. use HDF5, only : H5DCreate_f
  2722. #endif
  2723. #ifdef with_netcdf
  2724. use NetCDF, only : NF90_CHAR, NF90_BYTE, NF90_SHORT, NF90_INT, NF90_FLOAT, NF90_DOUBLE
  2725. use NetCDF, only : NF90_Def_Var
  2726. #ifdef with_netcdf4
  2727. use NetCDF, only : NF90_Def_Var_Deflate
  2728. #endif
  2729. #endif
  2730. ! --- in/out -------------------------------------
  2731. integer, intent(in) :: hid
  2732. character(len=*), intent(in) :: name
  2733. integer, intent(in) :: xtype
  2734. integer, intent(in) :: dimids(:)
  2735. integer, intent(out) :: varid
  2736. integer, intent(out) :: status
  2737. integer, intent(in), optional :: compression
  2738. integer, intent(in), optional :: deflate_level ! 0-9
  2739. ! --- const --------------------------------------
  2740. character(len=*), parameter :: rname = mname//'/MDF_Def_Var'
  2741. ! --- external -----------------------------------
  2742. #ifdef with_hdf4
  2743. integer(hdf4_wpi), external :: sfCreate
  2744. integer(hdf4_wpi), external :: sfDimID
  2745. integer(hdf4_wpi), external :: sfSDmName
  2746. integer(hdf4_wpi), external :: sfsCompress
  2747. #endif
  2748. ! --- local --------------------------------------
  2749. type(MDF_File), pointer :: filep
  2750. type(MDF_Dim), pointer :: dimp
  2751. type(MDF_Var), pointer :: varp
  2752. integer :: iftype
  2753. integer :: ftype
  2754. integer :: idim
  2755. #ifdef with_hdf4
  2756. integer :: hdf4_xtype
  2757. integer :: hdf4_shape(MAX_RANK)
  2758. integer :: hdf4_dimid
  2759. integer :: hdf4_comp_type
  2760. integer :: hdf4_comp_prm(1)
  2761. #endif
  2762. #ifdef with_hdf5_beta
  2763. integer :: hdf5_xtype
  2764. integer(HID_T) :: hdf5_type_id
  2765. integer(HID_T) :: hdf5_space_id
  2766. integer(HID_T) :: hdf5_dcpl_id
  2767. integer :: hdf5_deflate_level
  2768. #endif
  2769. #ifdef with_netcdf
  2770. integer :: netcdf_xtype
  2771. integer :: netcdf_dimids(MAX_RANK)
  2772. integer :: netcdf_deflate_level
  2773. #endif
  2774. ! --- begin --------------------------------------
  2775. ! pointer to file structure:
  2776. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  2777. IF_NOT_OK_RETURN(status=1)
  2778. ! new variable:
  2779. call MDF_Var_List_New_Item( filep%Var_List, varid, status )
  2780. IF_NOT_OK_RETURN(status=1)
  2781. ! pointer to variable structure:
  2782. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  2783. IF_NOT_OK_RETURN(status=1)
  2784. ! store name;
  2785. varp%name = trim(name)
  2786. ! store type:
  2787. varp%xtype = xtype
  2788. ! set kind value given type:
  2789. call MDF_Get_Kind( varp%xtype, varp%xkind, status )
  2790. IF_NOT_OK_RETURN(status=1)
  2791. ! number of dimensions:
  2792. varp%ndim = size(dimids)
  2793. ! dimension id's :
  2794. varp%dimids(1:varp%ndim) = dimids
  2795. ! fill shape:
  2796. do idim = 1, varp%ndim
  2797. ! pointer to dimension type:
  2798. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimids(idim), dimp, status )
  2799. IF_NOT_OK_RETURN(status=1)
  2800. ! copy dimension id:
  2801. varp%shp(idim) = dimp%length
  2802. end do
  2803. ! loop over file types:
  2804. do iftype = 1, filep%nftype
  2805. ! current type:
  2806. ftype = filep%ftypes(iftype)
  2807. ! select appropriate routine for each type:
  2808. select case ( ftype )
  2809. #ifdef with_hdf4
  2810. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2811. case ( MDF_HDF4 )
  2812. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2813. ! set data type:
  2814. select case ( xtype )
  2815. case ( MDF_CHAR ) ; hdf4_xtype = DFNT_CHAR
  2816. case ( MDF_BYTE ) ; hdf4_xtype = DFNT_INT8
  2817. case ( MDF_SHORT ) ; hdf4_xtype = DFNT_INT16
  2818. case ( MDF_INT ) ; hdf4_xtype = DFNT_INT32
  2819. case ( MDF_FLOAT ) ; hdf4_xtype = DFNT_FLOAT32
  2820. case ( MDF_DOUBLE ) ; hdf4_xtype = DFNT_FLOAT64
  2821. case default
  2822. write (gol,'("unsupported data type : ",i6)') xtype; call goErr
  2823. TRACEBACK; status=1; return
  2824. end select
  2825. ! extract dimensions:
  2826. do idim = 1, varp%ndim
  2827. ! pointer to dimension type:
  2828. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimids(idim), dimp, status )
  2829. IF_NOT_OK_RETURN(status=1)
  2830. ! fill dimension:
  2831. if ( dimp%length == MDF_UNLIMITED ) then
  2832. hdf4_shape(idim) = SD_UNLIMITED
  2833. else
  2834. hdf4_shape(idim) = dimp%length
  2835. end if
  2836. end do
  2837. ! define variable:
  2838. status = sfCreate( filep%hdf4_id, trim(name), hdf4_xtype, &
  2839. varp%ndim, hdf4_shape(1:varp%ndim) )
  2840. if ( status == FAIL ) then
  2841. write (gol,'("from sfCreate :")'); call goErr
  2842. write (gol,'(" name : ",a)') trim(name); call goErr
  2843. write (gol,'(" hdf file : ",a)') trim(filep%hdf4_fname); call goErr
  2844. TRACEBACK; status=1; return
  2845. end if
  2846. ! store
  2847. varp%hdf4_sdid = status
  2848. ! loop over dimension indices:
  2849. do idim = 1, varp%ndim
  2850. ! pointer to dimension type:
  2851. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimids(idim), dimp, status )
  2852. IF_NOT_OK_RETURN(status=1)
  2853. ! select dimension with zero based index:
  2854. status = sfDimID( varp%hdf4_sdid, idim-1 )
  2855. if ( status == FAIL ) then
  2856. write (gol,'("from sfDimID :")'); call goErr
  2857. write (gol,'(" dimension index : ",i6)') idim; call goErr
  2858. write (gol,'(" variable name : ",a)') trim(name); call goErr
  2859. write (gol,'(" hdf file : ",a)') trim(filep%hdf4_fname); call goErr
  2860. TRACEBACK; status=1; return
  2861. end if
  2862. hdf4_dimid = status
  2863. ! set dimension name
  2864. status = sfSDmName( hdf4_dimid, trim(dimp%name) )
  2865. if ( status == FAIL ) then
  2866. write (gol,'("setting dimension name :")'); call goErr
  2867. write (gol,'(" dim name : ",a)') trim(dimp%name); call goErr
  2868. write (gol,'(" dimension index : ",i6)') idim; call goErr
  2869. write (gol,'(" variable name : ",a)') trim(name); call goErr
  2870. write (gol,'(" hdf file : ",a)') trim(filep%hdf4_fname); call goErr
  2871. TRACEBACK; status=1; return
  2872. end if
  2873. end do ! dimensions
  2874. ! compression specified ?
  2875. if ( present(compression) ) then
  2876. ! apply ?
  2877. if ( compression /= MDF_NONE ) then
  2878. ! check ...
  2879. if ( any( varp%shp == MDF_UNLIMITED ) ) then
  2880. write (gol,'("HDF4 does not allow compresion of data sets with an unlimitted dimension ...")'); call goErr
  2881. TRACEBACK; status=1; return
  2882. end if
  2883. ! which one ?
  2884. select case ( compression )
  2885. ! deflation (=zlib)
  2886. case ( MDF_DEFLATE )
  2887. ! set compression type:
  2888. hdf4_comp_type = COMP_CODE_DEFLATE
  2889. ! set deflation level:
  2890. if ( present(deflate_level) ) then
  2891. hdf4_comp_prm(1) = deflate_level
  2892. else
  2893. hdf4_comp_prm(1) = 6
  2894. end if
  2895. case default
  2896. write (gol,'("unsupported compression type : ",i6)') compression; call goErr
  2897. TRACEBACK; status=1; return
  2898. end select
  2899. ! call HDF routine:
  2900. status = sfsCompress( varp%hdf4_sdid, hdf4_comp_type, hdf4_comp_prm )
  2901. if ( status == FAIL ) then
  2902. write (gol,'("from sfsCompress : ")'); call goErr
  2903. write (gol,'(" compression index : ",i6)') compression; call goErr
  2904. write (gol,'(" compression name : ",a)') trim(MDF_COMPRESSION_NAME(compression)); call goErr
  2905. write (gol,'(" hdf4 compress type : ",i6)') hdf4_comp_type; call goErr
  2906. write (gol,'(" hdf4 compress param : ",i6)') hdf4_comp_prm; call goErr
  2907. write (gol,'(" return status : ",i6)') status; call goErr
  2908. TRACEBACK; status=1; return
  2909. end if
  2910. end if ! apply ?
  2911. end if ! compression ?
  2912. #endif
  2913. #ifdef with_hdf5_beta
  2914. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2915. case ( MDF_HDF5 )
  2916. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2917. ! set data type:
  2918. select case ( xtype )
  2919. case ( MDF_CHAR ) ; hdf5_xtype = H5T_NATIVE_CHARACTER
  2920. case ( MDF_BYTE ) ; hdf5_xtype = H5T_STD_I8LE
  2921. case ( MDF_SHORT ) ; hdf5_xtype = H5T_STD_I16LE
  2922. case ( MDF_INT ) ; hdf5_xtype = H5T_NATIVE_INTEGER
  2923. case ( MDF_FLOAT ) ; hdf5_xtype = H5T_NATIVE_REAL
  2924. case ( MDF_DOUBLE ) ; hdf5_xtype = H5T_NATIVE_DOUBLE
  2925. case default
  2926. write (gol,'("unsupported data type : ",i6)') xtype; call goErr
  2927. TRACEBACK; status=1; return
  2928. end select
  2929. ! data type:
  2930. call H5TCopy_f( hdf5_xtype, hdf5_type_id, status )
  2931. IF_NOT_OK_RETURN(status=1)
  2932. !! set length for characters ?
  2933. !call H5TSet_Size_f( hdf5_type_id, len(values), status )
  2934. !IF_NOT_OK_RETURN(status=1)
  2935. ! extract dimensions:
  2936. do idim = 1, varp%ndim
  2937. ! pointer to dimension type:
  2938. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimids(idim), dimp, status )
  2939. IF_NOT_OK_RETURN(status=1)
  2940. ! fill dimension:
  2941. if ( dimp%length == MDF_UNLIMITED ) then
  2942. varp%hdf5_dims (idim) = 0
  2943. varp%hdf5_maxdims (idim) = H5S_UNLIMITED_F
  2944. varp%hdf5_chunkdims(idim) = 1
  2945. varp%hdf5_chunked = .true.
  2946. else
  2947. varp%hdf5_dims (idim) = dimp%length
  2948. varp%hdf5_maxdims (idim) = dimp%length
  2949. varp%hdf5_chunkdims(idim) = dimp%length
  2950. varp%hdf5_chunked = .false.
  2951. end if
  2952. end do
  2953. ! create data space:
  2954. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_space_id, status, &
  2955. maxdims=varp%hdf5_maxdims(1:varp%ndim) )
  2956. IF_NOT_OK_RETURN(status=1)
  2957. ! dataset creation property list:
  2958. call H5PCreate_f( H5P_DATASET_CREATE_F, hdf5_dcpl_id, status )
  2959. IF_NOT_OK_RETURN(status=1)
  2960. ! for unlimited dimensions ...
  2961. if ( varp%hdf5_chunked ) then
  2962. call H5PSet_Chunk_f( hdf5_dcpl_id, varp%ndim, varp%hdf5_chunkdims(1:varp%ndim), status )
  2963. IF_NOT_OK_RETURN(status=1)
  2964. end if
  2965. ! compression specified ?
  2966. if ( present(compression) ) then
  2967. ! which one ?
  2968. select case ( compression )
  2969. ! no compression ...
  2970. case ( MDF_NONE )
  2971. ! nothing to be done
  2972. ! deflation (=gzip)
  2973. case ( MDF_DEFLATE )
  2974. ! set deflation level:
  2975. if ( present(deflate_level) ) then
  2976. hdf5_deflate_level = deflate_level
  2977. else
  2978. hdf5_deflate_level = 0
  2979. end if
  2980. ! add filter to property list:
  2981. call H5PSet_Deflate_f( hdf5_dcpl_id, hdf5_deflate_level, status )
  2982. IF_NOT_OK_RETURN(status=1)
  2983. case default
  2984. write (gol,'("unsupported compression type : ",i6)') compression; call goErr
  2985. TRACEBACK; status=1; return
  2986. end select
  2987. end if ! compression ?
  2988. ! store name:
  2989. varp%hdf5_name = trim(name)
  2990. ! define variable:
  2991. call H5DCreate_f( filep%hdf5_file_id, trim(name), hdf5_type_id, hdf5_space_id, varp%hdf5_dataset_id, status, &
  2992. dcpl_id=hdf5_dcpl_id )
  2993. IF_NOT_OK_RETURN(status=1)
  2994. ! close property list:
  2995. call H5PClose_f( hdf5_dcpl_id, status )
  2996. IF_NOT_OK_RETURN(status=1)
  2997. ! close data space:
  2998. call H5SClose_f( hdf5_space_id, status )
  2999. IF_NOT_OK_RETURN(status=1)
  3000. ! close data type:
  3001. call H5TClose_f( hdf5_type_id, status )
  3002. IF_NOT_OK_RETURN(status=1)
  3003. #endif
  3004. #ifdef with_netcdf
  3005. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3006. case ( MDF_NETCDF, MDF_NETCDF4 )
  3007. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3008. ! set data type:
  3009. select case ( xtype )
  3010. case ( MDF_CHAR ) ; netcdf_xtype = NF90_CHAR
  3011. case ( MDF_BYTE ) ; netcdf_xtype = NF90_BYTE
  3012. case ( MDF_SHORT ) ; netcdf_xtype = NF90_SHORT
  3013. case ( MDF_INT ) ; netcdf_xtype = NF90_INT
  3014. case ( MDF_FLOAT ) ; netcdf_xtype = NF90_FLOAT
  3015. case ( MDF_DOUBLE ) ; netcdf_xtype = NF90_DOUBLE
  3016. case default
  3017. write (gol,'("unsupported data type : ",i6)') xtype; call goErr
  3018. TRACEBACK; status=1; return
  3019. end select
  3020. ! extract dimensions:
  3021. do idim = 1, varp%ndim
  3022. ! pointer to dimension type:
  3023. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimids(idim), dimp, status )
  3024. IF_NOT_OK_RETURN(status=1)
  3025. ! copy dimension id:
  3026. netcdf_dimids(idim) = dimp%netcdf_dimid
  3027. end do
  3028. ! define variable:
  3029. status = NF90_Def_Var( filep%netcdf_id, trim(name), netcdf_xtype, &
  3030. netcdf_dimids(1:varp%ndim), varp%netcdf_varid )
  3031. IF_NF90_NOT_OK_RETURN(status=1)
  3032. ! compression specified ?
  3033. if ( present(compression) ) then
  3034. ! which one ?
  3035. select case ( compression )
  3036. ! no compression ...
  3037. case ( MDF_NONE )
  3038. ! nothing to be done
  3039. #ifdef with_netcdf4
  3040. ! deflation (=zlib)
  3041. case ( MDF_DEFLATE )
  3042. ! set deflation level:
  3043. if ( present(deflate_level) ) then
  3044. netcdf_deflate_level = deflate_level
  3045. else
  3046. netcdf_deflate_level = 0
  3047. end if
  3048. ! set parameters (without shuffle, with deflate)
  3049. status = NF90_Def_Var_Deflate( filep%netcdf_id, varp%netcdf_varid, 0, 1, netcdf_deflate_level )
  3050. IF_NF90_NOT_OK_RETURN(status=1)
  3051. #endif
  3052. case default
  3053. write (gol,'("unsupported compression type : ",i6)') compression; call goErr
  3054. write (gol,'("(might be necessary to compile with macro `with_netcdf4` defined)")'); call goErr
  3055. TRACEBACK; status=1; return
  3056. end select
  3057. end if ! compression ?
  3058. #endif
  3059. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3060. case default
  3061. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3062. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3063. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3064. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3065. TRACEBACK; status=1; return
  3066. end select
  3067. end do ! file types
  3068. ! no attributes yet:
  3069. varp%natt = 0
  3070. ! ok
  3071. status = 0
  3072. end subroutine MDF_Def_Var
  3073. ! ***
  3074. !--------------------------------------------------------------------------
  3075. ! TM5 !
  3076. !--------------------------------------------------------------------------
  3077. !BOP
  3078. !
  3079. ! !IROUTINE: MDF_Var_Par_Access
  3080. !
  3081. ! !DESCRIPTION: Wrapper around NF90_Var_Par_Access. It changes whether read
  3082. ! /write operations on a parallel file system are performed
  3083. ! collectively or independently (the default) on the variable.
  3084. !\\
  3085. !\\
  3086. ! !INTERFACE:
  3087. !
  3088. subroutine MDF_Var_Par_Access( hid, varid, par_access_mode, status )
  3089. !
  3090. ! !USES:
  3091. !
  3092. #ifdef with_netcdf4_par
  3093. use NetCDF, only : NF90_INDEPENDENT, NF90_COLLECTIVE
  3094. use NetCDF, only : NF90_Var_Par_Access
  3095. #endif
  3096. !
  3097. ! !INPUT PARAMETERS:
  3098. !
  3099. integer, intent(in) :: hid
  3100. integer, intent(in) :: varid
  3101. integer, intent(in) :: par_access_mode
  3102. !
  3103. ! !OUTPUT PARAMETERS:
  3104. !
  3105. integer, intent(out) :: status
  3106. !
  3107. ! !REVISION HISTORY:
  3108. ! 13 Jan 2012 - Philippe Le Sager - added COLLECTIVE case
  3109. !
  3110. ! !REMARKS:
  3111. !
  3112. !EOP
  3113. !------------------------------------------------------------------------
  3114. !BOC
  3115. character(len=*), parameter :: rname = mname//'/MDF_Var_Par_Access'
  3116. ! --- local --------------------------------------
  3117. type(MDF_File), pointer :: filep
  3118. type(MDF_Var), pointer :: varp
  3119. integer :: iftype
  3120. integer :: ftype
  3121. #ifdef with_netcdf4_par
  3122. integer :: netcdf_par_access_mode
  3123. #endif
  3124. ! --- begin --------------------------------------
  3125. ! pointer to file structure:
  3126. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3127. IF_NOT_OK_RETURN(status=1)
  3128. ! opened for parallel i/o ?
  3129. if ( filep%parallel ) then
  3130. ! pointer to variable structure:
  3131. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3132. IF_NOT_OK_RETURN(status=1)
  3133. ! loop over file types:
  3134. do iftype = 1, filep%nftype
  3135. ! current type:
  3136. ftype = filep%ftypes(iftype)
  3137. ! select appropriate routine for each type:
  3138. select case ( ftype )
  3139. #ifdef with_netcdf4
  3140. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3141. case ( MDF_NETCDF4 )
  3142. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3143. #ifdef with_netcdf4_par
  3144. ! set mode:
  3145. select case ( par_access_mode )
  3146. case ( MDF_INDEPENDENT ) ; netcdf_par_access_mode = NF90_INDEPENDENT
  3147. case ( MDF_COLLECTIVE ) ; netcdf_par_access_mode = NF90_COLLECTIVE
  3148. case default
  3149. write (gol,'("unsupported parallel access mode : ",i6)') par_access_mode; call goErr
  3150. TRACEBACK; status=1; return
  3151. end select
  3152. ! set access mode:
  3153. status = NF90_Var_Par_Access( filep%netcdf_id, varp%netcdf_varid, netcdf_par_access_mode )
  3154. IF_NF90_NOT_OK_RETURN(status=1)
  3155. #else
  3156. write (gol,'("Parallel access of NetCDF requires compilation with `with_netcdf4_par` macro defined.")'); call goErr
  3157. TRACEBACK; status=1; return
  3158. #endif
  3159. #endif
  3160. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3161. case default
  3162. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3163. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3164. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3165. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3166. TRACEBACK; status=1; return
  3167. end select
  3168. end do ! file types
  3169. end if ! parallel i/o
  3170. ! ok
  3171. status = 0
  3172. end subroutine MDF_Var_Par_Access
  3173. !EOC
  3174. ! ***
  3175. subroutine MDF_Put_Var_c1_1d( hid, varid, values, status, &
  3176. start, count, stride, map )
  3177. #ifdef with_hdf5_beta
  3178. use HDF5, only : HID_T, HSIZE_T
  3179. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  3180. use HDF5, only : H5T_NATIVE_CHARACTER
  3181. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  3182. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  3183. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  3184. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  3185. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  3186. #endif
  3187. #ifdef with_netcdf
  3188. use NetCDF, only : NF90_Put_Var
  3189. #endif
  3190. ! --- in/out -------------------------------------
  3191. integer, intent(in) :: hid
  3192. integer, intent(in) :: varid
  3193. character(len=*), intent(in) :: values
  3194. integer, intent(out) :: status
  3195. integer, intent(in), optional :: start (:)
  3196. integer, intent(in), optional :: count (:)
  3197. integer, intent(in), optional :: stride(:)
  3198. integer, intent(in), optional :: map (:)
  3199. ! --- const --------------------------------------
  3200. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_1d'
  3201. ! --- external -----------------------------------
  3202. #ifdef with_hdf4
  3203. integer(hdf4_wpi), external :: sfWData
  3204. #endif
  3205. ! --- local --------------------------------------
  3206. type(MDF_File), pointer :: filep
  3207. type(MDF_Var), pointer :: varp
  3208. integer :: iftype
  3209. integer :: ftype
  3210. #ifdef with_hdf4
  3211. integer :: hdf4_offset(MAX_RANK)
  3212. integer :: hdf4_stride(MAX_RANK)
  3213. integer :: hdf4_count(MAX_RANK)
  3214. #endif
  3215. #ifdef with_hdf5_beta
  3216. !integer(HID_T) :: hdf5_type_id
  3217. integer(HID_T) :: hdf5_file_space_id
  3218. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  3219. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  3220. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  3221. #endif
  3222. ! --- begin --------------------------------------
  3223. ! pointer to file structure:
  3224. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3225. IF_NOT_OK_RETURN(status=1)
  3226. ! pointer to variable structure:
  3227. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3228. IF_NOT_OK_RETURN(status=1)
  3229. ! check ...
  3230. if ( size(shape(values)) > varp%ndim ) then
  3231. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  3232. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  3233. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  3234. TRACEBACK; status=1; return
  3235. end if
  3236. ! check ...
  3237. if ( present(start ) ) then
  3238. if ( size(start ) /= varp%ndim ) then
  3239. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3240. write (gol,'(" size start : ",i6)') size(start ); call goErr
  3241. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3242. TRACEBACK; status=1; return
  3243. end if
  3244. end if
  3245. if ( present(count ) ) then
  3246. if ( size(count ) /= varp%ndim ) then
  3247. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3248. write (gol,'(" size count : ",i6)') size(count ); call goErr
  3249. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3250. TRACEBACK; status=1; return
  3251. end if
  3252. end if
  3253. if ( present(stride ) ) then
  3254. if ( size(stride ) /= varp%ndim ) then
  3255. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3256. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  3257. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3258. TRACEBACK; status=1; return
  3259. end if
  3260. end if
  3261. if ( present(map ) ) then
  3262. if ( size(map ) /= varp%ndim ) then
  3263. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3264. write (gol,'(" size map : ",i6)') size(map ); call goErr
  3265. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3266. TRACEBACK; status=1; return
  3267. end if
  3268. end if
  3269. ! loop over file types:
  3270. do iftype = 1, filep%nftype
  3271. ! current type:
  3272. ftype = filep%ftypes(iftype)
  3273. ! select appropriate routine for each type:
  3274. select case ( ftype )
  3275. #ifdef with_hdf4
  3276. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3277. case ( MDF_HDF4 )
  3278. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3279. ! check ...
  3280. if ( present(map ) ) then
  3281. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  3282. TRACEBACK; status=1; return
  3283. end if
  3284. ! fill offset (zero based!) and stride with default values:
  3285. hdf4_offset = 0
  3286. hdf4_stride = 1
  3287. ! count is by default the shape; padd with singleton dimensions:
  3288. hdf4_count = 1; hdf4_count(1:1) = (/len(values)/)
  3289. ! replace by optional arguments if necessary:
  3290. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  3291. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  3292. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  3293. ! write:
  3294. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  3295. #endif
  3296. #ifdef with_hdf5_beta
  3297. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3298. case ( MDF_HDF5 )
  3299. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3300. ! check ...
  3301. if ( present(map ) ) then
  3302. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  3303. TRACEBACK; status=1; return
  3304. end if
  3305. ! fill offset (zero based!), stride, and count :
  3306. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  3307. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  3308. hdf5_count = 1 ! default singleton dimension
  3309. if ( present(count) ) then
  3310. hdf5_count(1:varp%ndim) = count
  3311. else
  3312. hdf5_count(1:1) = (/len(values)/)
  3313. end if
  3314. ! new dimension:
  3315. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  3316. ! target data space in file:
  3317. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  3318. IF_NOT_OK_RETURN(status=1)
  3319. ! chunked dataset ?
  3320. if ( varp%hdf5_chunked ) then
  3321. ! reset extend:
  3322. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  3323. IF_NOT_OK_RETURN(status=1)
  3324. end if
  3325. ! select hyperslab:
  3326. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  3327. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  3328. stride=hdf5_stride(1:varp%ndim) )
  3329. ! write data:
  3330. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  3331. int(shape(values),kind=HSIZE_T), status, &
  3332. file_space_id=hdf5_file_space_id )
  3333. IF_NOT_OK_RETURN(status=1)
  3334. ! release data space:
  3335. call H5SClose_f( hdf5_file_space_id, status )
  3336. IF_NOT_OK_RETURN(status=1)
  3337. #endif
  3338. #ifdef with_netcdf
  3339. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3340. case ( MDF_NETCDF, MDF_NETCDF4 )
  3341. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3342. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3343. start, count, stride, map )
  3344. IF_NF90_NOT_OK_RETURN(status=1)
  3345. ! just put; let netcdf library convert the right kind:
  3346. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3347. ! start, count, stride, map )
  3348. !IF_NF90_NOT_OK_RETURN(status=1)
  3349. #endif
  3350. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3351. case default
  3352. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3353. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3354. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3355. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3356. TRACEBACK; status=1; return
  3357. end select
  3358. end do ! file types
  3359. ! ok
  3360. status = 0
  3361. end subroutine MDF_Put_Var_c1_1d
  3362. ! ***
  3363. subroutine MDF_Get_Var_c1_1d( hid, varid, values, status, &
  3364. start, count, stride, map )
  3365. #ifdef with_netcdf
  3366. use NetCDF, only : NF90_Get_Var
  3367. #endif
  3368. ! --- in/out -------------------------------------
  3369. integer, intent(in) :: hid
  3370. integer, intent(in) :: varid
  3371. character(len=*), intent(out) :: values
  3372. integer, intent(out) :: status
  3373. integer, intent(in), optional :: start (:)
  3374. integer, intent(in), optional :: count (:)
  3375. integer, intent(in), optional :: stride(:)
  3376. integer, intent(in), optional :: map (:)
  3377. ! --- const --------------------------------------
  3378. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_1d'
  3379. ! --- external -----------------------------------
  3380. #ifdef with_hdf4
  3381. integer(hdf4_wpi), external :: sfRData
  3382. #endif
  3383. ! --- local --------------------------------------
  3384. type(MDF_File), pointer :: filep
  3385. type(MDF_Var), pointer :: varp
  3386. integer :: iftype
  3387. integer :: ftype
  3388. #ifdef with_hdf4
  3389. integer :: hdf4_offset(MAX_RANK)
  3390. integer :: hdf4_stride(MAX_RANK)
  3391. integer :: hdf4_count(MAX_RANK)
  3392. #endif
  3393. ! --- begin --------------------------------------
  3394. ! pointer to file structure:
  3395. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3396. IF_NOT_OK_RETURN(status=1)
  3397. ! pointer to variable structure:
  3398. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3399. IF_NOT_OK_RETURN(status=1)
  3400. ! check ...
  3401. if ( size(shape(values)) > varp%ndim ) then
  3402. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  3403. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  3404. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  3405. TRACEBACK; status=1; return
  3406. end if
  3407. ! check ...
  3408. if ( present(start ) ) then
  3409. if ( size(start ) /= varp%ndim ) then
  3410. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3411. write (gol,'(" size start : ",i6)') size(start ); call goErr
  3412. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3413. TRACEBACK; status=1; return
  3414. end if
  3415. end if
  3416. if ( present(count ) ) then
  3417. if ( size(count ) /= varp%ndim ) then
  3418. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3419. write (gol,'(" size count : ",i6)') size(count ); call goErr
  3420. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3421. TRACEBACK; status=1; return
  3422. end if
  3423. end if
  3424. if ( present(stride ) ) then
  3425. if ( size(stride ) /= varp%ndim ) then
  3426. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3427. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  3428. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3429. TRACEBACK; status=1; return
  3430. end if
  3431. end if
  3432. if ( present(map ) ) then
  3433. if ( size(map ) /= varp%ndim ) then
  3434. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3435. write (gol,'(" size map : ",i6)') size(map ); call goErr
  3436. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3437. TRACEBACK; status=1; return
  3438. end if
  3439. end if
  3440. ! loop over file types:
  3441. do iftype = 1, filep%nftype
  3442. ! current type:
  3443. ftype = filep%ftypes(iftype)
  3444. ! select appropriate routine for each type:
  3445. select case ( ftype )
  3446. #ifdef with_hdf4
  3447. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3448. case ( MDF_HDF4 )
  3449. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3450. ! check ...
  3451. if ( present(map ) ) then
  3452. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  3453. TRACEBACK; status=1; return
  3454. end if
  3455. ! fill offset (zero based!), stride, and count :
  3456. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  3457. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  3458. hdf4_count = 1 ! default singleton dimension
  3459. hdf4_count(1:1) = (/ len(values) /)
  3460. ! read:
  3461. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  3462. #endif
  3463. #ifdef with_netcdf
  3464. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3465. case ( MDF_NETCDF, MDF_NETCDF4 )
  3466. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3467. ! read values, converted automatically:
  3468. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3469. start, count, stride, map )
  3470. IF_NF90_NOT_OK_RETURN(status=1)
  3471. #endif
  3472. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3473. case default
  3474. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3475. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3476. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3477. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3478. TRACEBACK; status=1; return
  3479. end select
  3480. end do ! file types
  3481. ! ok
  3482. status = 0
  3483. end subroutine MDF_Get_Var_c1_1d
  3484. ! ***
  3485. subroutine MDF_Put_Var_c1_2d( hid, varid, values, status, &
  3486. start, count, stride, map )
  3487. #ifdef with_hdf5_beta
  3488. use HDF5, only : HID_T, HSIZE_T
  3489. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  3490. use HDF5, only : H5T_NATIVE_CHARACTER
  3491. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  3492. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  3493. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  3494. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  3495. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  3496. #endif
  3497. #ifdef with_netcdf
  3498. use NetCDF, only : NF90_Put_Var
  3499. #endif
  3500. ! --- in/out -------------------------------------
  3501. integer, intent(in) :: hid
  3502. integer, intent(in) :: varid
  3503. character(len=*), intent(in) :: values(:)
  3504. integer, intent(out) :: status
  3505. integer, intent(in), optional :: start (:)
  3506. integer, intent(in), optional :: count (:)
  3507. integer, intent(in), optional :: stride(:)
  3508. integer, intent(in), optional :: map (:)
  3509. ! --- const --------------------------------------
  3510. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_2d'
  3511. ! --- external -----------------------------------
  3512. #ifdef with_hdf4
  3513. integer(hdf4_wpi), external :: sfWData
  3514. #endif
  3515. ! --- local --------------------------------------
  3516. type(MDF_File), pointer :: filep
  3517. type(MDF_Var), pointer :: varp
  3518. integer :: iftype
  3519. integer :: ftype
  3520. #ifdef with_hdf4
  3521. integer :: hdf4_offset(MAX_RANK)
  3522. integer :: hdf4_stride(MAX_RANK)
  3523. integer :: hdf4_count(MAX_RANK)
  3524. #endif
  3525. #ifdef with_hdf5_beta
  3526. !integer(HID_T) :: hdf5_type_id
  3527. integer(HID_T) :: hdf5_file_space_id
  3528. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  3529. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  3530. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  3531. #endif
  3532. ! --- begin --------------------------------------
  3533. ! pointer to file structure:
  3534. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3535. IF_NOT_OK_RETURN(status=1)
  3536. ! pointer to variable structure:
  3537. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3538. IF_NOT_OK_RETURN(status=1)
  3539. ! check ...
  3540. if ( size(shape(values)) > varp%ndim ) then
  3541. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  3542. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  3543. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  3544. TRACEBACK; status=1; return
  3545. end if
  3546. ! check ...
  3547. if ( present(start ) ) then
  3548. if ( size(start ) /= varp%ndim ) then
  3549. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3550. write (gol,'(" size start : ",i6)') size(start ); call goErr
  3551. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3552. TRACEBACK; status=1; return
  3553. end if
  3554. end if
  3555. if ( present(count ) ) then
  3556. if ( size(count ) /= varp%ndim ) then
  3557. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3558. write (gol,'(" size count : ",i6)') size(count ); call goErr
  3559. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3560. TRACEBACK; status=1; return
  3561. end if
  3562. end if
  3563. if ( present(stride ) ) then
  3564. if ( size(stride ) /= varp%ndim ) then
  3565. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3566. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  3567. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3568. TRACEBACK; status=1; return
  3569. end if
  3570. end if
  3571. if ( present(map ) ) then
  3572. if ( size(map ) /= varp%ndim ) then
  3573. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3574. write (gol,'(" size map : ",i6)') size(map ); call goErr
  3575. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3576. TRACEBACK; status=1; return
  3577. end if
  3578. end if
  3579. ! loop over file types:
  3580. do iftype = 1, filep%nftype
  3581. ! current type:
  3582. ftype = filep%ftypes(iftype)
  3583. ! select appropriate routine for each type:
  3584. select case ( ftype )
  3585. #ifdef with_hdf4
  3586. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3587. case ( MDF_HDF4 )
  3588. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3589. ! check ...
  3590. if ( present(map ) ) then
  3591. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  3592. TRACEBACK; status=1; return
  3593. end if
  3594. ! fill offset (zero based!) and stride with default values:
  3595. hdf4_offset = 0
  3596. hdf4_stride = 1
  3597. ! count is by default the shape; padd with singleton dimensions:
  3598. hdf4_count = 1; hdf4_count(1:2) = (/len(values),shape(values)/)
  3599. ! replace by optional arguments if necessary:
  3600. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  3601. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  3602. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  3603. ! write:
  3604. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  3605. #endif
  3606. #ifdef with_hdf5_beta
  3607. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3608. case ( MDF_HDF5 )
  3609. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3610. ! check ...
  3611. if ( present(map ) ) then
  3612. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  3613. TRACEBACK; status=1; return
  3614. end if
  3615. ! fill offset (zero based!), stride, and count :
  3616. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  3617. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  3618. hdf5_count = 1 ! default singleton dimension
  3619. if ( present(count) ) then
  3620. hdf5_count(1:varp%ndim) = count
  3621. else
  3622. hdf5_count(1:2) = (/len(values),shape(values)/)
  3623. end if
  3624. ! new dimension:
  3625. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  3626. ! target data space in file:
  3627. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  3628. IF_NOT_OK_RETURN(status=1)
  3629. ! chunked dataset ?
  3630. if ( varp%hdf5_chunked ) then
  3631. ! reset extend:
  3632. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  3633. IF_NOT_OK_RETURN(status=1)
  3634. end if
  3635. ! select hyperslab:
  3636. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  3637. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  3638. stride=hdf5_stride(1:varp%ndim) )
  3639. ! write data:
  3640. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  3641. int(shape(values),kind=HSIZE_T), status, &
  3642. file_space_id=hdf5_file_space_id )
  3643. IF_NOT_OK_RETURN(status=1)
  3644. ! release data space:
  3645. call H5SClose_f( hdf5_file_space_id, status )
  3646. IF_NOT_OK_RETURN(status=1)
  3647. #endif
  3648. #ifdef with_netcdf
  3649. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3650. case ( MDF_NETCDF, MDF_NETCDF4 )
  3651. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3652. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3653. start, count, stride, map )
  3654. IF_NF90_NOT_OK_RETURN(status=1)
  3655. ! just put; let netcdf library convert the right kind:
  3656. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3657. ! start, count, stride, map )
  3658. !IF_NF90_NOT_OK_RETURN(status=1)
  3659. #endif
  3660. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3661. case default
  3662. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3663. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3664. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3665. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3666. TRACEBACK; status=1; return
  3667. end select
  3668. end do ! file types
  3669. ! ok
  3670. status = 0
  3671. end subroutine MDF_Put_Var_c1_2d
  3672. ! ***
  3673. subroutine MDF_Get_Var_c1_2d( hid, varid, values, status, &
  3674. start, count, stride, map )
  3675. #ifdef with_netcdf
  3676. use NetCDF, only : NF90_Get_Var
  3677. #endif
  3678. ! --- in/out -------------------------------------
  3679. integer, intent(in) :: hid
  3680. integer, intent(in) :: varid
  3681. character(len=*), intent(out) :: values(:)
  3682. integer, intent(out) :: status
  3683. integer, intent(in), optional :: start (:)
  3684. integer, intent(in), optional :: count (:)
  3685. integer, intent(in), optional :: stride(:)
  3686. integer, intent(in), optional :: map (:)
  3687. ! --- const --------------------------------------
  3688. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_2d'
  3689. ! --- external -----------------------------------
  3690. #ifdef with_hdf4
  3691. integer(hdf4_wpi), external :: sfRData
  3692. #endif
  3693. ! --- local --------------------------------------
  3694. type(MDF_File), pointer :: filep
  3695. type(MDF_Var), pointer :: varp
  3696. integer :: iftype
  3697. integer :: ftype
  3698. #ifdef with_hdf4
  3699. integer :: hdf4_offset(MAX_RANK)
  3700. integer :: hdf4_stride(MAX_RANK)
  3701. integer :: hdf4_count(MAX_RANK)
  3702. #endif
  3703. ! --- begin --------------------------------------
  3704. ! pointer to file structure:
  3705. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3706. IF_NOT_OK_RETURN(status=1)
  3707. ! pointer to variable structure:
  3708. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3709. IF_NOT_OK_RETURN(status=1)
  3710. ! check ...
  3711. if ( size(shape(values)) > varp%ndim ) then
  3712. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  3713. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  3714. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  3715. TRACEBACK; status=1; return
  3716. end if
  3717. ! check ...
  3718. if ( present(start ) ) then
  3719. if ( size(start ) /= varp%ndim ) then
  3720. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3721. write (gol,'(" size start : ",i6)') size(start ); call goErr
  3722. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3723. TRACEBACK; status=1; return
  3724. end if
  3725. end if
  3726. if ( present(count ) ) then
  3727. if ( size(count ) /= varp%ndim ) then
  3728. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3729. write (gol,'(" size count : ",i6)') size(count ); call goErr
  3730. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3731. TRACEBACK; status=1; return
  3732. end if
  3733. end if
  3734. if ( present(stride ) ) then
  3735. if ( size(stride ) /= varp%ndim ) then
  3736. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3737. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  3738. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3739. TRACEBACK; status=1; return
  3740. end if
  3741. end if
  3742. if ( present(map ) ) then
  3743. if ( size(map ) /= varp%ndim ) then
  3744. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3745. write (gol,'(" size map : ",i6)') size(map ); call goErr
  3746. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3747. TRACEBACK; status=1; return
  3748. end if
  3749. end if
  3750. ! loop over file types:
  3751. do iftype = 1, filep%nftype
  3752. ! current type:
  3753. ftype = filep%ftypes(iftype)
  3754. ! select appropriate routine for each type:
  3755. select case ( ftype )
  3756. #ifdef with_hdf4
  3757. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3758. case ( MDF_HDF4 )
  3759. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3760. ! check ...
  3761. if ( present(map ) ) then
  3762. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  3763. TRACEBACK; status=1; return
  3764. end if
  3765. ! fill offset (zero based!), stride, and count :
  3766. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  3767. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  3768. hdf4_count = 1 ! default singleton dimension
  3769. hdf4_count(1:2) = (/ len(values), shape(values) /)
  3770. ! read:
  3771. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  3772. #endif
  3773. #ifdef with_netcdf
  3774. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3775. case ( MDF_NETCDF, MDF_NETCDF4 )
  3776. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3777. ! read values, converted automatically:
  3778. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3779. start, count, stride, map )
  3780. IF_NF90_NOT_OK_RETURN(status=1)
  3781. #endif
  3782. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3783. case default
  3784. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3785. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3786. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3787. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3788. TRACEBACK; status=1; return
  3789. end select
  3790. end do ! file types
  3791. ! ok
  3792. status = 0
  3793. end subroutine MDF_Get_Var_c1_2d
  3794. ! ***
  3795. subroutine MDF_Put_Var_c1_3d( hid, varid, values, status, &
  3796. start, count, stride, map )
  3797. #ifdef with_hdf5_beta
  3798. use HDF5, only : HID_T, HSIZE_T
  3799. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  3800. use HDF5, only : H5T_NATIVE_CHARACTER
  3801. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  3802. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  3803. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  3804. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  3805. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  3806. #endif
  3807. #ifdef with_netcdf
  3808. use NetCDF, only : NF90_Put_Var
  3809. #endif
  3810. ! --- in/out -------------------------------------
  3811. integer, intent(in) :: hid
  3812. integer, intent(in) :: varid
  3813. character(len=*), intent(in) :: values(:,:)
  3814. integer, intent(out) :: status
  3815. integer, intent(in), optional :: start (:)
  3816. integer, intent(in), optional :: count (:)
  3817. integer, intent(in), optional :: stride(:)
  3818. integer, intent(in), optional :: map (:)
  3819. ! --- const --------------------------------------
  3820. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_3d'
  3821. ! --- external -----------------------------------
  3822. #ifdef with_hdf4
  3823. integer(hdf4_wpi), external :: sfWData
  3824. #endif
  3825. ! --- local --------------------------------------
  3826. type(MDF_File), pointer :: filep
  3827. type(MDF_Var), pointer :: varp
  3828. integer :: iftype
  3829. integer :: ftype
  3830. #ifdef with_hdf4
  3831. integer :: hdf4_offset(MAX_RANK)
  3832. integer :: hdf4_stride(MAX_RANK)
  3833. integer :: hdf4_count(MAX_RANK)
  3834. #endif
  3835. #ifdef with_hdf5_beta
  3836. !integer(HID_T) :: hdf5_type_id
  3837. integer(HID_T) :: hdf5_file_space_id
  3838. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  3839. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  3840. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  3841. #endif
  3842. ! --- begin --------------------------------------
  3843. ! pointer to file structure:
  3844. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  3845. IF_NOT_OK_RETURN(status=1)
  3846. ! pointer to variable structure:
  3847. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  3848. IF_NOT_OK_RETURN(status=1)
  3849. ! check ...
  3850. if ( size(shape(values)) > varp%ndim ) then
  3851. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  3852. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  3853. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  3854. TRACEBACK; status=1; return
  3855. end if
  3856. ! check ...
  3857. if ( present(start ) ) then
  3858. if ( size(start ) /= varp%ndim ) then
  3859. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3860. write (gol,'(" size start : ",i6)') size(start ); call goErr
  3861. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3862. TRACEBACK; status=1; return
  3863. end if
  3864. end if
  3865. if ( present(count ) ) then
  3866. if ( size(count ) /= varp%ndim ) then
  3867. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3868. write (gol,'(" size count : ",i6)') size(count ); call goErr
  3869. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3870. TRACEBACK; status=1; return
  3871. end if
  3872. end if
  3873. if ( present(stride ) ) then
  3874. if ( size(stride ) /= varp%ndim ) then
  3875. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3876. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  3877. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3878. TRACEBACK; status=1; return
  3879. end if
  3880. end if
  3881. if ( present(map ) ) then
  3882. if ( size(map ) /= varp%ndim ) then
  3883. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  3884. write (gol,'(" size map : ",i6)') size(map ); call goErr
  3885. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  3886. TRACEBACK; status=1; return
  3887. end if
  3888. end if
  3889. ! loop over file types:
  3890. do iftype = 1, filep%nftype
  3891. ! current type:
  3892. ftype = filep%ftypes(iftype)
  3893. ! select appropriate routine for each type:
  3894. select case ( ftype )
  3895. #ifdef with_hdf4
  3896. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3897. case ( MDF_HDF4 )
  3898. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3899. ! check ...
  3900. if ( present(map ) ) then
  3901. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  3902. TRACEBACK; status=1; return
  3903. end if
  3904. ! fill offset (zero based!) and stride with default values:
  3905. hdf4_offset = 0
  3906. hdf4_stride = 1
  3907. ! count is by default the shape; padd with singleton dimensions:
  3908. hdf4_count = 1; hdf4_count(1:3) = (/len(values),shape(values)/)
  3909. ! replace by optional arguments if necessary:
  3910. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  3911. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  3912. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  3913. ! write:
  3914. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  3915. #endif
  3916. #ifdef with_hdf5_beta
  3917. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3918. case ( MDF_HDF5 )
  3919. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3920. ! check ...
  3921. if ( present(map ) ) then
  3922. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  3923. TRACEBACK; status=1; return
  3924. end if
  3925. ! fill offset (zero based!), stride, and count :
  3926. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  3927. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  3928. hdf5_count = 1 ! default singleton dimension
  3929. if ( present(count) ) then
  3930. hdf5_count(1:varp%ndim) = count
  3931. else
  3932. hdf5_count(1:3) = (/len(values),shape(values)/)
  3933. end if
  3934. ! new dimension:
  3935. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  3936. ! target data space in file:
  3937. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  3938. IF_NOT_OK_RETURN(status=1)
  3939. ! chunked dataset ?
  3940. if ( varp%hdf5_chunked ) then
  3941. ! reset extend:
  3942. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  3943. IF_NOT_OK_RETURN(status=1)
  3944. end if
  3945. ! select hyperslab:
  3946. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  3947. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  3948. stride=hdf5_stride(1:varp%ndim) )
  3949. ! write data:
  3950. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  3951. int(shape(values),kind=HSIZE_T), status, &
  3952. file_space_id=hdf5_file_space_id )
  3953. IF_NOT_OK_RETURN(status=1)
  3954. ! release data space:
  3955. call H5SClose_f( hdf5_file_space_id, status )
  3956. IF_NOT_OK_RETURN(status=1)
  3957. #endif
  3958. #ifdef with_netcdf
  3959. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3960. case ( MDF_NETCDF, MDF_NETCDF4 )
  3961. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3962. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3963. start, count, stride, map )
  3964. IF_NF90_NOT_OK_RETURN(status=1)
  3965. ! just put; let netcdf library convert the right kind:
  3966. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  3967. ! start, count, stride, map )
  3968. !IF_NF90_NOT_OK_RETURN(status=1)
  3969. #endif
  3970. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3971. case default
  3972. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3973. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  3974. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  3975. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  3976. TRACEBACK; status=1; return
  3977. end select
  3978. end do ! file types
  3979. ! ok
  3980. status = 0
  3981. end subroutine MDF_Put_Var_c1_3d
  3982. ! ***
  3983. subroutine MDF_Get_Var_c1_3d( hid, varid, values, status, &
  3984. start, count, stride, map )
  3985. #ifdef with_netcdf
  3986. use NetCDF, only : NF90_Get_Var
  3987. #endif
  3988. ! --- in/out -------------------------------------
  3989. integer, intent(in) :: hid
  3990. integer, intent(in) :: varid
  3991. character(len=*), intent(out) :: values(:,:)
  3992. integer, intent(out) :: status
  3993. integer, intent(in), optional :: start (:)
  3994. integer, intent(in), optional :: count (:)
  3995. integer, intent(in), optional :: stride(:)
  3996. integer, intent(in), optional :: map (:)
  3997. ! --- const --------------------------------------
  3998. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_3d'
  3999. ! --- external -----------------------------------
  4000. #ifdef with_hdf4
  4001. integer(hdf4_wpi), external :: sfRData
  4002. #endif
  4003. ! --- local --------------------------------------
  4004. type(MDF_File), pointer :: filep
  4005. type(MDF_Var), pointer :: varp
  4006. integer :: iftype
  4007. integer :: ftype
  4008. #ifdef with_hdf4
  4009. integer :: hdf4_offset(MAX_RANK)
  4010. integer :: hdf4_stride(MAX_RANK)
  4011. integer :: hdf4_count(MAX_RANK)
  4012. #endif
  4013. ! --- begin --------------------------------------
  4014. ! pointer to file structure:
  4015. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4016. IF_NOT_OK_RETURN(status=1)
  4017. ! pointer to variable structure:
  4018. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4019. IF_NOT_OK_RETURN(status=1)
  4020. ! check ...
  4021. if ( size(shape(values)) > varp%ndim ) then
  4022. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  4023. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4024. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4025. TRACEBACK; status=1; return
  4026. end if
  4027. ! check ...
  4028. if ( present(start ) ) then
  4029. if ( size(start ) /= varp%ndim ) then
  4030. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4031. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4032. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4033. TRACEBACK; status=1; return
  4034. end if
  4035. end if
  4036. if ( present(count ) ) then
  4037. if ( size(count ) /= varp%ndim ) then
  4038. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4039. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4040. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4041. TRACEBACK; status=1; return
  4042. end if
  4043. end if
  4044. if ( present(stride ) ) then
  4045. if ( size(stride ) /= varp%ndim ) then
  4046. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4047. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4048. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4049. TRACEBACK; status=1; return
  4050. end if
  4051. end if
  4052. if ( present(map ) ) then
  4053. if ( size(map ) /= varp%ndim ) then
  4054. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4055. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4056. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4057. TRACEBACK; status=1; return
  4058. end if
  4059. end if
  4060. ! loop over file types:
  4061. do iftype = 1, filep%nftype
  4062. ! current type:
  4063. ftype = filep%ftypes(iftype)
  4064. ! select appropriate routine for each type:
  4065. select case ( ftype )
  4066. #ifdef with_hdf4
  4067. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4068. case ( MDF_HDF4 )
  4069. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4070. ! check ...
  4071. if ( present(map ) ) then
  4072. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4073. TRACEBACK; status=1; return
  4074. end if
  4075. ! fill offset (zero based!), stride, and count :
  4076. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4077. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4078. hdf4_count = 1 ! default singleton dimension
  4079. hdf4_count(1:3) = (/ len(values), shape(values) /)
  4080. ! read:
  4081. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4082. #endif
  4083. #ifdef with_netcdf
  4084. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4085. case ( MDF_NETCDF, MDF_NETCDF4 )
  4086. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4087. ! read values, converted automatically:
  4088. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4089. start, count, stride, map )
  4090. IF_NF90_NOT_OK_RETURN(status=1)
  4091. #endif
  4092. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4093. case default
  4094. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4095. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4096. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4097. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4098. TRACEBACK; status=1; return
  4099. end select
  4100. end do ! file types
  4101. ! ok
  4102. status = 0
  4103. end subroutine MDF_Get_Var_c1_3d
  4104. ! ***
  4105. subroutine MDF_Put_Var_c1_4d( hid, varid, values, status, &
  4106. start, count, stride, map )
  4107. #ifdef with_hdf5_beta
  4108. use HDF5, only : HID_T, HSIZE_T
  4109. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  4110. use HDF5, only : H5T_NATIVE_CHARACTER
  4111. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  4112. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  4113. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  4114. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  4115. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  4116. #endif
  4117. #ifdef with_netcdf
  4118. use NetCDF, only : NF90_Put_Var
  4119. #endif
  4120. ! --- in/out -------------------------------------
  4121. integer, intent(in) :: hid
  4122. integer, intent(in) :: varid
  4123. character(len=*), intent(in) :: values(:,:,:)
  4124. integer, intent(out) :: status
  4125. integer, intent(in), optional :: start (:)
  4126. integer, intent(in), optional :: count (:)
  4127. integer, intent(in), optional :: stride(:)
  4128. integer, intent(in), optional :: map (:)
  4129. ! --- const --------------------------------------
  4130. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_4d'
  4131. ! --- external -----------------------------------
  4132. #ifdef with_hdf4
  4133. integer(hdf4_wpi), external :: sfWData
  4134. #endif
  4135. ! --- local --------------------------------------
  4136. type(MDF_File), pointer :: filep
  4137. type(MDF_Var), pointer :: varp
  4138. integer :: iftype
  4139. integer :: ftype
  4140. #ifdef with_hdf4
  4141. integer :: hdf4_offset(MAX_RANK)
  4142. integer :: hdf4_stride(MAX_RANK)
  4143. integer :: hdf4_count(MAX_RANK)
  4144. #endif
  4145. #ifdef with_hdf5_beta
  4146. !integer(HID_T) :: hdf5_type_id
  4147. integer(HID_T) :: hdf5_file_space_id
  4148. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  4149. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  4150. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  4151. #endif
  4152. ! --- begin --------------------------------------
  4153. ! pointer to file structure:
  4154. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4155. IF_NOT_OK_RETURN(status=1)
  4156. ! pointer to variable structure:
  4157. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4158. IF_NOT_OK_RETURN(status=1)
  4159. ! check ...
  4160. if ( size(shape(values)) > varp%ndim ) then
  4161. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  4162. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4163. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4164. TRACEBACK; status=1; return
  4165. end if
  4166. ! check ...
  4167. if ( present(start ) ) then
  4168. if ( size(start ) /= varp%ndim ) then
  4169. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4170. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4171. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4172. TRACEBACK; status=1; return
  4173. end if
  4174. end if
  4175. if ( present(count ) ) then
  4176. if ( size(count ) /= varp%ndim ) then
  4177. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4178. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4179. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4180. TRACEBACK; status=1; return
  4181. end if
  4182. end if
  4183. if ( present(stride ) ) then
  4184. if ( size(stride ) /= varp%ndim ) then
  4185. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4186. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4187. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4188. TRACEBACK; status=1; return
  4189. end if
  4190. end if
  4191. if ( present(map ) ) then
  4192. if ( size(map ) /= varp%ndim ) then
  4193. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4194. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4195. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4196. TRACEBACK; status=1; return
  4197. end if
  4198. end if
  4199. ! loop over file types:
  4200. do iftype = 1, filep%nftype
  4201. ! current type:
  4202. ftype = filep%ftypes(iftype)
  4203. ! select appropriate routine for each type:
  4204. select case ( ftype )
  4205. #ifdef with_hdf4
  4206. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4207. case ( MDF_HDF4 )
  4208. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4209. ! check ...
  4210. if ( present(map ) ) then
  4211. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4212. TRACEBACK; status=1; return
  4213. end if
  4214. ! fill offset (zero based!) and stride with default values:
  4215. hdf4_offset = 0
  4216. hdf4_stride = 1
  4217. ! count is by default the shape; padd with singleton dimensions:
  4218. hdf4_count = 1; hdf4_count(1:4) = (/len(values),shape(values)/)
  4219. ! replace by optional arguments if necessary:
  4220. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4221. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4222. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  4223. ! write:
  4224. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4225. #endif
  4226. #ifdef with_hdf5_beta
  4227. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4228. case ( MDF_HDF5 )
  4229. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4230. ! check ...
  4231. if ( present(map ) ) then
  4232. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  4233. TRACEBACK; status=1; return
  4234. end if
  4235. ! fill offset (zero based!), stride, and count :
  4236. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  4237. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  4238. hdf5_count = 1 ! default singleton dimension
  4239. if ( present(count) ) then
  4240. hdf5_count(1:varp%ndim) = count
  4241. else
  4242. hdf5_count(1:4) = (/len(values),shape(values)/)
  4243. end if
  4244. ! new dimension:
  4245. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  4246. ! target data space in file:
  4247. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  4248. IF_NOT_OK_RETURN(status=1)
  4249. ! chunked dataset ?
  4250. if ( varp%hdf5_chunked ) then
  4251. ! reset extend:
  4252. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  4253. IF_NOT_OK_RETURN(status=1)
  4254. end if
  4255. ! select hyperslab:
  4256. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  4257. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  4258. stride=hdf5_stride(1:varp%ndim) )
  4259. ! write data:
  4260. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  4261. int(shape(values),kind=HSIZE_T), status, &
  4262. file_space_id=hdf5_file_space_id )
  4263. IF_NOT_OK_RETURN(status=1)
  4264. ! release data space:
  4265. call H5SClose_f( hdf5_file_space_id, status )
  4266. IF_NOT_OK_RETURN(status=1)
  4267. #endif
  4268. #ifdef with_netcdf
  4269. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4270. case ( MDF_NETCDF, MDF_NETCDF4 )
  4271. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4272. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4273. start, count, stride, map )
  4274. IF_NF90_NOT_OK_RETURN(status=1)
  4275. ! just put; let netcdf library convert the right kind:
  4276. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4277. ! start, count, stride, map )
  4278. !IF_NF90_NOT_OK_RETURN(status=1)
  4279. #endif
  4280. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4281. case default
  4282. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4283. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4284. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4285. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4286. TRACEBACK; status=1; return
  4287. end select
  4288. end do ! file types
  4289. ! ok
  4290. status = 0
  4291. end subroutine MDF_Put_Var_c1_4d
  4292. ! ***
  4293. subroutine MDF_Get_Var_c1_4d( hid, varid, values, status, &
  4294. start, count, stride, map )
  4295. #ifdef with_netcdf
  4296. use NetCDF, only : NF90_Get_Var
  4297. #endif
  4298. ! --- in/out -------------------------------------
  4299. integer, intent(in) :: hid
  4300. integer, intent(in) :: varid
  4301. character(len=*), intent(out) :: values(:,:,:)
  4302. integer, intent(out) :: status
  4303. integer, intent(in), optional :: start (:)
  4304. integer, intent(in), optional :: count (:)
  4305. integer, intent(in), optional :: stride(:)
  4306. integer, intent(in), optional :: map (:)
  4307. ! --- const --------------------------------------
  4308. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_4d'
  4309. ! --- external -----------------------------------
  4310. #ifdef with_hdf4
  4311. integer(hdf4_wpi), external :: sfRData
  4312. #endif
  4313. ! --- local --------------------------------------
  4314. type(MDF_File), pointer :: filep
  4315. type(MDF_Var), pointer :: varp
  4316. integer :: iftype
  4317. integer :: ftype
  4318. #ifdef with_hdf4
  4319. integer :: hdf4_offset(MAX_RANK)
  4320. integer :: hdf4_stride(MAX_RANK)
  4321. integer :: hdf4_count(MAX_RANK)
  4322. #endif
  4323. ! --- begin --------------------------------------
  4324. ! pointer to file structure:
  4325. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4326. IF_NOT_OK_RETURN(status=1)
  4327. ! pointer to variable structure:
  4328. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4329. IF_NOT_OK_RETURN(status=1)
  4330. ! check ...
  4331. if ( size(shape(values)) > varp%ndim ) then
  4332. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  4333. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4334. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4335. TRACEBACK; status=1; return
  4336. end if
  4337. ! check ...
  4338. if ( present(start ) ) then
  4339. if ( size(start ) /= varp%ndim ) then
  4340. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4341. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4342. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4343. TRACEBACK; status=1; return
  4344. end if
  4345. end if
  4346. if ( present(count ) ) then
  4347. if ( size(count ) /= varp%ndim ) then
  4348. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4349. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4350. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4351. TRACEBACK; status=1; return
  4352. end if
  4353. end if
  4354. if ( present(stride ) ) then
  4355. if ( size(stride ) /= varp%ndim ) then
  4356. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4357. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4358. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4359. TRACEBACK; status=1; return
  4360. end if
  4361. end if
  4362. if ( present(map ) ) then
  4363. if ( size(map ) /= varp%ndim ) then
  4364. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4365. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4366. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4367. TRACEBACK; status=1; return
  4368. end if
  4369. end if
  4370. ! loop over file types:
  4371. do iftype = 1, filep%nftype
  4372. ! current type:
  4373. ftype = filep%ftypes(iftype)
  4374. ! select appropriate routine for each type:
  4375. select case ( ftype )
  4376. #ifdef with_hdf4
  4377. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4378. case ( MDF_HDF4 )
  4379. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4380. ! check ...
  4381. if ( present(map ) ) then
  4382. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4383. TRACEBACK; status=1; return
  4384. end if
  4385. ! fill offset (zero based!), stride, and count :
  4386. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4387. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4388. hdf4_count = 1 ! default singleton dimension
  4389. hdf4_count(1:4) = (/ len(values), shape(values) /)
  4390. ! read:
  4391. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4392. #endif
  4393. #ifdef with_netcdf
  4394. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4395. case ( MDF_NETCDF, MDF_NETCDF4 )
  4396. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4397. ! read values, converted automatically:
  4398. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4399. start, count, stride, map )
  4400. IF_NF90_NOT_OK_RETURN(status=1)
  4401. #endif
  4402. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4403. case default
  4404. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4405. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4406. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4407. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4408. TRACEBACK; status=1; return
  4409. end select
  4410. end do ! file types
  4411. ! ok
  4412. status = 0
  4413. end subroutine MDF_Get_Var_c1_4d
  4414. ! ***
  4415. subroutine MDF_Put_Var_c1_5d( hid, varid, values, status, &
  4416. start, count, stride, map )
  4417. #ifdef with_hdf5_beta
  4418. use HDF5, only : HID_T, HSIZE_T
  4419. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  4420. use HDF5, only : H5T_NATIVE_CHARACTER
  4421. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  4422. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  4423. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  4424. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  4425. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  4426. #endif
  4427. #ifdef with_netcdf
  4428. use NetCDF, only : NF90_Put_Var
  4429. #endif
  4430. ! --- in/out -------------------------------------
  4431. integer, intent(in) :: hid
  4432. integer, intent(in) :: varid
  4433. character(len=*), intent(in) :: values(:,:,:,:)
  4434. integer, intent(out) :: status
  4435. integer, intent(in), optional :: start (:)
  4436. integer, intent(in), optional :: count (:)
  4437. integer, intent(in), optional :: stride(:)
  4438. integer, intent(in), optional :: map (:)
  4439. ! --- const --------------------------------------
  4440. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_5d'
  4441. ! --- external -----------------------------------
  4442. #ifdef with_hdf4
  4443. integer(hdf4_wpi), external :: sfWData
  4444. #endif
  4445. ! --- local --------------------------------------
  4446. type(MDF_File), pointer :: filep
  4447. type(MDF_Var), pointer :: varp
  4448. integer :: iftype
  4449. integer :: ftype
  4450. #ifdef with_hdf4
  4451. integer :: hdf4_offset(MAX_RANK)
  4452. integer :: hdf4_stride(MAX_RANK)
  4453. integer :: hdf4_count(MAX_RANK)
  4454. #endif
  4455. #ifdef with_hdf5_beta
  4456. !integer(HID_T) :: hdf5_type_id
  4457. integer(HID_T) :: hdf5_file_space_id
  4458. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  4459. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  4460. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  4461. #endif
  4462. ! --- begin --------------------------------------
  4463. ! pointer to file structure:
  4464. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4465. IF_NOT_OK_RETURN(status=1)
  4466. ! pointer to variable structure:
  4467. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4468. IF_NOT_OK_RETURN(status=1)
  4469. ! check ...
  4470. if ( size(shape(values)) > varp%ndim ) then
  4471. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  4472. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4473. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4474. TRACEBACK; status=1; return
  4475. end if
  4476. ! check ...
  4477. if ( present(start ) ) then
  4478. if ( size(start ) /= varp%ndim ) then
  4479. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4480. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4481. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4482. TRACEBACK; status=1; return
  4483. end if
  4484. end if
  4485. if ( present(count ) ) then
  4486. if ( size(count ) /= varp%ndim ) then
  4487. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4488. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4489. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4490. TRACEBACK; status=1; return
  4491. end if
  4492. end if
  4493. if ( present(stride ) ) then
  4494. if ( size(stride ) /= varp%ndim ) then
  4495. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4496. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4497. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4498. TRACEBACK; status=1; return
  4499. end if
  4500. end if
  4501. if ( present(map ) ) then
  4502. if ( size(map ) /= varp%ndim ) then
  4503. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4504. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4505. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4506. TRACEBACK; status=1; return
  4507. end if
  4508. end if
  4509. ! loop over file types:
  4510. do iftype = 1, filep%nftype
  4511. ! current type:
  4512. ftype = filep%ftypes(iftype)
  4513. ! select appropriate routine for each type:
  4514. select case ( ftype )
  4515. #ifdef with_hdf4
  4516. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4517. case ( MDF_HDF4 )
  4518. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4519. ! check ...
  4520. if ( present(map ) ) then
  4521. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4522. TRACEBACK; status=1; return
  4523. end if
  4524. ! fill offset (zero based!) and stride with default values:
  4525. hdf4_offset = 0
  4526. hdf4_stride = 1
  4527. ! count is by default the shape; padd with singleton dimensions:
  4528. hdf4_count = 1; hdf4_count(1:5) = (/len(values),shape(values)/)
  4529. ! replace by optional arguments if necessary:
  4530. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4531. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4532. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  4533. ! write:
  4534. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4535. #endif
  4536. #ifdef with_hdf5_beta
  4537. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4538. case ( MDF_HDF5 )
  4539. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4540. ! check ...
  4541. if ( present(map ) ) then
  4542. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  4543. TRACEBACK; status=1; return
  4544. end if
  4545. ! fill offset (zero based!), stride, and count :
  4546. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  4547. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  4548. hdf5_count = 1 ! default singleton dimension
  4549. if ( present(count) ) then
  4550. hdf5_count(1:varp%ndim) = count
  4551. else
  4552. hdf5_count(1:5) = (/len(values),shape(values)/)
  4553. end if
  4554. ! new dimension:
  4555. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  4556. ! target data space in file:
  4557. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  4558. IF_NOT_OK_RETURN(status=1)
  4559. ! chunked dataset ?
  4560. if ( varp%hdf5_chunked ) then
  4561. ! reset extend:
  4562. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  4563. IF_NOT_OK_RETURN(status=1)
  4564. end if
  4565. ! select hyperslab:
  4566. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  4567. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  4568. stride=hdf5_stride(1:varp%ndim) )
  4569. ! write data:
  4570. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  4571. int(shape(values),kind=HSIZE_T), status, &
  4572. file_space_id=hdf5_file_space_id )
  4573. IF_NOT_OK_RETURN(status=1)
  4574. ! release data space:
  4575. call H5SClose_f( hdf5_file_space_id, status )
  4576. IF_NOT_OK_RETURN(status=1)
  4577. #endif
  4578. #ifdef with_netcdf
  4579. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4580. case ( MDF_NETCDF, MDF_NETCDF4 )
  4581. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4582. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4583. start, count, stride, map )
  4584. IF_NF90_NOT_OK_RETURN(status=1)
  4585. ! just put; let netcdf library convert the right kind:
  4586. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4587. ! start, count, stride, map )
  4588. !IF_NF90_NOT_OK_RETURN(status=1)
  4589. #endif
  4590. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4591. case default
  4592. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4593. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4594. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4595. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4596. TRACEBACK; status=1; return
  4597. end select
  4598. end do ! file types
  4599. ! ok
  4600. status = 0
  4601. end subroutine MDF_Put_Var_c1_5d
  4602. ! ***
  4603. subroutine MDF_Get_Var_c1_5d( hid, varid, values, status, &
  4604. start, count, stride, map )
  4605. #ifdef with_netcdf
  4606. use NetCDF, only : NF90_Get_Var
  4607. #endif
  4608. ! --- in/out -------------------------------------
  4609. integer, intent(in) :: hid
  4610. integer, intent(in) :: varid
  4611. character(len=*), intent(out) :: values(:,:,:,:)
  4612. integer, intent(out) :: status
  4613. integer, intent(in), optional :: start (:)
  4614. integer, intent(in), optional :: count (:)
  4615. integer, intent(in), optional :: stride(:)
  4616. integer, intent(in), optional :: map (:)
  4617. ! --- const --------------------------------------
  4618. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_5d'
  4619. ! --- external -----------------------------------
  4620. #ifdef with_hdf4
  4621. integer(hdf4_wpi), external :: sfRData
  4622. #endif
  4623. ! --- local --------------------------------------
  4624. type(MDF_File), pointer :: filep
  4625. type(MDF_Var), pointer :: varp
  4626. integer :: iftype
  4627. integer :: ftype
  4628. #ifdef with_hdf4
  4629. integer :: hdf4_offset(MAX_RANK)
  4630. integer :: hdf4_stride(MAX_RANK)
  4631. integer :: hdf4_count(MAX_RANK)
  4632. #endif
  4633. ! --- begin --------------------------------------
  4634. ! pointer to file structure:
  4635. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4636. IF_NOT_OK_RETURN(status=1)
  4637. ! pointer to variable structure:
  4638. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4639. IF_NOT_OK_RETURN(status=1)
  4640. ! check ...
  4641. if ( size(shape(values)) > varp%ndim ) then
  4642. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  4643. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4644. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4645. TRACEBACK; status=1; return
  4646. end if
  4647. ! check ...
  4648. if ( present(start ) ) then
  4649. if ( size(start ) /= varp%ndim ) then
  4650. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4651. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4652. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4653. TRACEBACK; status=1; return
  4654. end if
  4655. end if
  4656. if ( present(count ) ) then
  4657. if ( size(count ) /= varp%ndim ) then
  4658. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4659. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4660. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4661. TRACEBACK; status=1; return
  4662. end if
  4663. end if
  4664. if ( present(stride ) ) then
  4665. if ( size(stride ) /= varp%ndim ) then
  4666. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4667. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4668. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4669. TRACEBACK; status=1; return
  4670. end if
  4671. end if
  4672. if ( present(map ) ) then
  4673. if ( size(map ) /= varp%ndim ) then
  4674. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4675. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4676. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4677. TRACEBACK; status=1; return
  4678. end if
  4679. end if
  4680. ! loop over file types:
  4681. do iftype = 1, filep%nftype
  4682. ! current type:
  4683. ftype = filep%ftypes(iftype)
  4684. ! select appropriate routine for each type:
  4685. select case ( ftype )
  4686. #ifdef with_hdf4
  4687. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4688. case ( MDF_HDF4 )
  4689. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4690. ! check ...
  4691. if ( present(map ) ) then
  4692. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4693. TRACEBACK; status=1; return
  4694. end if
  4695. ! fill offset (zero based!), stride, and count :
  4696. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4697. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4698. hdf4_count = 1 ! default singleton dimension
  4699. hdf4_count(1:5) = (/ len(values), shape(values) /)
  4700. ! read:
  4701. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4702. #endif
  4703. #ifdef with_netcdf
  4704. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4705. case ( MDF_NETCDF, MDF_NETCDF4 )
  4706. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4707. ! read values, converted automatically:
  4708. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4709. start, count, stride, map )
  4710. IF_NF90_NOT_OK_RETURN(status=1)
  4711. #endif
  4712. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4713. case default
  4714. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4715. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4716. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4717. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4718. TRACEBACK; status=1; return
  4719. end select
  4720. end do ! file types
  4721. ! ok
  4722. status = 0
  4723. end subroutine MDF_Get_Var_c1_5d
  4724. ! ***
  4725. subroutine MDF_Put_Var_c1_6d( hid, varid, values, status, &
  4726. start, count, stride, map )
  4727. #ifdef with_hdf5_beta
  4728. use HDF5, only : HID_T, HSIZE_T
  4729. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  4730. use HDF5, only : H5T_NATIVE_CHARACTER
  4731. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  4732. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  4733. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  4734. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  4735. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  4736. #endif
  4737. #ifdef with_netcdf
  4738. use NetCDF, only : NF90_Put_Var
  4739. #endif
  4740. ! --- in/out -------------------------------------
  4741. integer, intent(in) :: hid
  4742. integer, intent(in) :: varid
  4743. character(len=*), intent(in) :: values(:,:,:,:,:)
  4744. integer, intent(out) :: status
  4745. integer, intent(in), optional :: start (:)
  4746. integer, intent(in), optional :: count (:)
  4747. integer, intent(in), optional :: stride(:)
  4748. integer, intent(in), optional :: map (:)
  4749. ! --- const --------------------------------------
  4750. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_6d'
  4751. ! --- external -----------------------------------
  4752. #ifdef with_hdf4
  4753. integer(hdf4_wpi), external :: sfWData
  4754. #endif
  4755. ! --- local --------------------------------------
  4756. type(MDF_File), pointer :: filep
  4757. type(MDF_Var), pointer :: varp
  4758. integer :: iftype
  4759. integer :: ftype
  4760. #ifdef with_hdf4
  4761. integer :: hdf4_offset(MAX_RANK)
  4762. integer :: hdf4_stride(MAX_RANK)
  4763. integer :: hdf4_count(MAX_RANK)
  4764. #endif
  4765. #ifdef with_hdf5_beta
  4766. !integer(HID_T) :: hdf5_type_id
  4767. integer(HID_T) :: hdf5_file_space_id
  4768. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  4769. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  4770. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  4771. #endif
  4772. ! --- begin --------------------------------------
  4773. ! pointer to file structure:
  4774. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4775. IF_NOT_OK_RETURN(status=1)
  4776. ! pointer to variable structure:
  4777. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4778. IF_NOT_OK_RETURN(status=1)
  4779. ! check ...
  4780. if ( size(shape(values)) > varp%ndim ) then
  4781. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  4782. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4783. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4784. TRACEBACK; status=1; return
  4785. end if
  4786. ! check ...
  4787. if ( present(start ) ) then
  4788. if ( size(start ) /= varp%ndim ) then
  4789. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4790. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4791. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4792. TRACEBACK; status=1; return
  4793. end if
  4794. end if
  4795. if ( present(count ) ) then
  4796. if ( size(count ) /= varp%ndim ) then
  4797. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4798. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4799. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4800. TRACEBACK; status=1; return
  4801. end if
  4802. end if
  4803. if ( present(stride ) ) then
  4804. if ( size(stride ) /= varp%ndim ) then
  4805. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4806. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4807. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4808. TRACEBACK; status=1; return
  4809. end if
  4810. end if
  4811. if ( present(map ) ) then
  4812. if ( size(map ) /= varp%ndim ) then
  4813. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4814. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4815. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4816. TRACEBACK; status=1; return
  4817. end if
  4818. end if
  4819. ! loop over file types:
  4820. do iftype = 1, filep%nftype
  4821. ! current type:
  4822. ftype = filep%ftypes(iftype)
  4823. ! select appropriate routine for each type:
  4824. select case ( ftype )
  4825. #ifdef with_hdf4
  4826. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4827. case ( MDF_HDF4 )
  4828. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4829. ! check ...
  4830. if ( present(map ) ) then
  4831. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  4832. TRACEBACK; status=1; return
  4833. end if
  4834. ! fill offset (zero based!) and stride with default values:
  4835. hdf4_offset = 0
  4836. hdf4_stride = 1
  4837. ! count is by default the shape; padd with singleton dimensions:
  4838. hdf4_count = 1; hdf4_count(1:6) = (/len(values),shape(values)/)
  4839. ! replace by optional arguments if necessary:
  4840. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  4841. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  4842. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  4843. ! write:
  4844. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  4845. #endif
  4846. #ifdef with_hdf5_beta
  4847. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4848. case ( MDF_HDF5 )
  4849. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4850. ! check ...
  4851. if ( present(map ) ) then
  4852. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  4853. TRACEBACK; status=1; return
  4854. end if
  4855. ! fill offset (zero based!), stride, and count :
  4856. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  4857. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  4858. hdf5_count = 1 ! default singleton dimension
  4859. if ( present(count) ) then
  4860. hdf5_count(1:varp%ndim) = count
  4861. else
  4862. hdf5_count(1:6) = (/len(values),shape(values)/)
  4863. end if
  4864. ! new dimension:
  4865. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  4866. ! target data space in file:
  4867. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  4868. IF_NOT_OK_RETURN(status=1)
  4869. ! chunked dataset ?
  4870. if ( varp%hdf5_chunked ) then
  4871. ! reset extend:
  4872. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  4873. IF_NOT_OK_RETURN(status=1)
  4874. end if
  4875. ! select hyperslab:
  4876. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  4877. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  4878. stride=hdf5_stride(1:varp%ndim) )
  4879. ! write data:
  4880. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  4881. int(shape(values),kind=HSIZE_T), status, &
  4882. file_space_id=hdf5_file_space_id )
  4883. IF_NOT_OK_RETURN(status=1)
  4884. ! release data space:
  4885. call H5SClose_f( hdf5_file_space_id, status )
  4886. IF_NOT_OK_RETURN(status=1)
  4887. #endif
  4888. #ifdef with_netcdf
  4889. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4890. case ( MDF_NETCDF, MDF_NETCDF4 )
  4891. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4892. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4893. start, count, stride, map )
  4894. IF_NF90_NOT_OK_RETURN(status=1)
  4895. ! just put; let netcdf library convert the right kind:
  4896. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  4897. ! start, count, stride, map )
  4898. !IF_NF90_NOT_OK_RETURN(status=1)
  4899. #endif
  4900. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4901. case default
  4902. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4903. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  4904. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  4905. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  4906. TRACEBACK; status=1; return
  4907. end select
  4908. end do ! file types
  4909. ! ok
  4910. status = 0
  4911. end subroutine MDF_Put_Var_c1_6d
  4912. ! ***
  4913. subroutine MDF_Get_Var_c1_6d( hid, varid, values, status, &
  4914. start, count, stride, map )
  4915. #ifdef with_netcdf
  4916. use NetCDF, only : NF90_Get_Var
  4917. #endif
  4918. ! --- in/out -------------------------------------
  4919. integer, intent(in) :: hid
  4920. integer, intent(in) :: varid
  4921. character(len=*), intent(out) :: values(:,:,:,:,:)
  4922. integer, intent(out) :: status
  4923. integer, intent(in), optional :: start (:)
  4924. integer, intent(in), optional :: count (:)
  4925. integer, intent(in), optional :: stride(:)
  4926. integer, intent(in), optional :: map (:)
  4927. ! --- const --------------------------------------
  4928. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_6d'
  4929. ! --- external -----------------------------------
  4930. #ifdef with_hdf4
  4931. integer(hdf4_wpi), external :: sfRData
  4932. #endif
  4933. ! --- local --------------------------------------
  4934. type(MDF_File), pointer :: filep
  4935. type(MDF_Var), pointer :: varp
  4936. integer :: iftype
  4937. integer :: ftype
  4938. #ifdef with_hdf4
  4939. integer :: hdf4_offset(MAX_RANK)
  4940. integer :: hdf4_stride(MAX_RANK)
  4941. integer :: hdf4_count(MAX_RANK)
  4942. #endif
  4943. ! --- begin --------------------------------------
  4944. ! pointer to file structure:
  4945. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  4946. IF_NOT_OK_RETURN(status=1)
  4947. ! pointer to variable structure:
  4948. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  4949. IF_NOT_OK_RETURN(status=1)
  4950. ! check ...
  4951. if ( size(shape(values)) > varp%ndim ) then
  4952. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  4953. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  4954. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  4955. TRACEBACK; status=1; return
  4956. end if
  4957. ! check ...
  4958. if ( present(start ) ) then
  4959. if ( size(start ) /= varp%ndim ) then
  4960. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4961. write (gol,'(" size start : ",i6)') size(start ); call goErr
  4962. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4963. TRACEBACK; status=1; return
  4964. end if
  4965. end if
  4966. if ( present(count ) ) then
  4967. if ( size(count ) /= varp%ndim ) then
  4968. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4969. write (gol,'(" size count : ",i6)') size(count ); call goErr
  4970. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4971. TRACEBACK; status=1; return
  4972. end if
  4973. end if
  4974. if ( present(stride ) ) then
  4975. if ( size(stride ) /= varp%ndim ) then
  4976. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4977. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  4978. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4979. TRACEBACK; status=1; return
  4980. end if
  4981. end if
  4982. if ( present(map ) ) then
  4983. if ( size(map ) /= varp%ndim ) then
  4984. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  4985. write (gol,'(" size map : ",i6)') size(map ); call goErr
  4986. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  4987. TRACEBACK; status=1; return
  4988. end if
  4989. end if
  4990. ! loop over file types:
  4991. do iftype = 1, filep%nftype
  4992. ! current type:
  4993. ftype = filep%ftypes(iftype)
  4994. ! select appropriate routine for each type:
  4995. select case ( ftype )
  4996. #ifdef with_hdf4
  4997. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4998. case ( MDF_HDF4 )
  4999. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5000. ! check ...
  5001. if ( present(map ) ) then
  5002. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5003. TRACEBACK; status=1; return
  5004. end if
  5005. ! fill offset (zero based!), stride, and count :
  5006. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5007. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5008. hdf4_count = 1 ! default singleton dimension
  5009. hdf4_count(1:6) = (/ len(values), shape(values) /)
  5010. ! read:
  5011. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  5012. #endif
  5013. #ifdef with_netcdf
  5014. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5015. case ( MDF_NETCDF, MDF_NETCDF4 )
  5016. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5017. ! read values, converted automatically:
  5018. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5019. start, count, stride, map )
  5020. IF_NF90_NOT_OK_RETURN(status=1)
  5021. #endif
  5022. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5023. case default
  5024. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5025. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  5026. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  5027. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  5028. TRACEBACK; status=1; return
  5029. end select
  5030. end do ! file types
  5031. ! ok
  5032. status = 0
  5033. end subroutine MDF_Get_Var_c1_6d
  5034. ! ***
  5035. subroutine MDF_Put_Var_c1_7d( hid, varid, values, status, &
  5036. start, count, stride, map )
  5037. #ifdef with_hdf5_beta
  5038. use HDF5, only : HID_T, HSIZE_T
  5039. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  5040. use HDF5, only : H5T_NATIVE_CHARACTER
  5041. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  5042. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  5043. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  5044. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  5045. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  5046. #endif
  5047. #ifdef with_netcdf
  5048. use NetCDF, only : NF90_Put_Var
  5049. #endif
  5050. ! --- in/out -------------------------------------
  5051. integer, intent(in) :: hid
  5052. integer, intent(in) :: varid
  5053. character(len=*), intent(in) :: values(:,:,:,:,:,:)
  5054. integer, intent(out) :: status
  5055. integer, intent(in), optional :: start (:)
  5056. integer, intent(in), optional :: count (:)
  5057. integer, intent(in), optional :: stride(:)
  5058. integer, intent(in), optional :: map (:)
  5059. ! --- const --------------------------------------
  5060. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_c1_7d'
  5061. ! --- external -----------------------------------
  5062. #ifdef with_hdf4
  5063. integer(hdf4_wpi), external :: sfWData
  5064. #endif
  5065. ! --- local --------------------------------------
  5066. type(MDF_File), pointer :: filep
  5067. type(MDF_Var), pointer :: varp
  5068. integer :: iftype
  5069. integer :: ftype
  5070. #ifdef with_hdf4
  5071. integer :: hdf4_offset(MAX_RANK)
  5072. integer :: hdf4_stride(MAX_RANK)
  5073. integer :: hdf4_count(MAX_RANK)
  5074. #endif
  5075. #ifdef with_hdf5_beta
  5076. !integer(HID_T) :: hdf5_type_id
  5077. integer(HID_T) :: hdf5_file_space_id
  5078. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  5079. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  5080. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  5081. #endif
  5082. ! --- begin --------------------------------------
  5083. ! pointer to file structure:
  5084. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  5085. IF_NOT_OK_RETURN(status=1)
  5086. ! pointer to variable structure:
  5087. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  5088. IF_NOT_OK_RETURN(status=1)
  5089. ! check ...
  5090. if ( size(shape(values)) > varp%ndim ) then
  5091. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  5092. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  5093. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  5094. TRACEBACK; status=1; return
  5095. end if
  5096. ! check ...
  5097. if ( present(start ) ) then
  5098. if ( size(start ) /= varp%ndim ) then
  5099. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5100. write (gol,'(" size start : ",i6)') size(start ); call goErr
  5101. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5102. TRACEBACK; status=1; return
  5103. end if
  5104. end if
  5105. if ( present(count ) ) then
  5106. if ( size(count ) /= varp%ndim ) then
  5107. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5108. write (gol,'(" size count : ",i6)') size(count ); call goErr
  5109. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5110. TRACEBACK; status=1; return
  5111. end if
  5112. end if
  5113. if ( present(stride ) ) then
  5114. if ( size(stride ) /= varp%ndim ) then
  5115. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5116. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  5117. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5118. TRACEBACK; status=1; return
  5119. end if
  5120. end if
  5121. if ( present(map ) ) then
  5122. if ( size(map ) /= varp%ndim ) then
  5123. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5124. write (gol,'(" size map : ",i6)') size(map ); call goErr
  5125. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5126. TRACEBACK; status=1; return
  5127. end if
  5128. end if
  5129. ! loop over file types:
  5130. do iftype = 1, filep%nftype
  5131. ! current type:
  5132. ftype = filep%ftypes(iftype)
  5133. ! select appropriate routine for each type:
  5134. select case ( ftype )
  5135. #ifdef with_hdf4
  5136. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5137. case ( MDF_HDF4 )
  5138. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5139. ! check ...
  5140. if ( present(map ) ) then
  5141. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5142. TRACEBACK; status=1; return
  5143. end if
  5144. ! fill offset (zero based!) and stride with default values:
  5145. hdf4_offset = 0
  5146. hdf4_stride = 1
  5147. ! count is by default the shape; padd with singleton dimensions:
  5148. hdf4_count = 1; hdf4_count(1:7) = (/len(values),shape(values)/)
  5149. ! replace by optional arguments if necessary:
  5150. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5151. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5152. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  5153. ! write:
  5154. status = sfWData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  5155. #endif
  5156. #ifdef with_hdf5_beta
  5157. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5158. case ( MDF_HDF5 )
  5159. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5160. ! check ...
  5161. if ( present(map ) ) then
  5162. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  5163. TRACEBACK; status=1; return
  5164. end if
  5165. ! fill offset (zero based!), stride, and count :
  5166. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  5167. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  5168. hdf5_count = 1 ! default singleton dimension
  5169. if ( present(count) ) then
  5170. hdf5_count(1:varp%ndim) = count
  5171. else
  5172. hdf5_count(1:7) = (/len(values),shape(values)/)
  5173. end if
  5174. ! new dimension:
  5175. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  5176. ! target data space in file:
  5177. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  5178. IF_NOT_OK_RETURN(status=1)
  5179. ! chunked dataset ?
  5180. if ( varp%hdf5_chunked ) then
  5181. ! reset extend:
  5182. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  5183. IF_NOT_OK_RETURN(status=1)
  5184. end if
  5185. ! select hyperslab:
  5186. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  5187. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  5188. stride=hdf5_stride(1:varp%ndim) )
  5189. ! write data:
  5190. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_CHARACTER, values, &
  5191. int(shape(values),kind=HSIZE_T), status, &
  5192. file_space_id=hdf5_file_space_id )
  5193. IF_NOT_OK_RETURN(status=1)
  5194. ! release data space:
  5195. call H5SClose_f( hdf5_file_space_id, status )
  5196. IF_NOT_OK_RETURN(status=1)
  5197. #endif
  5198. #ifdef with_netcdf
  5199. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5200. case ( MDF_NETCDF, MDF_NETCDF4 )
  5201. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5202. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5203. start, count, stride, map )
  5204. IF_NF90_NOT_OK_RETURN(status=1)
  5205. ! just put; let netcdf library convert the right kind:
  5206. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5207. ! start, count, stride, map )
  5208. !IF_NF90_NOT_OK_RETURN(status=1)
  5209. #endif
  5210. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5211. case default
  5212. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5213. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  5214. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  5215. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  5216. TRACEBACK; status=1; return
  5217. end select
  5218. end do ! file types
  5219. ! ok
  5220. status = 0
  5221. end subroutine MDF_Put_Var_c1_7d
  5222. ! ***
  5223. subroutine MDF_Get_Var_c1_7d( hid, varid, values, status, &
  5224. start, count, stride, map )
  5225. #ifdef with_netcdf
  5226. use NetCDF, only : NF90_Get_Var
  5227. #endif
  5228. ! --- in/out -------------------------------------
  5229. integer, intent(in) :: hid
  5230. integer, intent(in) :: varid
  5231. character(len=*), intent(out) :: values(:,:,:,:,:,:)
  5232. integer, intent(out) :: status
  5233. integer, intent(in), optional :: start (:)
  5234. integer, intent(in), optional :: count (:)
  5235. integer, intent(in), optional :: stride(:)
  5236. integer, intent(in), optional :: map (:)
  5237. ! --- const --------------------------------------
  5238. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_c1_7d'
  5239. ! --- external -----------------------------------
  5240. #ifdef with_hdf4
  5241. integer(hdf4_wpi), external :: sfRData
  5242. #endif
  5243. ! --- local --------------------------------------
  5244. type(MDF_File), pointer :: filep
  5245. type(MDF_Var), pointer :: varp
  5246. integer :: iftype
  5247. integer :: ftype
  5248. #ifdef with_hdf4
  5249. integer :: hdf4_offset(MAX_RANK)
  5250. integer :: hdf4_stride(MAX_RANK)
  5251. integer :: hdf4_count(MAX_RANK)
  5252. #endif
  5253. ! --- begin --------------------------------------
  5254. ! pointer to file structure:
  5255. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  5256. IF_NOT_OK_RETURN(status=1)
  5257. ! pointer to variable structure:
  5258. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  5259. IF_NOT_OK_RETURN(status=1)
  5260. ! check ...
  5261. if ( size(shape(values)) > varp%ndim ) then
  5262. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  5263. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  5264. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  5265. TRACEBACK; status=1; return
  5266. end if
  5267. ! check ...
  5268. if ( present(start ) ) then
  5269. if ( size(start ) /= varp%ndim ) then
  5270. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5271. write (gol,'(" size start : ",i6)') size(start ); call goErr
  5272. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5273. TRACEBACK; status=1; return
  5274. end if
  5275. end if
  5276. if ( present(count ) ) then
  5277. if ( size(count ) /= varp%ndim ) then
  5278. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5279. write (gol,'(" size count : ",i6)') size(count ); call goErr
  5280. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5281. TRACEBACK; status=1; return
  5282. end if
  5283. end if
  5284. if ( present(stride ) ) then
  5285. if ( size(stride ) /= varp%ndim ) then
  5286. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5287. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  5288. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5289. TRACEBACK; status=1; return
  5290. end if
  5291. end if
  5292. if ( present(map ) ) then
  5293. if ( size(map ) /= varp%ndim ) then
  5294. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5295. write (gol,'(" size map : ",i6)') size(map ); call goErr
  5296. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5297. TRACEBACK; status=1; return
  5298. end if
  5299. end if
  5300. ! loop over file types:
  5301. do iftype = 1, filep%nftype
  5302. ! current type:
  5303. ftype = filep%ftypes(iftype)
  5304. ! select appropriate routine for each type:
  5305. select case ( ftype )
  5306. #ifdef with_hdf4
  5307. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5308. case ( MDF_HDF4 )
  5309. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5310. ! check ...
  5311. if ( present(map ) ) then
  5312. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5313. TRACEBACK; status=1; return
  5314. end if
  5315. ! fill offset (zero based!), stride, and count :
  5316. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5317. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5318. hdf4_count = 1 ! default singleton dimension
  5319. hdf4_count(1:7) = (/ len(values), shape(values) /)
  5320. ! read:
  5321. status = sfRData( varp%hdf4_sdid, hdf4_offset, hdf4_stride, hdf4_count, values )
  5322. #endif
  5323. #ifdef with_netcdf
  5324. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5325. case ( MDF_NETCDF, MDF_NETCDF4 )
  5326. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5327. ! read values, converted automatically:
  5328. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5329. start, count, stride, map )
  5330. IF_NF90_NOT_OK_RETURN(status=1)
  5331. #endif
  5332. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5333. case default
  5334. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5335. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  5336. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  5337. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  5338. TRACEBACK; status=1; return
  5339. end select
  5340. end do ! file types
  5341. ! ok
  5342. status = 0
  5343. end subroutine MDF_Get_Var_c1_7d
  5344. ! ***
  5345. subroutine MDF_Put_Var_i1_1d( hid, varid, values, status, &
  5346. start, count, stride, map )
  5347. #ifdef with_hdf5_beta
  5348. use HDF5, only : HID_T, HSIZE_T
  5349. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  5350. use HDF5, only : H5T_NATIVE_CHARACTER
  5351. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  5352. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  5353. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  5354. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  5355. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  5356. #endif
  5357. #ifdef with_netcdf
  5358. use NetCDF, only : NF90_Put_Var
  5359. #endif
  5360. ! --- in/out -------------------------------------
  5361. integer, intent(in) :: hid
  5362. integer, intent(in) :: varid
  5363. integer(1), intent(in) :: values(:)
  5364. integer, intent(out) :: status
  5365. integer, intent(in), optional :: start (:)
  5366. integer, intent(in), optional :: count (:)
  5367. integer, intent(in), optional :: stride(:)
  5368. integer, intent(in), optional :: map (:)
  5369. ! --- const --------------------------------------
  5370. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_1d'
  5371. ! --- external -----------------------------------
  5372. #ifdef with_hdf4
  5373. integer(hdf4_wpi), external :: sfWData
  5374. #endif
  5375. ! --- local --------------------------------------
  5376. type(MDF_File), pointer :: filep
  5377. type(MDF_Var), pointer :: varp
  5378. integer :: iftype
  5379. integer :: ftype
  5380. #ifdef with_hdf4
  5381. integer :: hdf4_offset(MAX_RANK)
  5382. integer :: hdf4_stride(MAX_RANK)
  5383. integer :: hdf4_count(MAX_RANK)
  5384. #endif
  5385. #ifdef with_hdf5_beta
  5386. !integer(HID_T) :: hdf5_type_id
  5387. integer(HID_T) :: hdf5_file_space_id
  5388. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  5389. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  5390. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  5391. #endif
  5392. integer(1), allocatable :: values_int1(:)
  5393. integer(2), allocatable :: values_int2(:)
  5394. integer(4), allocatable :: values_int4(:)
  5395. integer(8), allocatable :: values_int8(:)
  5396. real(4), allocatable :: values_real4(:)
  5397. real(8), allocatable :: values_real8(:)
  5398. ! --- begin --------------------------------------
  5399. ! pointer to file structure:
  5400. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  5401. IF_NOT_OK_RETURN(status=1)
  5402. ! pointer to variable structure:
  5403. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  5404. IF_NOT_OK_RETURN(status=1)
  5405. ! check ...
  5406. if ( size(shape(values)) > varp%ndim ) then
  5407. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  5408. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  5409. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  5410. TRACEBACK; status=1; return
  5411. end if
  5412. ! check ...
  5413. if ( present(start ) ) then
  5414. if ( size(start ) /= varp%ndim ) then
  5415. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5416. write (gol,'(" size start : ",i6)') size(start ); call goErr
  5417. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5418. TRACEBACK; status=1; return
  5419. end if
  5420. end if
  5421. if ( present(count ) ) then
  5422. if ( size(count ) /= varp%ndim ) then
  5423. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5424. write (gol,'(" size count : ",i6)') size(count ); call goErr
  5425. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5426. TRACEBACK; status=1; return
  5427. end if
  5428. end if
  5429. if ( present(stride ) ) then
  5430. if ( size(stride ) /= varp%ndim ) then
  5431. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5432. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  5433. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5434. TRACEBACK; status=1; return
  5435. end if
  5436. end if
  5437. if ( present(map ) ) then
  5438. if ( size(map ) /= varp%ndim ) then
  5439. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5440. write (gol,'(" size map : ",i6)') size(map ); call goErr
  5441. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5442. TRACEBACK; status=1; return
  5443. end if
  5444. end if
  5445. ! loop over file types:
  5446. do iftype = 1, filep%nftype
  5447. ! current type:
  5448. ftype = filep%ftypes(iftype)
  5449. ! select appropriate routine for each type:
  5450. select case ( ftype )
  5451. #ifdef with_hdf4
  5452. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5453. case ( MDF_HDF4 )
  5454. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5455. ! check ...
  5456. if ( present(map ) ) then
  5457. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5458. TRACEBACK; status=1; return
  5459. end if
  5460. ! fill offset (zero based!) and stride with default values:
  5461. hdf4_offset = 0
  5462. hdf4_stride = 1
  5463. ! count is by default the shape; padd with singleton dimensions:
  5464. hdf4_count = 1; hdf4_count(1:1) = shape(values)
  5465. ! replace by optional arguments if necessary:
  5466. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5467. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5468. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  5469. ! test target type;
  5470. ! convert to required kind before entering sfWData,
  5471. ! otherwise segmentation faults on some machines ...
  5472. select case ( varp%xtype )
  5473. case ( MDF_BYTE )
  5474. allocate( values_int1(size(values,1)) )
  5475. values_int1 = int(values,kind=1)
  5476. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5477. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  5478. deallocate( values_int1 )
  5479. case ( MDF_SHORT )
  5480. allocate( values_int2(size(values,1)) )
  5481. values_int2 = int(values,kind=2)
  5482. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5483. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  5484. deallocate( values_int2 )
  5485. case ( MDF_INT )
  5486. allocate( values_int4(size(values,1)) )
  5487. values_int4 = int(values,kind=4)
  5488. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5489. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  5490. deallocate( values_int4 )
  5491. case ( MDF_FLOAT )
  5492. allocate( values_real4(size(values,1)) )
  5493. values_real4 = real(values,kind=4)
  5494. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5495. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  5496. deallocate( values_real4 )
  5497. case ( MDF_DOUBLE )
  5498. allocate( values_real8(size(values,1)) )
  5499. values_real8 = real(values,kind=8)
  5500. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5501. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  5502. deallocate( values_real8 )
  5503. case default
  5504. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  5505. TRACEBACK; status=1; return
  5506. end select
  5507. if ( status == FAIL ) then
  5508. write (gol,'("writing hdf4 data set:")'); call goErr
  5509. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  5510. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  5511. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  5512. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  5513. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  5514. write (gol,'(" size : ",i12)') size(values); call goErr
  5515. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  5516. TRACEBACK; status=1; return
  5517. end if
  5518. #endif
  5519. #ifdef with_hdf5_beta
  5520. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5521. case ( MDF_HDF5 )
  5522. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5523. ! check ...
  5524. if ( present(map ) ) then
  5525. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  5526. TRACEBACK; status=1; return
  5527. end if
  5528. ! fill offset (zero based!), stride, and count :
  5529. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  5530. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  5531. hdf5_count = 1 ! default singleton dimension
  5532. if ( present(count) ) then
  5533. hdf5_count(1:varp%ndim) = count
  5534. else
  5535. hdf5_count(1:1) = shape(values)
  5536. end if
  5537. ! new dimension:
  5538. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  5539. ! target data space in file:
  5540. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  5541. IF_NOT_OK_RETURN(status=1)
  5542. ! chunked dataset ?
  5543. if ( varp%hdf5_chunked ) then
  5544. ! reset extend:
  5545. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  5546. IF_NOT_OK_RETURN(status=1)
  5547. end if
  5548. ! select hyperslab:
  5549. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  5550. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  5551. stride=hdf5_stride(1:varp%ndim) )
  5552. ! write data:
  5553. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  5554. int(shape(values),kind=HSIZE_T), status, &
  5555. file_space_id=hdf5_file_space_id )
  5556. IF_NOT_OK_RETURN(status=1)
  5557. ! release data space:
  5558. call H5SClose_f( hdf5_file_space_id, status )
  5559. IF_NOT_OK_RETURN(status=1)
  5560. #endif
  5561. #ifdef with_netcdf
  5562. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5563. case ( MDF_NETCDF, MDF_NETCDF4 )
  5564. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5565. ! test target type:
  5566. ! convert to required kind before entering NF90_Put_Var,
  5567. ! otherwise segmentation faults on some machines ...
  5568. select case ( varp%xtype )
  5569. case ( MDF_BYTE )
  5570. allocate( values_int1(size(values,1)) )
  5571. values_int1 = int(values,kind=1)
  5572. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  5573. start, count, stride, map )
  5574. IF_NF90_NOT_OK_RETURN(status=1)
  5575. deallocate( values_int1 )
  5576. case ( MDF_SHORT )
  5577. allocate( values_int2(size(values,1)) )
  5578. values_int2 = int(values,kind=2)
  5579. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  5580. start, count, stride, map )
  5581. IF_NF90_NOT_OK_RETURN(status=1)
  5582. deallocate( values_int2 )
  5583. case ( MDF_INT )
  5584. allocate( values_int4(size(values,1)) )
  5585. values_int4 = int(values,kind=4)
  5586. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  5587. start, count, stride, map )
  5588. IF_NF90_NOT_OK_RETURN(status=1)
  5589. deallocate( values_int4 )
  5590. case ( MDF_FLOAT )
  5591. allocate( values_real4(size(values,1)) )
  5592. values_real4 = real(values,kind=4)
  5593. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  5594. start, count, stride, map )
  5595. IF_NF90_NOT_OK_RETURN(status=1)
  5596. deallocate( values_real4 )
  5597. case ( MDF_DOUBLE )
  5598. allocate( values_real8(size(values,1)) )
  5599. values_real8 = real(values,kind=8)
  5600. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  5601. start, count, stride, map )
  5602. IF_NF90_NOT_OK_RETURN(status=1)
  5603. deallocate( values_real8 )
  5604. case default
  5605. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  5606. TRACEBACK; status=1; return
  5607. end select
  5608. ! just put; let netcdf library convert the right kind:
  5609. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5610. ! start, count, stride, map )
  5611. !IF_NF90_NOT_OK_RETURN(status=1)
  5612. #endif
  5613. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5614. case default
  5615. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5616. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  5617. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  5618. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  5619. TRACEBACK; status=1; return
  5620. end select
  5621. end do ! file types
  5622. ! ok
  5623. status = 0
  5624. end subroutine MDF_Put_Var_i1_1d
  5625. ! ***
  5626. subroutine MDF_Get_Var_i1_1d( hid, varid, values, status, &
  5627. start, count, stride, map )
  5628. #ifdef with_netcdf
  5629. use NetCDF, only : NF90_Get_Var
  5630. #endif
  5631. ! --- in/out -------------------------------------
  5632. integer, intent(in) :: hid
  5633. integer, intent(in) :: varid
  5634. integer(1), intent(out) :: values(:)
  5635. integer, intent(out) :: status
  5636. integer, intent(in), optional :: start (:)
  5637. integer, intent(in), optional :: count (:)
  5638. integer, intent(in), optional :: stride(:)
  5639. integer, intent(in), optional :: map (:)
  5640. ! --- const --------------------------------------
  5641. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_1d'
  5642. ! --- external -----------------------------------
  5643. #ifdef with_hdf4
  5644. integer(hdf4_wpi), external :: sfRData
  5645. #endif
  5646. ! --- local --------------------------------------
  5647. type(MDF_File), pointer :: filep
  5648. type(MDF_Var), pointer :: varp
  5649. integer :: iftype
  5650. integer :: ftype
  5651. #ifdef with_hdf4
  5652. integer :: hdf4_offset(MAX_RANK)
  5653. integer :: hdf4_stride(MAX_RANK)
  5654. integer :: hdf4_count(MAX_RANK)
  5655. integer(1), allocatable :: values_int1(:)
  5656. integer(2), allocatable :: values_int2(:)
  5657. integer(4), allocatable :: values_int4(:)
  5658. integer(8), allocatable :: values_int8(:)
  5659. real(4), allocatable :: values_real4(:)
  5660. real(8), allocatable :: values_real8(:)
  5661. #endif
  5662. ! --- begin --------------------------------------
  5663. ! pointer to file structure:
  5664. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  5665. IF_NOT_OK_RETURN(status=1)
  5666. ! pointer to variable structure:
  5667. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  5668. IF_NOT_OK_RETURN(status=1)
  5669. ! check ...
  5670. if ( size(shape(values)) > varp%ndim ) then
  5671. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  5672. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  5673. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  5674. TRACEBACK; status=1; return
  5675. end if
  5676. ! check ...
  5677. if ( present(start ) ) then
  5678. if ( size(start ) /= varp%ndim ) then
  5679. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5680. write (gol,'(" size start : ",i6)') size(start ); call goErr
  5681. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5682. TRACEBACK; status=1; return
  5683. end if
  5684. end if
  5685. if ( present(count ) ) then
  5686. if ( size(count ) /= varp%ndim ) then
  5687. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5688. write (gol,'(" size count : ",i6)') size(count ); call goErr
  5689. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5690. TRACEBACK; status=1; return
  5691. end if
  5692. end if
  5693. if ( present(stride ) ) then
  5694. if ( size(stride ) /= varp%ndim ) then
  5695. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5696. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  5697. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5698. TRACEBACK; status=1; return
  5699. end if
  5700. end if
  5701. if ( present(map ) ) then
  5702. if ( size(map ) /= varp%ndim ) then
  5703. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5704. write (gol,'(" size map : ",i6)') size(map ); call goErr
  5705. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5706. TRACEBACK; status=1; return
  5707. end if
  5708. end if
  5709. ! loop over file types:
  5710. do iftype = 1, filep%nftype
  5711. ! current type:
  5712. ftype = filep%ftypes(iftype)
  5713. ! select appropriate routine for each type:
  5714. select case ( ftype )
  5715. #ifdef with_hdf4
  5716. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5717. case ( MDF_HDF4 )
  5718. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5719. ! check ...
  5720. if ( present(map ) ) then
  5721. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5722. TRACEBACK; status=1; return
  5723. end if
  5724. ! fill offset (zero based!), stride, and count :
  5725. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5726. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5727. hdf4_count = 1 ! default singleton dimension
  5728. hdf4_count(1:1) = shape(values)
  5729. ! test source type:
  5730. select case ( varp%hdf4_xtype )
  5731. case ( DFNT_INT8 )
  5732. allocate( values_int1(size(values,1)) )
  5733. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  5734. values = int(values_int1,kind=1)
  5735. deallocate( values_int1 )
  5736. case ( DFNT_INT16 )
  5737. allocate( values_int2(size(values,1)) )
  5738. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  5739. values = int(values_int2,kind=1)
  5740. deallocate( values_int2 )
  5741. case ( DFNT_INT32 )
  5742. allocate( values_int4(size(values,1)) )
  5743. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  5744. values = int(values_int4,kind=1)
  5745. deallocate( values_int4 )
  5746. case ( DFNT_INT64 )
  5747. allocate( values_int8(size(values,1)) )
  5748. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  5749. values = int(values_int8,kind=1)
  5750. deallocate( values_int8 )
  5751. case ( DFNT_FLOAT32 )
  5752. allocate( values_real4(size(values,1)) )
  5753. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  5754. values = int(values_real4,kind=1)
  5755. deallocate( values_real4 )
  5756. case ( DFNT_FLOAT64 )
  5757. allocate( values_real8(size(values,1)) )
  5758. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  5759. values = int(values_real8,kind=1)
  5760. deallocate( values_real8 )
  5761. case default
  5762. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  5763. TRACEBACK; status=1; return
  5764. end select
  5765. if ( status == FAIL ) then
  5766. write (gol,'("reading hdf4 data set:")'); call goErr
  5767. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  5768. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  5769. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  5770. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  5771. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  5772. write (gol,'(" size : ",i6)') size(values); call goErr
  5773. TRACEBACK; status=1; return
  5774. end if
  5775. #endif
  5776. #ifdef with_netcdf
  5777. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5778. case ( MDF_NETCDF, MDF_NETCDF4 )
  5779. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5780. ! read values, converted automatically:
  5781. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  5782. start, count, stride, map )
  5783. IF_NF90_NOT_OK_RETURN(status=1)
  5784. #endif
  5785. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5786. case default
  5787. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5788. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  5789. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  5790. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  5791. TRACEBACK; status=1; return
  5792. end select
  5793. end do ! file types
  5794. ! ok
  5795. status = 0
  5796. end subroutine MDF_Get_Var_i1_1d
  5797. ! ***
  5798. subroutine MDF_Put_Var_i1_2d( hid, varid, values, status, &
  5799. start, count, stride, map )
  5800. #ifdef with_hdf5_beta
  5801. use HDF5, only : HID_T, HSIZE_T
  5802. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  5803. use HDF5, only : H5T_NATIVE_CHARACTER
  5804. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  5805. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  5806. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  5807. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  5808. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  5809. #endif
  5810. #ifdef with_netcdf
  5811. use NetCDF, only : NF90_Put_Var
  5812. #endif
  5813. ! --- in/out -------------------------------------
  5814. integer, intent(in) :: hid
  5815. integer, intent(in) :: varid
  5816. integer(1), intent(in) :: values(:,:)
  5817. integer, intent(out) :: status
  5818. integer, intent(in), optional :: start (:)
  5819. integer, intent(in), optional :: count (:)
  5820. integer, intent(in), optional :: stride(:)
  5821. integer, intent(in), optional :: map (:)
  5822. ! --- const --------------------------------------
  5823. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_2d'
  5824. ! --- external -----------------------------------
  5825. #ifdef with_hdf4
  5826. integer(hdf4_wpi), external :: sfWData
  5827. #endif
  5828. ! --- local --------------------------------------
  5829. type(MDF_File), pointer :: filep
  5830. type(MDF_Var), pointer :: varp
  5831. integer :: iftype
  5832. integer :: ftype
  5833. #ifdef with_hdf4
  5834. integer :: hdf4_offset(MAX_RANK)
  5835. integer :: hdf4_stride(MAX_RANK)
  5836. integer :: hdf4_count(MAX_RANK)
  5837. #endif
  5838. #ifdef with_hdf5_beta
  5839. !integer(HID_T) :: hdf5_type_id
  5840. integer(HID_T) :: hdf5_file_space_id
  5841. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  5842. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  5843. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  5844. #endif
  5845. integer(1), allocatable :: values_int1(:,:)
  5846. integer(2), allocatable :: values_int2(:,:)
  5847. integer(4), allocatable :: values_int4(:,:)
  5848. integer(8), allocatable :: values_int8(:,:)
  5849. real(4), allocatable :: values_real4(:,:)
  5850. real(8), allocatable :: values_real8(:,:)
  5851. ! --- begin --------------------------------------
  5852. ! pointer to file structure:
  5853. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  5854. IF_NOT_OK_RETURN(status=1)
  5855. ! pointer to variable structure:
  5856. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  5857. IF_NOT_OK_RETURN(status=1)
  5858. ! check ...
  5859. if ( size(shape(values)) > varp%ndim ) then
  5860. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  5861. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  5862. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  5863. TRACEBACK; status=1; return
  5864. end if
  5865. ! check ...
  5866. if ( present(start ) ) then
  5867. if ( size(start ) /= varp%ndim ) then
  5868. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5869. write (gol,'(" size start : ",i6)') size(start ); call goErr
  5870. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5871. TRACEBACK; status=1; return
  5872. end if
  5873. end if
  5874. if ( present(count ) ) then
  5875. if ( size(count ) /= varp%ndim ) then
  5876. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5877. write (gol,'(" size count : ",i6)') size(count ); call goErr
  5878. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5879. TRACEBACK; status=1; return
  5880. end if
  5881. end if
  5882. if ( present(stride ) ) then
  5883. if ( size(stride ) /= varp%ndim ) then
  5884. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5885. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  5886. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5887. TRACEBACK; status=1; return
  5888. end if
  5889. end if
  5890. if ( present(map ) ) then
  5891. if ( size(map ) /= varp%ndim ) then
  5892. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  5893. write (gol,'(" size map : ",i6)') size(map ); call goErr
  5894. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  5895. TRACEBACK; status=1; return
  5896. end if
  5897. end if
  5898. ! loop over file types:
  5899. do iftype = 1, filep%nftype
  5900. ! current type:
  5901. ftype = filep%ftypes(iftype)
  5902. ! select appropriate routine for each type:
  5903. select case ( ftype )
  5904. #ifdef with_hdf4
  5905. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5906. case ( MDF_HDF4 )
  5907. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5908. ! check ...
  5909. if ( present(map ) ) then
  5910. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  5911. TRACEBACK; status=1; return
  5912. end if
  5913. ! fill offset (zero based!) and stride with default values:
  5914. hdf4_offset = 0
  5915. hdf4_stride = 1
  5916. ! count is by default the shape; padd with singleton dimensions:
  5917. hdf4_count = 1; hdf4_count(1:2) = shape(values)
  5918. ! replace by optional arguments if necessary:
  5919. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  5920. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  5921. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  5922. ! test target type;
  5923. ! convert to required kind before entering sfWData,
  5924. ! otherwise segmentation faults on some machines ...
  5925. select case ( varp%xtype )
  5926. case ( MDF_BYTE )
  5927. allocate( values_int1(size(values,1),size(values,2)) )
  5928. values_int1 = int(values,kind=1)
  5929. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5930. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  5931. deallocate( values_int1 )
  5932. case ( MDF_SHORT )
  5933. allocate( values_int2(size(values,1),size(values,2)) )
  5934. values_int2 = int(values,kind=2)
  5935. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5936. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  5937. deallocate( values_int2 )
  5938. case ( MDF_INT )
  5939. allocate( values_int4(size(values,1),size(values,2)) )
  5940. values_int4 = int(values,kind=4)
  5941. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5942. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  5943. deallocate( values_int4 )
  5944. case ( MDF_FLOAT )
  5945. allocate( values_real4(size(values,1),size(values,2)) )
  5946. values_real4 = real(values,kind=4)
  5947. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5948. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  5949. deallocate( values_real4 )
  5950. case ( MDF_DOUBLE )
  5951. allocate( values_real8(size(values,1),size(values,2)) )
  5952. values_real8 = real(values,kind=8)
  5953. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  5954. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  5955. deallocate( values_real8 )
  5956. case default
  5957. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  5958. TRACEBACK; status=1; return
  5959. end select
  5960. if ( status == FAIL ) then
  5961. write (gol,'("writing hdf4 data set:")'); call goErr
  5962. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  5963. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  5964. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  5965. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  5966. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  5967. write (gol,'(" size : ",i12)') size(values); call goErr
  5968. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  5969. TRACEBACK; status=1; return
  5970. end if
  5971. #endif
  5972. #ifdef with_hdf5_beta
  5973. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5974. case ( MDF_HDF5 )
  5975. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  5976. ! check ...
  5977. if ( present(map ) ) then
  5978. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  5979. TRACEBACK; status=1; return
  5980. end if
  5981. ! fill offset (zero based!), stride, and count :
  5982. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  5983. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  5984. hdf5_count = 1 ! default singleton dimension
  5985. if ( present(count) ) then
  5986. hdf5_count(1:varp%ndim) = count
  5987. else
  5988. hdf5_count(1:2) = shape(values)
  5989. end if
  5990. ! new dimension:
  5991. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  5992. ! target data space in file:
  5993. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  5994. IF_NOT_OK_RETURN(status=1)
  5995. ! chunked dataset ?
  5996. if ( varp%hdf5_chunked ) then
  5997. ! reset extend:
  5998. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  5999. IF_NOT_OK_RETURN(status=1)
  6000. end if
  6001. ! select hyperslab:
  6002. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  6003. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  6004. stride=hdf5_stride(1:varp%ndim) )
  6005. ! write data:
  6006. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  6007. int(shape(values),kind=HSIZE_T), status, &
  6008. file_space_id=hdf5_file_space_id )
  6009. IF_NOT_OK_RETURN(status=1)
  6010. ! release data space:
  6011. call H5SClose_f( hdf5_file_space_id, status )
  6012. IF_NOT_OK_RETURN(status=1)
  6013. #endif
  6014. #ifdef with_netcdf
  6015. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6016. case ( MDF_NETCDF, MDF_NETCDF4 )
  6017. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6018. ! test target type:
  6019. ! convert to required kind before entering NF90_Put_Var,
  6020. ! otherwise segmentation faults on some machines ...
  6021. select case ( varp%xtype )
  6022. case ( MDF_BYTE )
  6023. allocate( values_int1(size(values,1),size(values,2)) )
  6024. values_int1 = int(values,kind=1)
  6025. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  6026. start, count, stride, map )
  6027. IF_NF90_NOT_OK_RETURN(status=1)
  6028. deallocate( values_int1 )
  6029. case ( MDF_SHORT )
  6030. allocate( values_int2(size(values,1),size(values,2)) )
  6031. values_int2 = int(values,kind=2)
  6032. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  6033. start, count, stride, map )
  6034. IF_NF90_NOT_OK_RETURN(status=1)
  6035. deallocate( values_int2 )
  6036. case ( MDF_INT )
  6037. allocate( values_int4(size(values,1),size(values,2)) )
  6038. values_int4 = int(values,kind=4)
  6039. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  6040. start, count, stride, map )
  6041. IF_NF90_NOT_OK_RETURN(status=1)
  6042. deallocate( values_int4 )
  6043. case ( MDF_FLOAT )
  6044. allocate( values_real4(size(values,1),size(values,2)) )
  6045. values_real4 = real(values,kind=4)
  6046. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  6047. start, count, stride, map )
  6048. IF_NF90_NOT_OK_RETURN(status=1)
  6049. deallocate( values_real4 )
  6050. case ( MDF_DOUBLE )
  6051. allocate( values_real8(size(values,1),size(values,2)) )
  6052. values_real8 = real(values,kind=8)
  6053. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  6054. start, count, stride, map )
  6055. IF_NF90_NOT_OK_RETURN(status=1)
  6056. deallocate( values_real8 )
  6057. case default
  6058. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  6059. TRACEBACK; status=1; return
  6060. end select
  6061. ! just put; let netcdf library convert the right kind:
  6062. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  6063. ! start, count, stride, map )
  6064. !IF_NF90_NOT_OK_RETURN(status=1)
  6065. #endif
  6066. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6067. case default
  6068. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6069. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  6070. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  6071. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  6072. TRACEBACK; status=1; return
  6073. end select
  6074. end do ! file types
  6075. ! ok
  6076. status = 0
  6077. end subroutine MDF_Put_Var_i1_2d
  6078. ! ***
  6079. subroutine MDF_Get_Var_i1_2d( hid, varid, values, status, &
  6080. start, count, stride, map )
  6081. #ifdef with_netcdf
  6082. use NetCDF, only : NF90_Get_Var
  6083. #endif
  6084. ! --- in/out -------------------------------------
  6085. integer, intent(in) :: hid
  6086. integer, intent(in) :: varid
  6087. integer(1), intent(out) :: values(:,:)
  6088. integer, intent(out) :: status
  6089. integer, intent(in), optional :: start (:)
  6090. integer, intent(in), optional :: count (:)
  6091. integer, intent(in), optional :: stride(:)
  6092. integer, intent(in), optional :: map (:)
  6093. ! --- const --------------------------------------
  6094. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_2d'
  6095. ! --- external -----------------------------------
  6096. #ifdef with_hdf4
  6097. integer(hdf4_wpi), external :: sfRData
  6098. #endif
  6099. ! --- local --------------------------------------
  6100. type(MDF_File), pointer :: filep
  6101. type(MDF_Var), pointer :: varp
  6102. integer :: iftype
  6103. integer :: ftype
  6104. #ifdef with_hdf4
  6105. integer :: hdf4_offset(MAX_RANK)
  6106. integer :: hdf4_stride(MAX_RANK)
  6107. integer :: hdf4_count(MAX_RANK)
  6108. integer(1), allocatable :: values_int1(:,:)
  6109. integer(2), allocatable :: values_int2(:,:)
  6110. integer(4), allocatable :: values_int4(:,:)
  6111. integer(8), allocatable :: values_int8(:,:)
  6112. real(4), allocatable :: values_real4(:,:)
  6113. real(8), allocatable :: values_real8(:,:)
  6114. #endif
  6115. ! --- begin --------------------------------------
  6116. ! pointer to file structure:
  6117. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  6118. IF_NOT_OK_RETURN(status=1)
  6119. ! pointer to variable structure:
  6120. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  6121. IF_NOT_OK_RETURN(status=1)
  6122. ! check ...
  6123. if ( size(shape(values)) > varp%ndim ) then
  6124. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  6125. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  6126. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  6127. TRACEBACK; status=1; return
  6128. end if
  6129. ! check ...
  6130. if ( present(start ) ) then
  6131. if ( size(start ) /= varp%ndim ) then
  6132. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6133. write (gol,'(" size start : ",i6)') size(start ); call goErr
  6134. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6135. TRACEBACK; status=1; return
  6136. end if
  6137. end if
  6138. if ( present(count ) ) then
  6139. if ( size(count ) /= varp%ndim ) then
  6140. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6141. write (gol,'(" size count : ",i6)') size(count ); call goErr
  6142. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6143. TRACEBACK; status=1; return
  6144. end if
  6145. end if
  6146. if ( present(stride ) ) then
  6147. if ( size(stride ) /= varp%ndim ) then
  6148. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6149. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  6150. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6151. TRACEBACK; status=1; return
  6152. end if
  6153. end if
  6154. if ( present(map ) ) then
  6155. if ( size(map ) /= varp%ndim ) then
  6156. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6157. write (gol,'(" size map : ",i6)') size(map ); call goErr
  6158. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6159. TRACEBACK; status=1; return
  6160. end if
  6161. end if
  6162. ! loop over file types:
  6163. do iftype = 1, filep%nftype
  6164. ! current type:
  6165. ftype = filep%ftypes(iftype)
  6166. ! select appropriate routine for each type:
  6167. select case ( ftype )
  6168. #ifdef with_hdf4
  6169. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6170. case ( MDF_HDF4 )
  6171. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6172. ! check ...
  6173. if ( present(map ) ) then
  6174. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  6175. TRACEBACK; status=1; return
  6176. end if
  6177. ! fill offset (zero based!), stride, and count :
  6178. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  6179. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  6180. hdf4_count = 1 ! default singleton dimension
  6181. hdf4_count(1:2) = shape(values)
  6182. ! test source type:
  6183. select case ( varp%hdf4_xtype )
  6184. case ( DFNT_INT8 )
  6185. allocate( values_int1(size(values,1),size(values,2)) )
  6186. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  6187. values = int(values_int1,kind=1)
  6188. deallocate( values_int1 )
  6189. case ( DFNT_INT16 )
  6190. allocate( values_int2(size(values,1),size(values,2)) )
  6191. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  6192. values = int(values_int2,kind=1)
  6193. deallocate( values_int2 )
  6194. case ( DFNT_INT32 )
  6195. allocate( values_int4(size(values,1),size(values,2)) )
  6196. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  6197. values = int(values_int4,kind=1)
  6198. deallocate( values_int4 )
  6199. case ( DFNT_INT64 )
  6200. allocate( values_int8(size(values,1),size(values,2)) )
  6201. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  6202. values = int(values_int8,kind=1)
  6203. deallocate( values_int8 )
  6204. case ( DFNT_FLOAT32 )
  6205. allocate( values_real4(size(values,1),size(values,2)) )
  6206. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  6207. values = int(values_real4,kind=1)
  6208. deallocate( values_real4 )
  6209. case ( DFNT_FLOAT64 )
  6210. allocate( values_real8(size(values,1),size(values,2)) )
  6211. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  6212. values = int(values_real8,kind=1)
  6213. deallocate( values_real8 )
  6214. case default
  6215. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  6216. TRACEBACK; status=1; return
  6217. end select
  6218. if ( status == FAIL ) then
  6219. write (gol,'("reading hdf4 data set:")'); call goErr
  6220. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  6221. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  6222. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  6223. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  6224. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  6225. write (gol,'(" size : ",i6)') size(values); call goErr
  6226. TRACEBACK; status=1; return
  6227. end if
  6228. #endif
  6229. #ifdef with_netcdf
  6230. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6231. case ( MDF_NETCDF, MDF_NETCDF4 )
  6232. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6233. ! read values, converted automatically:
  6234. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  6235. start, count, stride, map )
  6236. IF_NF90_NOT_OK_RETURN(status=1)
  6237. #endif
  6238. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6239. case default
  6240. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6241. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  6242. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  6243. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  6244. TRACEBACK; status=1; return
  6245. end select
  6246. end do ! file types
  6247. ! ok
  6248. status = 0
  6249. end subroutine MDF_Get_Var_i1_2d
  6250. ! ***
  6251. subroutine MDF_Put_Var_i1_3d( hid, varid, values, status, &
  6252. start, count, stride, map )
  6253. #ifdef with_hdf5_beta
  6254. use HDF5, only : HID_T, HSIZE_T
  6255. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  6256. use HDF5, only : H5T_NATIVE_CHARACTER
  6257. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  6258. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  6259. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  6260. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  6261. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  6262. #endif
  6263. #ifdef with_netcdf
  6264. use NetCDF, only : NF90_Put_Var
  6265. #endif
  6266. ! --- in/out -------------------------------------
  6267. integer, intent(in) :: hid
  6268. integer, intent(in) :: varid
  6269. integer(1), intent(in) :: values(:,:,:)
  6270. integer, intent(out) :: status
  6271. integer, intent(in), optional :: start (:)
  6272. integer, intent(in), optional :: count (:)
  6273. integer, intent(in), optional :: stride(:)
  6274. integer, intent(in), optional :: map (:)
  6275. ! --- const --------------------------------------
  6276. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_3d'
  6277. ! --- external -----------------------------------
  6278. #ifdef with_hdf4
  6279. integer(hdf4_wpi), external :: sfWData
  6280. #endif
  6281. ! --- local --------------------------------------
  6282. type(MDF_File), pointer :: filep
  6283. type(MDF_Var), pointer :: varp
  6284. integer :: iftype
  6285. integer :: ftype
  6286. #ifdef with_hdf4
  6287. integer :: hdf4_offset(MAX_RANK)
  6288. integer :: hdf4_stride(MAX_RANK)
  6289. integer :: hdf4_count(MAX_RANK)
  6290. #endif
  6291. #ifdef with_hdf5_beta
  6292. !integer(HID_T) :: hdf5_type_id
  6293. integer(HID_T) :: hdf5_file_space_id
  6294. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  6295. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  6296. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  6297. #endif
  6298. integer(1), allocatable :: values_int1(:,:,:)
  6299. integer(2), allocatable :: values_int2(:,:,:)
  6300. integer(4), allocatable :: values_int4(:,:,:)
  6301. integer(8), allocatable :: values_int8(:,:,:)
  6302. real(4), allocatable :: values_real4(:,:,:)
  6303. real(8), allocatable :: values_real8(:,:,:)
  6304. ! --- begin --------------------------------------
  6305. ! pointer to file structure:
  6306. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  6307. IF_NOT_OK_RETURN(status=1)
  6308. ! pointer to variable structure:
  6309. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  6310. IF_NOT_OK_RETURN(status=1)
  6311. ! check ...
  6312. if ( size(shape(values)) > varp%ndim ) then
  6313. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  6314. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  6315. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  6316. TRACEBACK; status=1; return
  6317. end if
  6318. ! check ...
  6319. if ( present(start ) ) then
  6320. if ( size(start ) /= varp%ndim ) then
  6321. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6322. write (gol,'(" size start : ",i6)') size(start ); call goErr
  6323. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6324. TRACEBACK; status=1; return
  6325. end if
  6326. end if
  6327. if ( present(count ) ) then
  6328. if ( size(count ) /= varp%ndim ) then
  6329. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6330. write (gol,'(" size count : ",i6)') size(count ); call goErr
  6331. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6332. TRACEBACK; status=1; return
  6333. end if
  6334. end if
  6335. if ( present(stride ) ) then
  6336. if ( size(stride ) /= varp%ndim ) then
  6337. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6338. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  6339. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6340. TRACEBACK; status=1; return
  6341. end if
  6342. end if
  6343. if ( present(map ) ) then
  6344. if ( size(map ) /= varp%ndim ) then
  6345. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6346. write (gol,'(" size map : ",i6)') size(map ); call goErr
  6347. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6348. TRACEBACK; status=1; return
  6349. end if
  6350. end if
  6351. ! loop over file types:
  6352. do iftype = 1, filep%nftype
  6353. ! current type:
  6354. ftype = filep%ftypes(iftype)
  6355. ! select appropriate routine for each type:
  6356. select case ( ftype )
  6357. #ifdef with_hdf4
  6358. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6359. case ( MDF_HDF4 )
  6360. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6361. ! check ...
  6362. if ( present(map ) ) then
  6363. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  6364. TRACEBACK; status=1; return
  6365. end if
  6366. ! fill offset (zero based!) and stride with default values:
  6367. hdf4_offset = 0
  6368. hdf4_stride = 1
  6369. ! count is by default the shape; padd with singleton dimensions:
  6370. hdf4_count = 1; hdf4_count(1:3) = shape(values)
  6371. ! replace by optional arguments if necessary:
  6372. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  6373. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  6374. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  6375. ! test target type;
  6376. ! convert to required kind before entering sfWData,
  6377. ! otherwise segmentation faults on some machines ...
  6378. select case ( varp%xtype )
  6379. case ( MDF_BYTE )
  6380. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  6381. values_int1 = int(values,kind=1)
  6382. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6383. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  6384. deallocate( values_int1 )
  6385. case ( MDF_SHORT )
  6386. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  6387. values_int2 = int(values,kind=2)
  6388. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6389. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  6390. deallocate( values_int2 )
  6391. case ( MDF_INT )
  6392. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  6393. values_int4 = int(values,kind=4)
  6394. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6395. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  6396. deallocate( values_int4 )
  6397. case ( MDF_FLOAT )
  6398. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  6399. values_real4 = real(values,kind=4)
  6400. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6401. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  6402. deallocate( values_real4 )
  6403. case ( MDF_DOUBLE )
  6404. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  6405. values_real8 = real(values,kind=8)
  6406. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6407. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  6408. deallocate( values_real8 )
  6409. case default
  6410. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  6411. TRACEBACK; status=1; return
  6412. end select
  6413. if ( status == FAIL ) then
  6414. write (gol,'("writing hdf4 data set:")'); call goErr
  6415. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  6416. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  6417. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  6418. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  6419. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  6420. write (gol,'(" size : ",i12)') size(values); call goErr
  6421. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  6422. TRACEBACK; status=1; return
  6423. end if
  6424. #endif
  6425. #ifdef with_hdf5_beta
  6426. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6427. case ( MDF_HDF5 )
  6428. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6429. ! check ...
  6430. if ( present(map ) ) then
  6431. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  6432. TRACEBACK; status=1; return
  6433. end if
  6434. ! fill offset (zero based!), stride, and count :
  6435. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  6436. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  6437. hdf5_count = 1 ! default singleton dimension
  6438. if ( present(count) ) then
  6439. hdf5_count(1:varp%ndim) = count
  6440. else
  6441. hdf5_count(1:3) = shape(values)
  6442. end if
  6443. ! new dimension:
  6444. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  6445. ! target data space in file:
  6446. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  6447. IF_NOT_OK_RETURN(status=1)
  6448. ! chunked dataset ?
  6449. if ( varp%hdf5_chunked ) then
  6450. ! reset extend:
  6451. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  6452. IF_NOT_OK_RETURN(status=1)
  6453. end if
  6454. ! select hyperslab:
  6455. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  6456. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  6457. stride=hdf5_stride(1:varp%ndim) )
  6458. ! write data:
  6459. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  6460. int(shape(values),kind=HSIZE_T), status, &
  6461. file_space_id=hdf5_file_space_id )
  6462. IF_NOT_OK_RETURN(status=1)
  6463. ! release data space:
  6464. call H5SClose_f( hdf5_file_space_id, status )
  6465. IF_NOT_OK_RETURN(status=1)
  6466. #endif
  6467. #ifdef with_netcdf
  6468. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6469. case ( MDF_NETCDF, MDF_NETCDF4 )
  6470. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6471. ! test target type:
  6472. ! convert to required kind before entering NF90_Put_Var,
  6473. ! otherwise segmentation faults on some machines ...
  6474. select case ( varp%xtype )
  6475. case ( MDF_BYTE )
  6476. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  6477. values_int1 = int(values,kind=1)
  6478. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  6479. start, count, stride, map )
  6480. IF_NF90_NOT_OK_RETURN(status=1)
  6481. deallocate( values_int1 )
  6482. case ( MDF_SHORT )
  6483. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  6484. values_int2 = int(values,kind=2)
  6485. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  6486. start, count, stride, map )
  6487. IF_NF90_NOT_OK_RETURN(status=1)
  6488. deallocate( values_int2 )
  6489. case ( MDF_INT )
  6490. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  6491. values_int4 = int(values,kind=4)
  6492. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  6493. start, count, stride, map )
  6494. IF_NF90_NOT_OK_RETURN(status=1)
  6495. deallocate( values_int4 )
  6496. case ( MDF_FLOAT )
  6497. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  6498. values_real4 = real(values,kind=4)
  6499. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  6500. start, count, stride, map )
  6501. IF_NF90_NOT_OK_RETURN(status=1)
  6502. deallocate( values_real4 )
  6503. case ( MDF_DOUBLE )
  6504. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  6505. values_real8 = real(values,kind=8)
  6506. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  6507. start, count, stride, map )
  6508. IF_NF90_NOT_OK_RETURN(status=1)
  6509. deallocate( values_real8 )
  6510. case default
  6511. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  6512. TRACEBACK; status=1; return
  6513. end select
  6514. ! just put; let netcdf library convert the right kind:
  6515. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  6516. ! start, count, stride, map )
  6517. !IF_NF90_NOT_OK_RETURN(status=1)
  6518. #endif
  6519. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6520. case default
  6521. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6522. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  6523. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  6524. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  6525. TRACEBACK; status=1; return
  6526. end select
  6527. end do ! file types
  6528. ! ok
  6529. status = 0
  6530. end subroutine MDF_Put_Var_i1_3d
  6531. ! ***
  6532. subroutine MDF_Get_Var_i1_3d( hid, varid, values, status, &
  6533. start, count, stride, map )
  6534. #ifdef with_netcdf
  6535. use NetCDF, only : NF90_Get_Var
  6536. #endif
  6537. ! --- in/out -------------------------------------
  6538. integer, intent(in) :: hid
  6539. integer, intent(in) :: varid
  6540. integer(1), intent(out) :: values(:,:,:)
  6541. integer, intent(out) :: status
  6542. integer, intent(in), optional :: start (:)
  6543. integer, intent(in), optional :: count (:)
  6544. integer, intent(in), optional :: stride(:)
  6545. integer, intent(in), optional :: map (:)
  6546. ! --- const --------------------------------------
  6547. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_3d'
  6548. ! --- external -----------------------------------
  6549. #ifdef with_hdf4
  6550. integer(hdf4_wpi), external :: sfRData
  6551. #endif
  6552. ! --- local --------------------------------------
  6553. type(MDF_File), pointer :: filep
  6554. type(MDF_Var), pointer :: varp
  6555. integer :: iftype
  6556. integer :: ftype
  6557. #ifdef with_hdf4
  6558. integer :: hdf4_offset(MAX_RANK)
  6559. integer :: hdf4_stride(MAX_RANK)
  6560. integer :: hdf4_count(MAX_RANK)
  6561. integer(1), allocatable :: values_int1(:,:,:)
  6562. integer(2), allocatable :: values_int2(:,:,:)
  6563. integer(4), allocatable :: values_int4(:,:,:)
  6564. integer(8), allocatable :: values_int8(:,:,:)
  6565. real(4), allocatable :: values_real4(:,:,:)
  6566. real(8), allocatable :: values_real8(:,:,:)
  6567. #endif
  6568. ! --- begin --------------------------------------
  6569. ! pointer to file structure:
  6570. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  6571. IF_NOT_OK_RETURN(status=1)
  6572. ! pointer to variable structure:
  6573. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  6574. IF_NOT_OK_RETURN(status=1)
  6575. ! check ...
  6576. if ( size(shape(values)) > varp%ndim ) then
  6577. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  6578. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  6579. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  6580. TRACEBACK; status=1; return
  6581. end if
  6582. ! check ...
  6583. if ( present(start ) ) then
  6584. if ( size(start ) /= varp%ndim ) then
  6585. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6586. write (gol,'(" size start : ",i6)') size(start ); call goErr
  6587. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6588. TRACEBACK; status=1; return
  6589. end if
  6590. end if
  6591. if ( present(count ) ) then
  6592. if ( size(count ) /= varp%ndim ) then
  6593. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6594. write (gol,'(" size count : ",i6)') size(count ); call goErr
  6595. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6596. TRACEBACK; status=1; return
  6597. end if
  6598. end if
  6599. if ( present(stride ) ) then
  6600. if ( size(stride ) /= varp%ndim ) then
  6601. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6602. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  6603. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6604. TRACEBACK; status=1; return
  6605. end if
  6606. end if
  6607. if ( present(map ) ) then
  6608. if ( size(map ) /= varp%ndim ) then
  6609. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6610. write (gol,'(" size map : ",i6)') size(map ); call goErr
  6611. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6612. TRACEBACK; status=1; return
  6613. end if
  6614. end if
  6615. ! loop over file types:
  6616. do iftype = 1, filep%nftype
  6617. ! current type:
  6618. ftype = filep%ftypes(iftype)
  6619. ! select appropriate routine for each type:
  6620. select case ( ftype )
  6621. #ifdef with_hdf4
  6622. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6623. case ( MDF_HDF4 )
  6624. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6625. ! check ...
  6626. if ( present(map ) ) then
  6627. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  6628. TRACEBACK; status=1; return
  6629. end if
  6630. ! fill offset (zero based!), stride, and count :
  6631. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  6632. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  6633. hdf4_count = 1 ! default singleton dimension
  6634. hdf4_count(1:3) = shape(values)
  6635. ! test source type:
  6636. select case ( varp%hdf4_xtype )
  6637. case ( DFNT_INT8 )
  6638. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  6639. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  6640. values = int(values_int1,kind=1)
  6641. deallocate( values_int1 )
  6642. case ( DFNT_INT16 )
  6643. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  6644. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  6645. values = int(values_int2,kind=1)
  6646. deallocate( values_int2 )
  6647. case ( DFNT_INT32 )
  6648. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  6649. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  6650. values = int(values_int4,kind=1)
  6651. deallocate( values_int4 )
  6652. case ( DFNT_INT64 )
  6653. allocate( values_int8(size(values,1),size(values,2),size(values,3)) )
  6654. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  6655. values = int(values_int8,kind=1)
  6656. deallocate( values_int8 )
  6657. case ( DFNT_FLOAT32 )
  6658. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  6659. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  6660. values = int(values_real4,kind=1)
  6661. deallocate( values_real4 )
  6662. case ( DFNT_FLOAT64 )
  6663. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  6664. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  6665. values = int(values_real8,kind=1)
  6666. deallocate( values_real8 )
  6667. case default
  6668. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  6669. TRACEBACK; status=1; return
  6670. end select
  6671. if ( status == FAIL ) then
  6672. write (gol,'("reading hdf4 data set:")'); call goErr
  6673. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  6674. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  6675. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  6676. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  6677. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  6678. write (gol,'(" size : ",i6)') size(values); call goErr
  6679. TRACEBACK; status=1; return
  6680. end if
  6681. #endif
  6682. #ifdef with_netcdf
  6683. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6684. case ( MDF_NETCDF, MDF_NETCDF4 )
  6685. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6686. ! read values, converted automatically:
  6687. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  6688. start, count, stride, map )
  6689. IF_NF90_NOT_OK_RETURN(status=1)
  6690. #endif
  6691. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6692. case default
  6693. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6694. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  6695. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  6696. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  6697. TRACEBACK; status=1; return
  6698. end select
  6699. end do ! file types
  6700. ! ok
  6701. status = 0
  6702. end subroutine MDF_Get_Var_i1_3d
  6703. ! ***
  6704. subroutine MDF_Put_Var_i1_4d( hid, varid, values, status, &
  6705. start, count, stride, map )
  6706. #ifdef with_hdf5_beta
  6707. use HDF5, only : HID_T, HSIZE_T
  6708. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  6709. use HDF5, only : H5T_NATIVE_CHARACTER
  6710. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  6711. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  6712. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  6713. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  6714. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  6715. #endif
  6716. #ifdef with_netcdf
  6717. use NetCDF, only : NF90_Put_Var
  6718. #endif
  6719. ! --- in/out -------------------------------------
  6720. integer, intent(in) :: hid
  6721. integer, intent(in) :: varid
  6722. integer(1), intent(in) :: values(:,:,:,:)
  6723. integer, intent(out) :: status
  6724. integer, intent(in), optional :: start (:)
  6725. integer, intent(in), optional :: count (:)
  6726. integer, intent(in), optional :: stride(:)
  6727. integer, intent(in), optional :: map (:)
  6728. ! --- const --------------------------------------
  6729. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_4d'
  6730. ! --- external -----------------------------------
  6731. #ifdef with_hdf4
  6732. integer(hdf4_wpi), external :: sfWData
  6733. #endif
  6734. ! --- local --------------------------------------
  6735. type(MDF_File), pointer :: filep
  6736. type(MDF_Var), pointer :: varp
  6737. integer :: iftype
  6738. integer :: ftype
  6739. #ifdef with_hdf4
  6740. integer :: hdf4_offset(MAX_RANK)
  6741. integer :: hdf4_stride(MAX_RANK)
  6742. integer :: hdf4_count(MAX_RANK)
  6743. #endif
  6744. #ifdef with_hdf5_beta
  6745. !integer(HID_T) :: hdf5_type_id
  6746. integer(HID_T) :: hdf5_file_space_id
  6747. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  6748. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  6749. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  6750. #endif
  6751. integer(1), allocatable :: values_int1(:,:,:,:)
  6752. integer(2), allocatable :: values_int2(:,:,:,:)
  6753. integer(4), allocatable :: values_int4(:,:,:,:)
  6754. integer(8), allocatable :: values_int8(:,:,:,:)
  6755. real(4), allocatable :: values_real4(:,:,:,:)
  6756. real(8), allocatable :: values_real8(:,:,:,:)
  6757. ! --- begin --------------------------------------
  6758. ! pointer to file structure:
  6759. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  6760. IF_NOT_OK_RETURN(status=1)
  6761. ! pointer to variable structure:
  6762. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  6763. IF_NOT_OK_RETURN(status=1)
  6764. ! check ...
  6765. if ( size(shape(values)) > varp%ndim ) then
  6766. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  6767. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  6768. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  6769. TRACEBACK; status=1; return
  6770. end if
  6771. ! check ...
  6772. if ( present(start ) ) then
  6773. if ( size(start ) /= varp%ndim ) then
  6774. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6775. write (gol,'(" size start : ",i6)') size(start ); call goErr
  6776. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6777. TRACEBACK; status=1; return
  6778. end if
  6779. end if
  6780. if ( present(count ) ) then
  6781. if ( size(count ) /= varp%ndim ) then
  6782. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6783. write (gol,'(" size count : ",i6)') size(count ); call goErr
  6784. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6785. TRACEBACK; status=1; return
  6786. end if
  6787. end if
  6788. if ( present(stride ) ) then
  6789. if ( size(stride ) /= varp%ndim ) then
  6790. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6791. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  6792. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6793. TRACEBACK; status=1; return
  6794. end if
  6795. end if
  6796. if ( present(map ) ) then
  6797. if ( size(map ) /= varp%ndim ) then
  6798. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  6799. write (gol,'(" size map : ",i6)') size(map ); call goErr
  6800. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  6801. TRACEBACK; status=1; return
  6802. end if
  6803. end if
  6804. ! loop over file types:
  6805. do iftype = 1, filep%nftype
  6806. ! current type:
  6807. ftype = filep%ftypes(iftype)
  6808. ! select appropriate routine for each type:
  6809. select case ( ftype )
  6810. #ifdef with_hdf4
  6811. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6812. case ( MDF_HDF4 )
  6813. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6814. ! check ...
  6815. if ( present(map ) ) then
  6816. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  6817. TRACEBACK; status=1; return
  6818. end if
  6819. ! fill offset (zero based!) and stride with default values:
  6820. hdf4_offset = 0
  6821. hdf4_stride = 1
  6822. ! count is by default the shape; padd with singleton dimensions:
  6823. hdf4_count = 1; hdf4_count(1:4) = shape(values)
  6824. ! replace by optional arguments if necessary:
  6825. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  6826. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  6827. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  6828. ! test target type;
  6829. ! convert to required kind before entering sfWData,
  6830. ! otherwise segmentation faults on some machines ...
  6831. select case ( varp%xtype )
  6832. case ( MDF_BYTE )
  6833. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6834. values_int1 = int(values,kind=1)
  6835. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6836. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  6837. deallocate( values_int1 )
  6838. case ( MDF_SHORT )
  6839. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6840. values_int2 = int(values,kind=2)
  6841. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6842. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  6843. deallocate( values_int2 )
  6844. case ( MDF_INT )
  6845. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6846. values_int4 = int(values,kind=4)
  6847. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6848. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  6849. deallocate( values_int4 )
  6850. case ( MDF_FLOAT )
  6851. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6852. values_real4 = real(values,kind=4)
  6853. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6854. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  6855. deallocate( values_real4 )
  6856. case ( MDF_DOUBLE )
  6857. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6858. values_real8 = real(values,kind=8)
  6859. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  6860. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  6861. deallocate( values_real8 )
  6862. case default
  6863. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  6864. TRACEBACK; status=1; return
  6865. end select
  6866. if ( status == FAIL ) then
  6867. write (gol,'("writing hdf4 data set:")'); call goErr
  6868. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  6869. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  6870. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  6871. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  6872. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  6873. write (gol,'(" size : ",i12)') size(values); call goErr
  6874. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  6875. TRACEBACK; status=1; return
  6876. end if
  6877. #endif
  6878. #ifdef with_hdf5_beta
  6879. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6880. case ( MDF_HDF5 )
  6881. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6882. ! check ...
  6883. if ( present(map ) ) then
  6884. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  6885. TRACEBACK; status=1; return
  6886. end if
  6887. ! fill offset (zero based!), stride, and count :
  6888. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  6889. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  6890. hdf5_count = 1 ! default singleton dimension
  6891. if ( present(count) ) then
  6892. hdf5_count(1:varp%ndim) = count
  6893. else
  6894. hdf5_count(1:4) = shape(values)
  6895. end if
  6896. ! new dimension:
  6897. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  6898. ! target data space in file:
  6899. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  6900. IF_NOT_OK_RETURN(status=1)
  6901. ! chunked dataset ?
  6902. if ( varp%hdf5_chunked ) then
  6903. ! reset extend:
  6904. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  6905. IF_NOT_OK_RETURN(status=1)
  6906. end if
  6907. ! select hyperslab:
  6908. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  6909. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  6910. stride=hdf5_stride(1:varp%ndim) )
  6911. ! write data:
  6912. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  6913. int(shape(values),kind=HSIZE_T), status, &
  6914. file_space_id=hdf5_file_space_id )
  6915. IF_NOT_OK_RETURN(status=1)
  6916. ! release data space:
  6917. call H5SClose_f( hdf5_file_space_id, status )
  6918. IF_NOT_OK_RETURN(status=1)
  6919. #endif
  6920. #ifdef with_netcdf
  6921. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6922. case ( MDF_NETCDF, MDF_NETCDF4 )
  6923. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6924. ! test target type:
  6925. ! convert to required kind before entering NF90_Put_Var,
  6926. ! otherwise segmentation faults on some machines ...
  6927. select case ( varp%xtype )
  6928. case ( MDF_BYTE )
  6929. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6930. values_int1 = int(values,kind=1)
  6931. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  6932. start, count, stride, map )
  6933. IF_NF90_NOT_OK_RETURN(status=1)
  6934. deallocate( values_int1 )
  6935. case ( MDF_SHORT )
  6936. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6937. values_int2 = int(values,kind=2)
  6938. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  6939. start, count, stride, map )
  6940. IF_NF90_NOT_OK_RETURN(status=1)
  6941. deallocate( values_int2 )
  6942. case ( MDF_INT )
  6943. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6944. values_int4 = int(values,kind=4)
  6945. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  6946. start, count, stride, map )
  6947. IF_NF90_NOT_OK_RETURN(status=1)
  6948. deallocate( values_int4 )
  6949. case ( MDF_FLOAT )
  6950. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6951. values_real4 = real(values,kind=4)
  6952. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  6953. start, count, stride, map )
  6954. IF_NF90_NOT_OK_RETURN(status=1)
  6955. deallocate( values_real4 )
  6956. case ( MDF_DOUBLE )
  6957. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  6958. values_real8 = real(values,kind=8)
  6959. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  6960. start, count, stride, map )
  6961. IF_NF90_NOT_OK_RETURN(status=1)
  6962. deallocate( values_real8 )
  6963. case default
  6964. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  6965. TRACEBACK; status=1; return
  6966. end select
  6967. ! just put; let netcdf library convert the right kind:
  6968. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  6969. ! start, count, stride, map )
  6970. !IF_NF90_NOT_OK_RETURN(status=1)
  6971. #endif
  6972. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6973. case default
  6974. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  6975. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  6976. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  6977. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  6978. TRACEBACK; status=1; return
  6979. end select
  6980. end do ! file types
  6981. ! ok
  6982. status = 0
  6983. end subroutine MDF_Put_Var_i1_4d
  6984. ! ***
  6985. subroutine MDF_Get_Var_i1_4d( hid, varid, values, status, &
  6986. start, count, stride, map )
  6987. #ifdef with_netcdf
  6988. use NetCDF, only : NF90_Get_Var
  6989. #endif
  6990. ! --- in/out -------------------------------------
  6991. integer, intent(in) :: hid
  6992. integer, intent(in) :: varid
  6993. integer(1), intent(out) :: values(:,:,:,:)
  6994. integer, intent(out) :: status
  6995. integer, intent(in), optional :: start (:)
  6996. integer, intent(in), optional :: count (:)
  6997. integer, intent(in), optional :: stride(:)
  6998. integer, intent(in), optional :: map (:)
  6999. ! --- const --------------------------------------
  7000. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_4d'
  7001. ! --- external -----------------------------------
  7002. #ifdef with_hdf4
  7003. integer(hdf4_wpi), external :: sfRData
  7004. #endif
  7005. ! --- local --------------------------------------
  7006. type(MDF_File), pointer :: filep
  7007. type(MDF_Var), pointer :: varp
  7008. integer :: iftype
  7009. integer :: ftype
  7010. #ifdef with_hdf4
  7011. integer :: hdf4_offset(MAX_RANK)
  7012. integer :: hdf4_stride(MAX_RANK)
  7013. integer :: hdf4_count(MAX_RANK)
  7014. integer(1), allocatable :: values_int1(:,:,:,:)
  7015. integer(2), allocatable :: values_int2(:,:,:,:)
  7016. integer(4), allocatable :: values_int4(:,:,:,:)
  7017. integer(8), allocatable :: values_int8(:,:,:,:)
  7018. real(4), allocatable :: values_real4(:,:,:,:)
  7019. real(8), allocatable :: values_real8(:,:,:,:)
  7020. #endif
  7021. ! --- begin --------------------------------------
  7022. ! pointer to file structure:
  7023. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  7024. IF_NOT_OK_RETURN(status=1)
  7025. ! pointer to variable structure:
  7026. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  7027. IF_NOT_OK_RETURN(status=1)
  7028. ! check ...
  7029. if ( size(shape(values)) > varp%ndim ) then
  7030. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  7031. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  7032. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  7033. TRACEBACK; status=1; return
  7034. end if
  7035. ! check ...
  7036. if ( present(start ) ) then
  7037. if ( size(start ) /= varp%ndim ) then
  7038. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7039. write (gol,'(" size start : ",i6)') size(start ); call goErr
  7040. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7041. TRACEBACK; status=1; return
  7042. end if
  7043. end if
  7044. if ( present(count ) ) then
  7045. if ( size(count ) /= varp%ndim ) then
  7046. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7047. write (gol,'(" size count : ",i6)') size(count ); call goErr
  7048. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7049. TRACEBACK; status=1; return
  7050. end if
  7051. end if
  7052. if ( present(stride ) ) then
  7053. if ( size(stride ) /= varp%ndim ) then
  7054. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7055. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  7056. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7057. TRACEBACK; status=1; return
  7058. end if
  7059. end if
  7060. if ( present(map ) ) then
  7061. if ( size(map ) /= varp%ndim ) then
  7062. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7063. write (gol,'(" size map : ",i6)') size(map ); call goErr
  7064. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7065. TRACEBACK; status=1; return
  7066. end if
  7067. end if
  7068. ! loop over file types:
  7069. do iftype = 1, filep%nftype
  7070. ! current type:
  7071. ftype = filep%ftypes(iftype)
  7072. ! select appropriate routine for each type:
  7073. select case ( ftype )
  7074. #ifdef with_hdf4
  7075. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7076. case ( MDF_HDF4 )
  7077. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7078. ! check ...
  7079. if ( present(map ) ) then
  7080. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  7081. TRACEBACK; status=1; return
  7082. end if
  7083. ! fill offset (zero based!), stride, and count :
  7084. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  7085. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  7086. hdf4_count = 1 ! default singleton dimension
  7087. hdf4_count(1:4) = shape(values)
  7088. ! test source type:
  7089. select case ( varp%hdf4_xtype )
  7090. case ( DFNT_INT8 )
  7091. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7092. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  7093. values = int(values_int1,kind=1)
  7094. deallocate( values_int1 )
  7095. case ( DFNT_INT16 )
  7096. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7097. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  7098. values = int(values_int2,kind=1)
  7099. deallocate( values_int2 )
  7100. case ( DFNT_INT32 )
  7101. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7102. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  7103. values = int(values_int4,kind=1)
  7104. deallocate( values_int4 )
  7105. case ( DFNT_INT64 )
  7106. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7107. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  7108. values = int(values_int8,kind=1)
  7109. deallocate( values_int8 )
  7110. case ( DFNT_FLOAT32 )
  7111. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7112. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  7113. values = int(values_real4,kind=1)
  7114. deallocate( values_real4 )
  7115. case ( DFNT_FLOAT64 )
  7116. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  7117. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  7118. values = int(values_real8,kind=1)
  7119. deallocate( values_real8 )
  7120. case default
  7121. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  7122. TRACEBACK; status=1; return
  7123. end select
  7124. if ( status == FAIL ) then
  7125. write (gol,'("reading hdf4 data set:")'); call goErr
  7126. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  7127. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  7128. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  7129. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  7130. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  7131. write (gol,'(" size : ",i6)') size(values); call goErr
  7132. TRACEBACK; status=1; return
  7133. end if
  7134. #endif
  7135. #ifdef with_netcdf
  7136. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7137. case ( MDF_NETCDF, MDF_NETCDF4 )
  7138. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7139. ! read values, converted automatically:
  7140. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  7141. start, count, stride, map )
  7142. IF_NF90_NOT_OK_RETURN(status=1)
  7143. #endif
  7144. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7145. case default
  7146. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7147. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  7148. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  7149. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  7150. TRACEBACK; status=1; return
  7151. end select
  7152. end do ! file types
  7153. ! ok
  7154. status = 0
  7155. end subroutine MDF_Get_Var_i1_4d
  7156. ! ***
  7157. subroutine MDF_Put_Var_i1_5d( hid, varid, values, status, &
  7158. start, count, stride, map )
  7159. #ifdef with_hdf5_beta
  7160. use HDF5, only : HID_T, HSIZE_T
  7161. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  7162. use HDF5, only : H5T_NATIVE_CHARACTER
  7163. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  7164. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  7165. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  7166. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  7167. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  7168. #endif
  7169. #ifdef with_netcdf
  7170. use NetCDF, only : NF90_Put_Var
  7171. #endif
  7172. ! --- in/out -------------------------------------
  7173. integer, intent(in) :: hid
  7174. integer, intent(in) :: varid
  7175. integer(1), intent(in) :: values(:,:,:,:,:)
  7176. integer, intent(out) :: status
  7177. integer, intent(in), optional :: start (:)
  7178. integer, intent(in), optional :: count (:)
  7179. integer, intent(in), optional :: stride(:)
  7180. integer, intent(in), optional :: map (:)
  7181. ! --- const --------------------------------------
  7182. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_5d'
  7183. ! --- external -----------------------------------
  7184. #ifdef with_hdf4
  7185. integer(hdf4_wpi), external :: sfWData
  7186. #endif
  7187. ! --- local --------------------------------------
  7188. type(MDF_File), pointer :: filep
  7189. type(MDF_Var), pointer :: varp
  7190. integer :: iftype
  7191. integer :: ftype
  7192. #ifdef with_hdf4
  7193. integer :: hdf4_offset(MAX_RANK)
  7194. integer :: hdf4_stride(MAX_RANK)
  7195. integer :: hdf4_count(MAX_RANK)
  7196. #endif
  7197. #ifdef with_hdf5_beta
  7198. !integer(HID_T) :: hdf5_type_id
  7199. integer(HID_T) :: hdf5_file_space_id
  7200. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  7201. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  7202. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  7203. #endif
  7204. integer(1), allocatable :: values_int1(:,:,:,:,:)
  7205. integer(2), allocatable :: values_int2(:,:,:,:,:)
  7206. integer(4), allocatable :: values_int4(:,:,:,:,:)
  7207. integer(8), allocatable :: values_int8(:,:,:,:,:)
  7208. real(4), allocatable :: values_real4(:,:,:,:,:)
  7209. real(8), allocatable :: values_real8(:,:,:,:,:)
  7210. ! --- begin --------------------------------------
  7211. ! pointer to file structure:
  7212. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  7213. IF_NOT_OK_RETURN(status=1)
  7214. ! pointer to variable structure:
  7215. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  7216. IF_NOT_OK_RETURN(status=1)
  7217. ! check ...
  7218. if ( size(shape(values)) > varp%ndim ) then
  7219. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  7220. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  7221. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  7222. TRACEBACK; status=1; return
  7223. end if
  7224. ! check ...
  7225. if ( present(start ) ) then
  7226. if ( size(start ) /= varp%ndim ) then
  7227. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7228. write (gol,'(" size start : ",i6)') size(start ); call goErr
  7229. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7230. TRACEBACK; status=1; return
  7231. end if
  7232. end if
  7233. if ( present(count ) ) then
  7234. if ( size(count ) /= varp%ndim ) then
  7235. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7236. write (gol,'(" size count : ",i6)') size(count ); call goErr
  7237. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7238. TRACEBACK; status=1; return
  7239. end if
  7240. end if
  7241. if ( present(stride ) ) then
  7242. if ( size(stride ) /= varp%ndim ) then
  7243. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7244. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  7245. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7246. TRACEBACK; status=1; return
  7247. end if
  7248. end if
  7249. if ( present(map ) ) then
  7250. if ( size(map ) /= varp%ndim ) then
  7251. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7252. write (gol,'(" size map : ",i6)') size(map ); call goErr
  7253. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7254. TRACEBACK; status=1; return
  7255. end if
  7256. end if
  7257. ! loop over file types:
  7258. do iftype = 1, filep%nftype
  7259. ! current type:
  7260. ftype = filep%ftypes(iftype)
  7261. ! select appropriate routine for each type:
  7262. select case ( ftype )
  7263. #ifdef with_hdf4
  7264. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7265. case ( MDF_HDF4 )
  7266. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7267. ! check ...
  7268. if ( present(map ) ) then
  7269. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  7270. TRACEBACK; status=1; return
  7271. end if
  7272. ! fill offset (zero based!) and stride with default values:
  7273. hdf4_offset = 0
  7274. hdf4_stride = 1
  7275. ! count is by default the shape; padd with singleton dimensions:
  7276. hdf4_count = 1; hdf4_count(1:5) = shape(values)
  7277. ! replace by optional arguments if necessary:
  7278. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  7279. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  7280. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  7281. ! test target type;
  7282. ! convert to required kind before entering sfWData,
  7283. ! otherwise segmentation faults on some machines ...
  7284. select case ( varp%xtype )
  7285. case ( MDF_BYTE )
  7286. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7287. values_int1 = int(values,kind=1)
  7288. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7289. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  7290. deallocate( values_int1 )
  7291. case ( MDF_SHORT )
  7292. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7293. values_int2 = int(values,kind=2)
  7294. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7295. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  7296. deallocate( values_int2 )
  7297. case ( MDF_INT )
  7298. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7299. values_int4 = int(values,kind=4)
  7300. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7301. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  7302. deallocate( values_int4 )
  7303. case ( MDF_FLOAT )
  7304. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7305. values_real4 = real(values,kind=4)
  7306. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7307. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  7308. deallocate( values_real4 )
  7309. case ( MDF_DOUBLE )
  7310. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7311. values_real8 = real(values,kind=8)
  7312. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7313. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  7314. deallocate( values_real8 )
  7315. case default
  7316. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  7317. TRACEBACK; status=1; return
  7318. end select
  7319. if ( status == FAIL ) then
  7320. write (gol,'("writing hdf4 data set:")'); call goErr
  7321. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  7322. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  7323. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  7324. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  7325. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  7326. write (gol,'(" size : ",i12)') size(values); call goErr
  7327. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  7328. TRACEBACK; status=1; return
  7329. end if
  7330. #endif
  7331. #ifdef with_hdf5_beta
  7332. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7333. case ( MDF_HDF5 )
  7334. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7335. ! check ...
  7336. if ( present(map ) ) then
  7337. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  7338. TRACEBACK; status=1; return
  7339. end if
  7340. ! fill offset (zero based!), stride, and count :
  7341. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  7342. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  7343. hdf5_count = 1 ! default singleton dimension
  7344. if ( present(count) ) then
  7345. hdf5_count(1:varp%ndim) = count
  7346. else
  7347. hdf5_count(1:5) = shape(values)
  7348. end if
  7349. ! new dimension:
  7350. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  7351. ! target data space in file:
  7352. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  7353. IF_NOT_OK_RETURN(status=1)
  7354. ! chunked dataset ?
  7355. if ( varp%hdf5_chunked ) then
  7356. ! reset extend:
  7357. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  7358. IF_NOT_OK_RETURN(status=1)
  7359. end if
  7360. ! select hyperslab:
  7361. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  7362. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  7363. stride=hdf5_stride(1:varp%ndim) )
  7364. ! write data:
  7365. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  7366. int(shape(values),kind=HSIZE_T), status, &
  7367. file_space_id=hdf5_file_space_id )
  7368. IF_NOT_OK_RETURN(status=1)
  7369. ! release data space:
  7370. call H5SClose_f( hdf5_file_space_id, status )
  7371. IF_NOT_OK_RETURN(status=1)
  7372. #endif
  7373. #ifdef with_netcdf
  7374. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7375. case ( MDF_NETCDF, MDF_NETCDF4 )
  7376. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7377. ! test target type:
  7378. ! convert to required kind before entering NF90_Put_Var,
  7379. ! otherwise segmentation faults on some machines ...
  7380. select case ( varp%xtype )
  7381. case ( MDF_BYTE )
  7382. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7383. values_int1 = int(values,kind=1)
  7384. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  7385. start, count, stride, map )
  7386. IF_NF90_NOT_OK_RETURN(status=1)
  7387. deallocate( values_int1 )
  7388. case ( MDF_SHORT )
  7389. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7390. values_int2 = int(values,kind=2)
  7391. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  7392. start, count, stride, map )
  7393. IF_NF90_NOT_OK_RETURN(status=1)
  7394. deallocate( values_int2 )
  7395. case ( MDF_INT )
  7396. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7397. values_int4 = int(values,kind=4)
  7398. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  7399. start, count, stride, map )
  7400. IF_NF90_NOT_OK_RETURN(status=1)
  7401. deallocate( values_int4 )
  7402. case ( MDF_FLOAT )
  7403. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7404. values_real4 = real(values,kind=4)
  7405. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  7406. start, count, stride, map )
  7407. IF_NF90_NOT_OK_RETURN(status=1)
  7408. deallocate( values_real4 )
  7409. case ( MDF_DOUBLE )
  7410. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7411. values_real8 = real(values,kind=8)
  7412. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  7413. start, count, stride, map )
  7414. IF_NF90_NOT_OK_RETURN(status=1)
  7415. deallocate( values_real8 )
  7416. case default
  7417. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  7418. TRACEBACK; status=1; return
  7419. end select
  7420. ! just put; let netcdf library convert the right kind:
  7421. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  7422. ! start, count, stride, map )
  7423. !IF_NF90_NOT_OK_RETURN(status=1)
  7424. #endif
  7425. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7426. case default
  7427. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7428. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  7429. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  7430. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  7431. TRACEBACK; status=1; return
  7432. end select
  7433. end do ! file types
  7434. ! ok
  7435. status = 0
  7436. end subroutine MDF_Put_Var_i1_5d
  7437. ! ***
  7438. subroutine MDF_Get_Var_i1_5d( hid, varid, values, status, &
  7439. start, count, stride, map )
  7440. #ifdef with_netcdf
  7441. use NetCDF, only : NF90_Get_Var
  7442. #endif
  7443. ! --- in/out -------------------------------------
  7444. integer, intent(in) :: hid
  7445. integer, intent(in) :: varid
  7446. integer(1), intent(out) :: values(:,:,:,:,:)
  7447. integer, intent(out) :: status
  7448. integer, intent(in), optional :: start (:)
  7449. integer, intent(in), optional :: count (:)
  7450. integer, intent(in), optional :: stride(:)
  7451. integer, intent(in), optional :: map (:)
  7452. ! --- const --------------------------------------
  7453. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_5d'
  7454. ! --- external -----------------------------------
  7455. #ifdef with_hdf4
  7456. integer(hdf4_wpi), external :: sfRData
  7457. #endif
  7458. ! --- local --------------------------------------
  7459. type(MDF_File), pointer :: filep
  7460. type(MDF_Var), pointer :: varp
  7461. integer :: iftype
  7462. integer :: ftype
  7463. #ifdef with_hdf4
  7464. integer :: hdf4_offset(MAX_RANK)
  7465. integer :: hdf4_stride(MAX_RANK)
  7466. integer :: hdf4_count(MAX_RANK)
  7467. integer(1), allocatable :: values_int1(:,:,:,:,:)
  7468. integer(2), allocatable :: values_int2(:,:,:,:,:)
  7469. integer(4), allocatable :: values_int4(:,:,:,:,:)
  7470. integer(8), allocatable :: values_int8(:,:,:,:,:)
  7471. real(4), allocatable :: values_real4(:,:,:,:,:)
  7472. real(8), allocatable :: values_real8(:,:,:,:,:)
  7473. #endif
  7474. ! --- begin --------------------------------------
  7475. ! pointer to file structure:
  7476. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  7477. IF_NOT_OK_RETURN(status=1)
  7478. ! pointer to variable structure:
  7479. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  7480. IF_NOT_OK_RETURN(status=1)
  7481. ! check ...
  7482. if ( size(shape(values)) > varp%ndim ) then
  7483. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  7484. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  7485. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  7486. TRACEBACK; status=1; return
  7487. end if
  7488. ! check ...
  7489. if ( present(start ) ) then
  7490. if ( size(start ) /= varp%ndim ) then
  7491. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7492. write (gol,'(" size start : ",i6)') size(start ); call goErr
  7493. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7494. TRACEBACK; status=1; return
  7495. end if
  7496. end if
  7497. if ( present(count ) ) then
  7498. if ( size(count ) /= varp%ndim ) then
  7499. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7500. write (gol,'(" size count : ",i6)') size(count ); call goErr
  7501. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7502. TRACEBACK; status=1; return
  7503. end if
  7504. end if
  7505. if ( present(stride ) ) then
  7506. if ( size(stride ) /= varp%ndim ) then
  7507. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7508. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  7509. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7510. TRACEBACK; status=1; return
  7511. end if
  7512. end if
  7513. if ( present(map ) ) then
  7514. if ( size(map ) /= varp%ndim ) then
  7515. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7516. write (gol,'(" size map : ",i6)') size(map ); call goErr
  7517. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7518. TRACEBACK; status=1; return
  7519. end if
  7520. end if
  7521. ! loop over file types:
  7522. do iftype = 1, filep%nftype
  7523. ! current type:
  7524. ftype = filep%ftypes(iftype)
  7525. ! select appropriate routine for each type:
  7526. select case ( ftype )
  7527. #ifdef with_hdf4
  7528. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7529. case ( MDF_HDF4 )
  7530. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7531. ! check ...
  7532. if ( present(map ) ) then
  7533. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  7534. TRACEBACK; status=1; return
  7535. end if
  7536. ! fill offset (zero based!), stride, and count :
  7537. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  7538. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  7539. hdf4_count = 1 ! default singleton dimension
  7540. hdf4_count(1:5) = shape(values)
  7541. ! test source type:
  7542. select case ( varp%hdf4_xtype )
  7543. case ( DFNT_INT8 )
  7544. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7545. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  7546. values = int(values_int1,kind=1)
  7547. deallocate( values_int1 )
  7548. case ( DFNT_INT16 )
  7549. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7550. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  7551. values = int(values_int2,kind=1)
  7552. deallocate( values_int2 )
  7553. case ( DFNT_INT32 )
  7554. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7555. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  7556. values = int(values_int4,kind=1)
  7557. deallocate( values_int4 )
  7558. case ( DFNT_INT64 )
  7559. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7560. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  7561. values = int(values_int8,kind=1)
  7562. deallocate( values_int8 )
  7563. case ( DFNT_FLOAT32 )
  7564. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7565. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  7566. values = int(values_real4,kind=1)
  7567. deallocate( values_real4 )
  7568. case ( DFNT_FLOAT64 )
  7569. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  7570. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  7571. values = int(values_real8,kind=1)
  7572. deallocate( values_real8 )
  7573. case default
  7574. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  7575. TRACEBACK; status=1; return
  7576. end select
  7577. if ( status == FAIL ) then
  7578. write (gol,'("reading hdf4 data set:")'); call goErr
  7579. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  7580. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  7581. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  7582. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  7583. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  7584. write (gol,'(" size : ",i6)') size(values); call goErr
  7585. TRACEBACK; status=1; return
  7586. end if
  7587. #endif
  7588. #ifdef with_netcdf
  7589. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7590. case ( MDF_NETCDF, MDF_NETCDF4 )
  7591. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7592. ! read values, converted automatically:
  7593. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  7594. start, count, stride, map )
  7595. IF_NF90_NOT_OK_RETURN(status=1)
  7596. #endif
  7597. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7598. case default
  7599. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7600. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  7601. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  7602. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  7603. TRACEBACK; status=1; return
  7604. end select
  7605. end do ! file types
  7606. ! ok
  7607. status = 0
  7608. end subroutine MDF_Get_Var_i1_5d
  7609. ! ***
  7610. subroutine MDF_Put_Var_i1_6d( hid, varid, values, status, &
  7611. start, count, stride, map )
  7612. #ifdef with_hdf5_beta
  7613. use HDF5, only : HID_T, HSIZE_T
  7614. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  7615. use HDF5, only : H5T_NATIVE_CHARACTER
  7616. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  7617. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  7618. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  7619. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  7620. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  7621. #endif
  7622. #ifdef with_netcdf
  7623. use NetCDF, only : NF90_Put_Var
  7624. #endif
  7625. ! --- in/out -------------------------------------
  7626. integer, intent(in) :: hid
  7627. integer, intent(in) :: varid
  7628. integer(1), intent(in) :: values(:,:,:,:,:,:)
  7629. integer, intent(out) :: status
  7630. integer, intent(in), optional :: start (:)
  7631. integer, intent(in), optional :: count (:)
  7632. integer, intent(in), optional :: stride(:)
  7633. integer, intent(in), optional :: map (:)
  7634. ! --- const --------------------------------------
  7635. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_6d'
  7636. ! --- external -----------------------------------
  7637. #ifdef with_hdf4
  7638. integer(hdf4_wpi), external :: sfWData
  7639. #endif
  7640. ! --- local --------------------------------------
  7641. type(MDF_File), pointer :: filep
  7642. type(MDF_Var), pointer :: varp
  7643. integer :: iftype
  7644. integer :: ftype
  7645. #ifdef with_hdf4
  7646. integer :: hdf4_offset(MAX_RANK)
  7647. integer :: hdf4_stride(MAX_RANK)
  7648. integer :: hdf4_count(MAX_RANK)
  7649. #endif
  7650. #ifdef with_hdf5_beta
  7651. !integer(HID_T) :: hdf5_type_id
  7652. integer(HID_T) :: hdf5_file_space_id
  7653. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  7654. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  7655. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  7656. #endif
  7657. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  7658. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  7659. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  7660. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  7661. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  7662. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  7663. ! --- begin --------------------------------------
  7664. ! pointer to file structure:
  7665. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  7666. IF_NOT_OK_RETURN(status=1)
  7667. ! pointer to variable structure:
  7668. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  7669. IF_NOT_OK_RETURN(status=1)
  7670. ! check ...
  7671. if ( size(shape(values)) > varp%ndim ) then
  7672. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  7673. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  7674. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  7675. TRACEBACK; status=1; return
  7676. end if
  7677. ! check ...
  7678. if ( present(start ) ) then
  7679. if ( size(start ) /= varp%ndim ) then
  7680. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7681. write (gol,'(" size start : ",i6)') size(start ); call goErr
  7682. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7683. TRACEBACK; status=1; return
  7684. end if
  7685. end if
  7686. if ( present(count ) ) then
  7687. if ( size(count ) /= varp%ndim ) then
  7688. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7689. write (gol,'(" size count : ",i6)') size(count ); call goErr
  7690. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7691. TRACEBACK; status=1; return
  7692. end if
  7693. end if
  7694. if ( present(stride ) ) then
  7695. if ( size(stride ) /= varp%ndim ) then
  7696. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7697. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  7698. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7699. TRACEBACK; status=1; return
  7700. end if
  7701. end if
  7702. if ( present(map ) ) then
  7703. if ( size(map ) /= varp%ndim ) then
  7704. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7705. write (gol,'(" size map : ",i6)') size(map ); call goErr
  7706. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7707. TRACEBACK; status=1; return
  7708. end if
  7709. end if
  7710. ! loop over file types:
  7711. do iftype = 1, filep%nftype
  7712. ! current type:
  7713. ftype = filep%ftypes(iftype)
  7714. ! select appropriate routine for each type:
  7715. select case ( ftype )
  7716. #ifdef with_hdf4
  7717. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7718. case ( MDF_HDF4 )
  7719. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7720. ! check ...
  7721. if ( present(map ) ) then
  7722. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  7723. TRACEBACK; status=1; return
  7724. end if
  7725. ! fill offset (zero based!) and stride with default values:
  7726. hdf4_offset = 0
  7727. hdf4_stride = 1
  7728. ! count is by default the shape; padd with singleton dimensions:
  7729. hdf4_count = 1; hdf4_count(1:6) = shape(values)
  7730. ! replace by optional arguments if necessary:
  7731. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  7732. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  7733. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  7734. ! test target type;
  7735. ! convert to required kind before entering sfWData,
  7736. ! otherwise segmentation faults on some machines ...
  7737. select case ( varp%xtype )
  7738. case ( MDF_BYTE )
  7739. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7740. values_int1 = int(values,kind=1)
  7741. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7742. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  7743. deallocate( values_int1 )
  7744. case ( MDF_SHORT )
  7745. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7746. values_int2 = int(values,kind=2)
  7747. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7748. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  7749. deallocate( values_int2 )
  7750. case ( MDF_INT )
  7751. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7752. values_int4 = int(values,kind=4)
  7753. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7754. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  7755. deallocate( values_int4 )
  7756. case ( MDF_FLOAT )
  7757. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7758. values_real4 = real(values,kind=4)
  7759. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7760. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  7761. deallocate( values_real4 )
  7762. case ( MDF_DOUBLE )
  7763. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7764. values_real8 = real(values,kind=8)
  7765. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  7766. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  7767. deallocate( values_real8 )
  7768. case default
  7769. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  7770. TRACEBACK; status=1; return
  7771. end select
  7772. if ( status == FAIL ) then
  7773. write (gol,'("writing hdf4 data set:")'); call goErr
  7774. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  7775. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  7776. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  7777. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  7778. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  7779. write (gol,'(" size : ",i12)') size(values); call goErr
  7780. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  7781. TRACEBACK; status=1; return
  7782. end if
  7783. #endif
  7784. #ifdef with_hdf5_beta
  7785. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7786. case ( MDF_HDF5 )
  7787. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7788. ! check ...
  7789. if ( present(map ) ) then
  7790. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  7791. TRACEBACK; status=1; return
  7792. end if
  7793. ! fill offset (zero based!), stride, and count :
  7794. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  7795. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  7796. hdf5_count = 1 ! default singleton dimension
  7797. if ( present(count) ) then
  7798. hdf5_count(1:varp%ndim) = count
  7799. else
  7800. hdf5_count(1:6) = shape(values)
  7801. end if
  7802. ! new dimension:
  7803. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  7804. ! target data space in file:
  7805. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  7806. IF_NOT_OK_RETURN(status=1)
  7807. ! chunked dataset ?
  7808. if ( varp%hdf5_chunked ) then
  7809. ! reset extend:
  7810. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  7811. IF_NOT_OK_RETURN(status=1)
  7812. end if
  7813. ! select hyperslab:
  7814. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  7815. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  7816. stride=hdf5_stride(1:varp%ndim) )
  7817. ! write data:
  7818. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  7819. int(shape(values),kind=HSIZE_T), status, &
  7820. file_space_id=hdf5_file_space_id )
  7821. IF_NOT_OK_RETURN(status=1)
  7822. ! release data space:
  7823. call H5SClose_f( hdf5_file_space_id, status )
  7824. IF_NOT_OK_RETURN(status=1)
  7825. #endif
  7826. #ifdef with_netcdf
  7827. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7828. case ( MDF_NETCDF, MDF_NETCDF4 )
  7829. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7830. ! test target type:
  7831. ! convert to required kind before entering NF90_Put_Var,
  7832. ! otherwise segmentation faults on some machines ...
  7833. select case ( varp%xtype )
  7834. case ( MDF_BYTE )
  7835. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7836. values_int1 = int(values,kind=1)
  7837. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  7838. start, count, stride, map )
  7839. IF_NF90_NOT_OK_RETURN(status=1)
  7840. deallocate( values_int1 )
  7841. case ( MDF_SHORT )
  7842. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7843. values_int2 = int(values,kind=2)
  7844. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  7845. start, count, stride, map )
  7846. IF_NF90_NOT_OK_RETURN(status=1)
  7847. deallocate( values_int2 )
  7848. case ( MDF_INT )
  7849. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7850. values_int4 = int(values,kind=4)
  7851. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  7852. start, count, stride, map )
  7853. IF_NF90_NOT_OK_RETURN(status=1)
  7854. deallocate( values_int4 )
  7855. case ( MDF_FLOAT )
  7856. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7857. values_real4 = real(values,kind=4)
  7858. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  7859. start, count, stride, map )
  7860. IF_NF90_NOT_OK_RETURN(status=1)
  7861. deallocate( values_real4 )
  7862. case ( MDF_DOUBLE )
  7863. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7864. values_real8 = real(values,kind=8)
  7865. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  7866. start, count, stride, map )
  7867. IF_NF90_NOT_OK_RETURN(status=1)
  7868. deallocate( values_real8 )
  7869. case default
  7870. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  7871. TRACEBACK; status=1; return
  7872. end select
  7873. ! just put; let netcdf library convert the right kind:
  7874. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  7875. ! start, count, stride, map )
  7876. !IF_NF90_NOT_OK_RETURN(status=1)
  7877. #endif
  7878. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7879. case default
  7880. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7881. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  7882. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  7883. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  7884. TRACEBACK; status=1; return
  7885. end select
  7886. end do ! file types
  7887. ! ok
  7888. status = 0
  7889. end subroutine MDF_Put_Var_i1_6d
  7890. ! ***
  7891. subroutine MDF_Get_Var_i1_6d( hid, varid, values, status, &
  7892. start, count, stride, map )
  7893. #ifdef with_netcdf
  7894. use NetCDF, only : NF90_Get_Var
  7895. #endif
  7896. ! --- in/out -------------------------------------
  7897. integer, intent(in) :: hid
  7898. integer, intent(in) :: varid
  7899. integer(1), intent(out) :: values(:,:,:,:,:,:)
  7900. integer, intent(out) :: status
  7901. integer, intent(in), optional :: start (:)
  7902. integer, intent(in), optional :: count (:)
  7903. integer, intent(in), optional :: stride(:)
  7904. integer, intent(in), optional :: map (:)
  7905. ! --- const --------------------------------------
  7906. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_6d'
  7907. ! --- external -----------------------------------
  7908. #ifdef with_hdf4
  7909. integer(hdf4_wpi), external :: sfRData
  7910. #endif
  7911. ! --- local --------------------------------------
  7912. type(MDF_File), pointer :: filep
  7913. type(MDF_Var), pointer :: varp
  7914. integer :: iftype
  7915. integer :: ftype
  7916. #ifdef with_hdf4
  7917. integer :: hdf4_offset(MAX_RANK)
  7918. integer :: hdf4_stride(MAX_RANK)
  7919. integer :: hdf4_count(MAX_RANK)
  7920. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  7921. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  7922. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  7923. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  7924. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  7925. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  7926. #endif
  7927. ! --- begin --------------------------------------
  7928. ! pointer to file structure:
  7929. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  7930. IF_NOT_OK_RETURN(status=1)
  7931. ! pointer to variable structure:
  7932. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  7933. IF_NOT_OK_RETURN(status=1)
  7934. ! check ...
  7935. if ( size(shape(values)) > varp%ndim ) then
  7936. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  7937. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  7938. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  7939. TRACEBACK; status=1; return
  7940. end if
  7941. ! check ...
  7942. if ( present(start ) ) then
  7943. if ( size(start ) /= varp%ndim ) then
  7944. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7945. write (gol,'(" size start : ",i6)') size(start ); call goErr
  7946. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7947. TRACEBACK; status=1; return
  7948. end if
  7949. end if
  7950. if ( present(count ) ) then
  7951. if ( size(count ) /= varp%ndim ) then
  7952. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7953. write (gol,'(" size count : ",i6)') size(count ); call goErr
  7954. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7955. TRACEBACK; status=1; return
  7956. end if
  7957. end if
  7958. if ( present(stride ) ) then
  7959. if ( size(stride ) /= varp%ndim ) then
  7960. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7961. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  7962. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7963. TRACEBACK; status=1; return
  7964. end if
  7965. end if
  7966. if ( present(map ) ) then
  7967. if ( size(map ) /= varp%ndim ) then
  7968. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  7969. write (gol,'(" size map : ",i6)') size(map ); call goErr
  7970. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  7971. TRACEBACK; status=1; return
  7972. end if
  7973. end if
  7974. ! loop over file types:
  7975. do iftype = 1, filep%nftype
  7976. ! current type:
  7977. ftype = filep%ftypes(iftype)
  7978. ! select appropriate routine for each type:
  7979. select case ( ftype )
  7980. #ifdef with_hdf4
  7981. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7982. case ( MDF_HDF4 )
  7983. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  7984. ! check ...
  7985. if ( present(map ) ) then
  7986. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  7987. TRACEBACK; status=1; return
  7988. end if
  7989. ! fill offset (zero based!), stride, and count :
  7990. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  7991. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  7992. hdf4_count = 1 ! default singleton dimension
  7993. hdf4_count(1:6) = shape(values)
  7994. ! test source type:
  7995. select case ( varp%hdf4_xtype )
  7996. case ( DFNT_INT8 )
  7997. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  7998. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  7999. values = int(values_int1,kind=1)
  8000. deallocate( values_int1 )
  8001. case ( DFNT_INT16 )
  8002. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  8003. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  8004. values = int(values_int2,kind=1)
  8005. deallocate( values_int2 )
  8006. case ( DFNT_INT32 )
  8007. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  8008. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  8009. values = int(values_int4,kind=1)
  8010. deallocate( values_int4 )
  8011. case ( DFNT_INT64 )
  8012. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  8013. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  8014. values = int(values_int8,kind=1)
  8015. deallocate( values_int8 )
  8016. case ( DFNT_FLOAT32 )
  8017. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  8018. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  8019. values = int(values_real4,kind=1)
  8020. deallocate( values_real4 )
  8021. case ( DFNT_FLOAT64 )
  8022. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  8023. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  8024. values = int(values_real8,kind=1)
  8025. deallocate( values_real8 )
  8026. case default
  8027. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  8028. TRACEBACK; status=1; return
  8029. end select
  8030. if ( status == FAIL ) then
  8031. write (gol,'("reading hdf4 data set:")'); call goErr
  8032. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  8033. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  8034. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  8035. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  8036. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  8037. write (gol,'(" size : ",i6)') size(values); call goErr
  8038. TRACEBACK; status=1; return
  8039. end if
  8040. #endif
  8041. #ifdef with_netcdf
  8042. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8043. case ( MDF_NETCDF, MDF_NETCDF4 )
  8044. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8045. ! read values, converted automatically:
  8046. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  8047. start, count, stride, map )
  8048. IF_NF90_NOT_OK_RETURN(status=1)
  8049. #endif
  8050. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8051. case default
  8052. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8053. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  8054. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  8055. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  8056. TRACEBACK; status=1; return
  8057. end select
  8058. end do ! file types
  8059. ! ok
  8060. status = 0
  8061. end subroutine MDF_Get_Var_i1_6d
  8062. ! ***
  8063. subroutine MDF_Put_Var_i1_7d( hid, varid, values, status, &
  8064. start, count, stride, map )
  8065. #ifdef with_hdf5_beta
  8066. use HDF5, only : HID_T, HSIZE_T
  8067. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  8068. use HDF5, only : H5T_NATIVE_CHARACTER
  8069. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  8070. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  8071. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  8072. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  8073. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  8074. #endif
  8075. #ifdef with_netcdf
  8076. use NetCDF, only : NF90_Put_Var
  8077. #endif
  8078. ! --- in/out -------------------------------------
  8079. integer, intent(in) :: hid
  8080. integer, intent(in) :: varid
  8081. integer(1), intent(in) :: values(:,:,:,:,:,:,:)
  8082. integer, intent(out) :: status
  8083. integer, intent(in), optional :: start (:)
  8084. integer, intent(in), optional :: count (:)
  8085. integer, intent(in), optional :: stride(:)
  8086. integer, intent(in), optional :: map (:)
  8087. ! --- const --------------------------------------
  8088. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i1_7d'
  8089. ! --- external -----------------------------------
  8090. #ifdef with_hdf4
  8091. integer(hdf4_wpi), external :: sfWData
  8092. #endif
  8093. ! --- local --------------------------------------
  8094. type(MDF_File), pointer :: filep
  8095. type(MDF_Var), pointer :: varp
  8096. integer :: iftype
  8097. integer :: ftype
  8098. #ifdef with_hdf4
  8099. integer :: hdf4_offset(MAX_RANK)
  8100. integer :: hdf4_stride(MAX_RANK)
  8101. integer :: hdf4_count(MAX_RANK)
  8102. #endif
  8103. #ifdef with_hdf5_beta
  8104. !integer(HID_T) :: hdf5_type_id
  8105. integer(HID_T) :: hdf5_file_space_id
  8106. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  8107. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  8108. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  8109. #endif
  8110. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  8111. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  8112. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  8113. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  8114. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  8115. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  8116. ! --- begin --------------------------------------
  8117. ! pointer to file structure:
  8118. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  8119. IF_NOT_OK_RETURN(status=1)
  8120. ! pointer to variable structure:
  8121. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  8122. IF_NOT_OK_RETURN(status=1)
  8123. ! check ...
  8124. if ( size(shape(values)) > varp%ndim ) then
  8125. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  8126. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  8127. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  8128. TRACEBACK; status=1; return
  8129. end if
  8130. ! check ...
  8131. if ( present(start ) ) then
  8132. if ( size(start ) /= varp%ndim ) then
  8133. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8134. write (gol,'(" size start : ",i6)') size(start ); call goErr
  8135. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8136. TRACEBACK; status=1; return
  8137. end if
  8138. end if
  8139. if ( present(count ) ) then
  8140. if ( size(count ) /= varp%ndim ) then
  8141. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8142. write (gol,'(" size count : ",i6)') size(count ); call goErr
  8143. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8144. TRACEBACK; status=1; return
  8145. end if
  8146. end if
  8147. if ( present(stride ) ) then
  8148. if ( size(stride ) /= varp%ndim ) then
  8149. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8150. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  8151. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8152. TRACEBACK; status=1; return
  8153. end if
  8154. end if
  8155. if ( present(map ) ) then
  8156. if ( size(map ) /= varp%ndim ) then
  8157. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8158. write (gol,'(" size map : ",i6)') size(map ); call goErr
  8159. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8160. TRACEBACK; status=1; return
  8161. end if
  8162. end if
  8163. ! loop over file types:
  8164. do iftype = 1, filep%nftype
  8165. ! current type:
  8166. ftype = filep%ftypes(iftype)
  8167. ! select appropriate routine for each type:
  8168. select case ( ftype )
  8169. #ifdef with_hdf4
  8170. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8171. case ( MDF_HDF4 )
  8172. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8173. ! check ...
  8174. if ( present(map ) ) then
  8175. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  8176. TRACEBACK; status=1; return
  8177. end if
  8178. ! fill offset (zero based!) and stride with default values:
  8179. hdf4_offset = 0
  8180. hdf4_stride = 1
  8181. ! count is by default the shape; padd with singleton dimensions:
  8182. hdf4_count = 1; hdf4_count(1:7) = shape(values)
  8183. ! replace by optional arguments if necessary:
  8184. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  8185. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  8186. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  8187. ! test target type;
  8188. ! convert to required kind before entering sfWData,
  8189. ! otherwise segmentation faults on some machines ...
  8190. select case ( varp%xtype )
  8191. case ( MDF_BYTE )
  8192. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8193. values_int1 = int(values,kind=1)
  8194. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8195. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  8196. deallocate( values_int1 )
  8197. case ( MDF_SHORT )
  8198. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8199. values_int2 = int(values,kind=2)
  8200. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8201. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  8202. deallocate( values_int2 )
  8203. case ( MDF_INT )
  8204. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8205. values_int4 = int(values,kind=4)
  8206. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8207. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  8208. deallocate( values_int4 )
  8209. case ( MDF_FLOAT )
  8210. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8211. values_real4 = real(values,kind=4)
  8212. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8213. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  8214. deallocate( values_real4 )
  8215. case ( MDF_DOUBLE )
  8216. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8217. values_real8 = real(values,kind=8)
  8218. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8219. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  8220. deallocate( values_real8 )
  8221. case default
  8222. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  8223. TRACEBACK; status=1; return
  8224. end select
  8225. if ( status == FAIL ) then
  8226. write (gol,'("writing hdf4 data set:")'); call goErr
  8227. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  8228. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  8229. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  8230. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  8231. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  8232. write (gol,'(" size : ",i12)') size(values); call goErr
  8233. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  8234. TRACEBACK; status=1; return
  8235. end if
  8236. #endif
  8237. #ifdef with_hdf5_beta
  8238. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8239. case ( MDF_HDF5 )
  8240. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8241. ! check ...
  8242. if ( present(map ) ) then
  8243. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  8244. TRACEBACK; status=1; return
  8245. end if
  8246. ! fill offset (zero based!), stride, and count :
  8247. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  8248. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  8249. hdf5_count = 1 ! default singleton dimension
  8250. if ( present(count) ) then
  8251. hdf5_count(1:varp%ndim) = count
  8252. else
  8253. hdf5_count(1:7) = shape(values)
  8254. end if
  8255. ! new dimension:
  8256. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  8257. ! target data space in file:
  8258. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  8259. IF_NOT_OK_RETURN(status=1)
  8260. ! chunked dataset ?
  8261. if ( varp%hdf5_chunked ) then
  8262. ! reset extend:
  8263. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  8264. IF_NOT_OK_RETURN(status=1)
  8265. end if
  8266. ! select hyperslab:
  8267. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  8268. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  8269. stride=hdf5_stride(1:varp%ndim) )
  8270. ! write data:
  8271. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  8272. int(shape(values),kind=HSIZE_T), status, &
  8273. file_space_id=hdf5_file_space_id )
  8274. IF_NOT_OK_RETURN(status=1)
  8275. ! release data space:
  8276. call H5SClose_f( hdf5_file_space_id, status )
  8277. IF_NOT_OK_RETURN(status=1)
  8278. #endif
  8279. #ifdef with_netcdf
  8280. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8281. case ( MDF_NETCDF, MDF_NETCDF4 )
  8282. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8283. ! test target type:
  8284. ! convert to required kind before entering NF90_Put_Var,
  8285. ! otherwise segmentation faults on some machines ...
  8286. select case ( varp%xtype )
  8287. case ( MDF_BYTE )
  8288. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8289. values_int1 = int(values,kind=1)
  8290. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  8291. start, count, stride, map )
  8292. IF_NF90_NOT_OK_RETURN(status=1)
  8293. deallocate( values_int1 )
  8294. case ( MDF_SHORT )
  8295. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8296. values_int2 = int(values,kind=2)
  8297. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  8298. start, count, stride, map )
  8299. IF_NF90_NOT_OK_RETURN(status=1)
  8300. deallocate( values_int2 )
  8301. case ( MDF_INT )
  8302. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8303. values_int4 = int(values,kind=4)
  8304. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  8305. start, count, stride, map )
  8306. IF_NF90_NOT_OK_RETURN(status=1)
  8307. deallocate( values_int4 )
  8308. case ( MDF_FLOAT )
  8309. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8310. values_real4 = real(values,kind=4)
  8311. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  8312. start, count, stride, map )
  8313. IF_NF90_NOT_OK_RETURN(status=1)
  8314. deallocate( values_real4 )
  8315. case ( MDF_DOUBLE )
  8316. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8317. values_real8 = real(values,kind=8)
  8318. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  8319. start, count, stride, map )
  8320. IF_NF90_NOT_OK_RETURN(status=1)
  8321. deallocate( values_real8 )
  8322. case default
  8323. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  8324. TRACEBACK; status=1; return
  8325. end select
  8326. ! just put; let netcdf library convert the right kind:
  8327. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  8328. ! start, count, stride, map )
  8329. !IF_NF90_NOT_OK_RETURN(status=1)
  8330. #endif
  8331. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8332. case default
  8333. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8334. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  8335. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  8336. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  8337. TRACEBACK; status=1; return
  8338. end select
  8339. end do ! file types
  8340. ! ok
  8341. status = 0
  8342. end subroutine MDF_Put_Var_i1_7d
  8343. ! ***
  8344. subroutine MDF_Get_Var_i1_7d( hid, varid, values, status, &
  8345. start, count, stride, map )
  8346. #ifdef with_netcdf
  8347. use NetCDF, only : NF90_Get_Var
  8348. #endif
  8349. ! --- in/out -------------------------------------
  8350. integer, intent(in) :: hid
  8351. integer, intent(in) :: varid
  8352. integer(1), intent(out) :: values(:,:,:,:,:,:,:)
  8353. integer, intent(out) :: status
  8354. integer, intent(in), optional :: start (:)
  8355. integer, intent(in), optional :: count (:)
  8356. integer, intent(in), optional :: stride(:)
  8357. integer, intent(in), optional :: map (:)
  8358. ! --- const --------------------------------------
  8359. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i1_7d'
  8360. ! --- external -----------------------------------
  8361. #ifdef with_hdf4
  8362. integer(hdf4_wpi), external :: sfRData
  8363. #endif
  8364. ! --- local --------------------------------------
  8365. type(MDF_File), pointer :: filep
  8366. type(MDF_Var), pointer :: varp
  8367. integer :: iftype
  8368. integer :: ftype
  8369. #ifdef with_hdf4
  8370. integer :: hdf4_offset(MAX_RANK)
  8371. integer :: hdf4_stride(MAX_RANK)
  8372. integer :: hdf4_count(MAX_RANK)
  8373. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  8374. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  8375. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  8376. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  8377. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  8378. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  8379. #endif
  8380. ! --- begin --------------------------------------
  8381. ! pointer to file structure:
  8382. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  8383. IF_NOT_OK_RETURN(status=1)
  8384. ! pointer to variable structure:
  8385. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  8386. IF_NOT_OK_RETURN(status=1)
  8387. ! check ...
  8388. if ( size(shape(values)) > varp%ndim ) then
  8389. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  8390. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  8391. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  8392. TRACEBACK; status=1; return
  8393. end if
  8394. ! check ...
  8395. if ( present(start ) ) then
  8396. if ( size(start ) /= varp%ndim ) then
  8397. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8398. write (gol,'(" size start : ",i6)') size(start ); call goErr
  8399. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8400. TRACEBACK; status=1; return
  8401. end if
  8402. end if
  8403. if ( present(count ) ) then
  8404. if ( size(count ) /= varp%ndim ) then
  8405. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8406. write (gol,'(" size count : ",i6)') size(count ); call goErr
  8407. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8408. TRACEBACK; status=1; return
  8409. end if
  8410. end if
  8411. if ( present(stride ) ) then
  8412. if ( size(stride ) /= varp%ndim ) then
  8413. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8414. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  8415. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8416. TRACEBACK; status=1; return
  8417. end if
  8418. end if
  8419. if ( present(map ) ) then
  8420. if ( size(map ) /= varp%ndim ) then
  8421. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8422. write (gol,'(" size map : ",i6)') size(map ); call goErr
  8423. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8424. TRACEBACK; status=1; return
  8425. end if
  8426. end if
  8427. ! loop over file types:
  8428. do iftype = 1, filep%nftype
  8429. ! current type:
  8430. ftype = filep%ftypes(iftype)
  8431. ! select appropriate routine for each type:
  8432. select case ( ftype )
  8433. #ifdef with_hdf4
  8434. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8435. case ( MDF_HDF4 )
  8436. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8437. ! check ...
  8438. if ( present(map ) ) then
  8439. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  8440. TRACEBACK; status=1; return
  8441. end if
  8442. ! fill offset (zero based!), stride, and count :
  8443. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  8444. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  8445. hdf4_count = 1 ! default singleton dimension
  8446. hdf4_count(1:7) = shape(values)
  8447. ! test source type:
  8448. select case ( varp%hdf4_xtype )
  8449. case ( DFNT_INT8 )
  8450. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8451. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  8452. values = int(values_int1,kind=1)
  8453. deallocate( values_int1 )
  8454. case ( DFNT_INT16 )
  8455. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8456. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  8457. values = int(values_int2,kind=1)
  8458. deallocate( values_int2 )
  8459. case ( DFNT_INT32 )
  8460. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8461. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  8462. values = int(values_int4,kind=1)
  8463. deallocate( values_int4 )
  8464. case ( DFNT_INT64 )
  8465. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8466. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  8467. values = int(values_int8,kind=1)
  8468. deallocate( values_int8 )
  8469. case ( DFNT_FLOAT32 )
  8470. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8471. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  8472. values = int(values_real4,kind=1)
  8473. deallocate( values_real4 )
  8474. case ( DFNT_FLOAT64 )
  8475. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  8476. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  8477. values = int(values_real8,kind=1)
  8478. deallocate( values_real8 )
  8479. case default
  8480. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  8481. TRACEBACK; status=1; return
  8482. end select
  8483. if ( status == FAIL ) then
  8484. write (gol,'("reading hdf4 data set:")'); call goErr
  8485. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  8486. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  8487. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  8488. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  8489. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  8490. write (gol,'(" size : ",i6)') size(values); call goErr
  8491. TRACEBACK; status=1; return
  8492. end if
  8493. #endif
  8494. #ifdef with_netcdf
  8495. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8496. case ( MDF_NETCDF, MDF_NETCDF4 )
  8497. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8498. ! read values, converted automatically:
  8499. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  8500. start, count, stride, map )
  8501. IF_NF90_NOT_OK_RETURN(status=1)
  8502. #endif
  8503. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8504. case default
  8505. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8506. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  8507. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  8508. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  8509. TRACEBACK; status=1; return
  8510. end select
  8511. end do ! file types
  8512. ! ok
  8513. status = 0
  8514. end subroutine MDF_Get_Var_i1_7d
  8515. ! ***
  8516. subroutine MDF_Put_Var_i2_1d( hid, varid, values, status, &
  8517. start, count, stride, map )
  8518. #ifdef with_hdf5_beta
  8519. use HDF5, only : HID_T, HSIZE_T
  8520. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  8521. use HDF5, only : H5T_NATIVE_CHARACTER
  8522. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  8523. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  8524. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  8525. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  8526. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  8527. #endif
  8528. #ifdef with_netcdf
  8529. use NetCDF, only : NF90_Put_Var
  8530. #endif
  8531. ! --- in/out -------------------------------------
  8532. integer, intent(in) :: hid
  8533. integer, intent(in) :: varid
  8534. integer(2), intent(in) :: values(:)
  8535. integer, intent(out) :: status
  8536. integer, intent(in), optional :: start (:)
  8537. integer, intent(in), optional :: count (:)
  8538. integer, intent(in), optional :: stride(:)
  8539. integer, intent(in), optional :: map (:)
  8540. ! --- const --------------------------------------
  8541. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_1d'
  8542. ! --- external -----------------------------------
  8543. #ifdef with_hdf4
  8544. integer(hdf4_wpi), external :: sfWData
  8545. #endif
  8546. ! --- local --------------------------------------
  8547. type(MDF_File), pointer :: filep
  8548. type(MDF_Var), pointer :: varp
  8549. integer :: iftype
  8550. integer :: ftype
  8551. #ifdef with_hdf4
  8552. integer :: hdf4_offset(MAX_RANK)
  8553. integer :: hdf4_stride(MAX_RANK)
  8554. integer :: hdf4_count(MAX_RANK)
  8555. #endif
  8556. #ifdef with_hdf5_beta
  8557. !integer(HID_T) :: hdf5_type_id
  8558. integer(HID_T) :: hdf5_file_space_id
  8559. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  8560. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  8561. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  8562. #endif
  8563. integer(1), allocatable :: values_int1(:)
  8564. integer(2), allocatable :: values_int2(:)
  8565. integer(4), allocatable :: values_int4(:)
  8566. integer(8), allocatable :: values_int8(:)
  8567. real(4), allocatable :: values_real4(:)
  8568. real(8), allocatable :: values_real8(:)
  8569. ! --- begin --------------------------------------
  8570. ! pointer to file structure:
  8571. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  8572. IF_NOT_OK_RETURN(status=1)
  8573. ! pointer to variable structure:
  8574. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  8575. IF_NOT_OK_RETURN(status=1)
  8576. ! check ...
  8577. if ( size(shape(values)) > varp%ndim ) then
  8578. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  8579. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  8580. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  8581. TRACEBACK; status=1; return
  8582. end if
  8583. ! check ...
  8584. if ( present(start ) ) then
  8585. if ( size(start ) /= varp%ndim ) then
  8586. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8587. write (gol,'(" size start : ",i6)') size(start ); call goErr
  8588. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8589. TRACEBACK; status=1; return
  8590. end if
  8591. end if
  8592. if ( present(count ) ) then
  8593. if ( size(count ) /= varp%ndim ) then
  8594. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8595. write (gol,'(" size count : ",i6)') size(count ); call goErr
  8596. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8597. TRACEBACK; status=1; return
  8598. end if
  8599. end if
  8600. if ( present(stride ) ) then
  8601. if ( size(stride ) /= varp%ndim ) then
  8602. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8603. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  8604. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8605. TRACEBACK; status=1; return
  8606. end if
  8607. end if
  8608. if ( present(map ) ) then
  8609. if ( size(map ) /= varp%ndim ) then
  8610. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8611. write (gol,'(" size map : ",i6)') size(map ); call goErr
  8612. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8613. TRACEBACK; status=1; return
  8614. end if
  8615. end if
  8616. ! loop over file types:
  8617. do iftype = 1, filep%nftype
  8618. ! current type:
  8619. ftype = filep%ftypes(iftype)
  8620. ! select appropriate routine for each type:
  8621. select case ( ftype )
  8622. #ifdef with_hdf4
  8623. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8624. case ( MDF_HDF4 )
  8625. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8626. ! check ...
  8627. if ( present(map ) ) then
  8628. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  8629. TRACEBACK; status=1; return
  8630. end if
  8631. ! fill offset (zero based!) and stride with default values:
  8632. hdf4_offset = 0
  8633. hdf4_stride = 1
  8634. ! count is by default the shape; padd with singleton dimensions:
  8635. hdf4_count = 1; hdf4_count(1:1) = shape(values)
  8636. ! replace by optional arguments if necessary:
  8637. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  8638. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  8639. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  8640. ! test target type;
  8641. ! convert to required kind before entering sfWData,
  8642. ! otherwise segmentation faults on some machines ...
  8643. select case ( varp%xtype )
  8644. case ( MDF_BYTE )
  8645. allocate( values_int1(size(values,1)) )
  8646. values_int1 = int(values,kind=1)
  8647. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8648. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  8649. deallocate( values_int1 )
  8650. case ( MDF_SHORT )
  8651. allocate( values_int2(size(values,1)) )
  8652. values_int2 = int(values,kind=2)
  8653. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8654. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  8655. deallocate( values_int2 )
  8656. case ( MDF_INT )
  8657. allocate( values_int4(size(values,1)) )
  8658. values_int4 = int(values,kind=4)
  8659. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8660. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  8661. deallocate( values_int4 )
  8662. case ( MDF_FLOAT )
  8663. allocate( values_real4(size(values,1)) )
  8664. values_real4 = real(values,kind=4)
  8665. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8666. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  8667. deallocate( values_real4 )
  8668. case ( MDF_DOUBLE )
  8669. allocate( values_real8(size(values,1)) )
  8670. values_real8 = real(values,kind=8)
  8671. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  8672. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  8673. deallocate( values_real8 )
  8674. case default
  8675. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  8676. TRACEBACK; status=1; return
  8677. end select
  8678. if ( status == FAIL ) then
  8679. write (gol,'("writing hdf4 data set:")'); call goErr
  8680. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  8681. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  8682. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  8683. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  8684. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  8685. write (gol,'(" size : ",i12)') size(values); call goErr
  8686. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  8687. TRACEBACK; status=1; return
  8688. end if
  8689. #endif
  8690. #ifdef with_hdf5_beta
  8691. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8692. case ( MDF_HDF5 )
  8693. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8694. ! check ...
  8695. if ( present(map ) ) then
  8696. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  8697. TRACEBACK; status=1; return
  8698. end if
  8699. ! fill offset (zero based!), stride, and count :
  8700. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  8701. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  8702. hdf5_count = 1 ! default singleton dimension
  8703. if ( present(count) ) then
  8704. hdf5_count(1:varp%ndim) = count
  8705. else
  8706. hdf5_count(1:1) = shape(values)
  8707. end if
  8708. ! new dimension:
  8709. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  8710. ! target data space in file:
  8711. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  8712. IF_NOT_OK_RETURN(status=1)
  8713. ! chunked dataset ?
  8714. if ( varp%hdf5_chunked ) then
  8715. ! reset extend:
  8716. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  8717. IF_NOT_OK_RETURN(status=1)
  8718. end if
  8719. ! select hyperslab:
  8720. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  8721. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  8722. stride=hdf5_stride(1:varp%ndim) )
  8723. ! write data:
  8724. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  8725. int(shape(values),kind=HSIZE_T), status, &
  8726. file_space_id=hdf5_file_space_id )
  8727. IF_NOT_OK_RETURN(status=1)
  8728. ! release data space:
  8729. call H5SClose_f( hdf5_file_space_id, status )
  8730. IF_NOT_OK_RETURN(status=1)
  8731. #endif
  8732. #ifdef with_netcdf
  8733. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8734. case ( MDF_NETCDF, MDF_NETCDF4 )
  8735. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8736. ! test target type:
  8737. ! convert to required kind before entering NF90_Put_Var,
  8738. ! otherwise segmentation faults on some machines ...
  8739. select case ( varp%xtype )
  8740. case ( MDF_BYTE )
  8741. allocate( values_int1(size(values,1)) )
  8742. values_int1 = int(values,kind=1)
  8743. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  8744. start, count, stride, map )
  8745. IF_NF90_NOT_OK_RETURN(status=1)
  8746. deallocate( values_int1 )
  8747. case ( MDF_SHORT )
  8748. allocate( values_int2(size(values,1)) )
  8749. values_int2 = int(values,kind=2)
  8750. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  8751. start, count, stride, map )
  8752. IF_NF90_NOT_OK_RETURN(status=1)
  8753. deallocate( values_int2 )
  8754. case ( MDF_INT )
  8755. allocate( values_int4(size(values,1)) )
  8756. values_int4 = int(values,kind=4)
  8757. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  8758. start, count, stride, map )
  8759. IF_NF90_NOT_OK_RETURN(status=1)
  8760. deallocate( values_int4 )
  8761. case ( MDF_FLOAT )
  8762. allocate( values_real4(size(values,1)) )
  8763. values_real4 = real(values,kind=4)
  8764. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  8765. start, count, stride, map )
  8766. IF_NF90_NOT_OK_RETURN(status=1)
  8767. deallocate( values_real4 )
  8768. case ( MDF_DOUBLE )
  8769. allocate( values_real8(size(values,1)) )
  8770. values_real8 = real(values,kind=8)
  8771. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  8772. start, count, stride, map )
  8773. IF_NF90_NOT_OK_RETURN(status=1)
  8774. deallocate( values_real8 )
  8775. case default
  8776. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  8777. TRACEBACK; status=1; return
  8778. end select
  8779. ! just put; let netcdf library convert the right kind:
  8780. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  8781. ! start, count, stride, map )
  8782. !IF_NF90_NOT_OK_RETURN(status=1)
  8783. #endif
  8784. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8785. case default
  8786. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8787. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  8788. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  8789. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  8790. TRACEBACK; status=1; return
  8791. end select
  8792. end do ! file types
  8793. ! ok
  8794. status = 0
  8795. end subroutine MDF_Put_Var_i2_1d
  8796. ! ***
  8797. subroutine MDF_Get_Var_i2_1d( hid, varid, values, status, &
  8798. start, count, stride, map )
  8799. #ifdef with_netcdf
  8800. use NetCDF, only : NF90_Get_Var
  8801. #endif
  8802. ! --- in/out -------------------------------------
  8803. integer, intent(in) :: hid
  8804. integer, intent(in) :: varid
  8805. integer(2), intent(out) :: values(:)
  8806. integer, intent(out) :: status
  8807. integer, intent(in), optional :: start (:)
  8808. integer, intent(in), optional :: count (:)
  8809. integer, intent(in), optional :: stride(:)
  8810. integer, intent(in), optional :: map (:)
  8811. ! --- const --------------------------------------
  8812. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_1d'
  8813. ! --- external -----------------------------------
  8814. #ifdef with_hdf4
  8815. integer(hdf4_wpi), external :: sfRData
  8816. #endif
  8817. ! --- local --------------------------------------
  8818. type(MDF_File), pointer :: filep
  8819. type(MDF_Var), pointer :: varp
  8820. integer :: iftype
  8821. integer :: ftype
  8822. #ifdef with_hdf4
  8823. integer :: hdf4_offset(MAX_RANK)
  8824. integer :: hdf4_stride(MAX_RANK)
  8825. integer :: hdf4_count(MAX_RANK)
  8826. integer(1), allocatable :: values_int1(:)
  8827. integer(2), allocatable :: values_int2(:)
  8828. integer(4), allocatable :: values_int4(:)
  8829. integer(8), allocatable :: values_int8(:)
  8830. real(4), allocatable :: values_real4(:)
  8831. real(8), allocatable :: values_real8(:)
  8832. #endif
  8833. ! --- begin --------------------------------------
  8834. ! pointer to file structure:
  8835. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  8836. IF_NOT_OK_RETURN(status=1)
  8837. ! pointer to variable structure:
  8838. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  8839. IF_NOT_OK_RETURN(status=1)
  8840. ! check ...
  8841. if ( size(shape(values)) > varp%ndim ) then
  8842. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  8843. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  8844. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  8845. TRACEBACK; status=1; return
  8846. end if
  8847. ! check ...
  8848. if ( present(start ) ) then
  8849. if ( size(start ) /= varp%ndim ) then
  8850. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8851. write (gol,'(" size start : ",i6)') size(start ); call goErr
  8852. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8853. TRACEBACK; status=1; return
  8854. end if
  8855. end if
  8856. if ( present(count ) ) then
  8857. if ( size(count ) /= varp%ndim ) then
  8858. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8859. write (gol,'(" size count : ",i6)') size(count ); call goErr
  8860. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8861. TRACEBACK; status=1; return
  8862. end if
  8863. end if
  8864. if ( present(stride ) ) then
  8865. if ( size(stride ) /= varp%ndim ) then
  8866. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8867. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  8868. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8869. TRACEBACK; status=1; return
  8870. end if
  8871. end if
  8872. if ( present(map ) ) then
  8873. if ( size(map ) /= varp%ndim ) then
  8874. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  8875. write (gol,'(" size map : ",i6)') size(map ); call goErr
  8876. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  8877. TRACEBACK; status=1; return
  8878. end if
  8879. end if
  8880. ! loop over file types:
  8881. do iftype = 1, filep%nftype
  8882. ! current type:
  8883. ftype = filep%ftypes(iftype)
  8884. ! select appropriate routine for each type:
  8885. select case ( ftype )
  8886. #ifdef with_hdf4
  8887. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8888. case ( MDF_HDF4 )
  8889. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8890. ! check ...
  8891. if ( present(map ) ) then
  8892. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  8893. TRACEBACK; status=1; return
  8894. end if
  8895. ! fill offset (zero based!), stride, and count :
  8896. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  8897. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  8898. hdf4_count = 1 ! default singleton dimension
  8899. hdf4_count(1:1) = shape(values)
  8900. ! test source type:
  8901. select case ( varp%hdf4_xtype )
  8902. case ( DFNT_INT8 )
  8903. allocate( values_int1(size(values,1)) )
  8904. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  8905. values = int(values_int1,kind=2)
  8906. deallocate( values_int1 )
  8907. case ( DFNT_INT16 )
  8908. allocate( values_int2(size(values,1)) )
  8909. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  8910. values = int(values_int2,kind=2)
  8911. deallocate( values_int2 )
  8912. case ( DFNT_INT32 )
  8913. allocate( values_int4(size(values,1)) )
  8914. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  8915. values = int(values_int4,kind=2)
  8916. deallocate( values_int4 )
  8917. case ( DFNT_INT64 )
  8918. allocate( values_int8(size(values,1)) )
  8919. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  8920. values = int(values_int8,kind=2)
  8921. deallocate( values_int8 )
  8922. case ( DFNT_FLOAT32 )
  8923. allocate( values_real4(size(values,1)) )
  8924. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  8925. values = int(values_real4,kind=2)
  8926. deallocate( values_real4 )
  8927. case ( DFNT_FLOAT64 )
  8928. allocate( values_real8(size(values,1)) )
  8929. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  8930. values = int(values_real8,kind=2)
  8931. deallocate( values_real8 )
  8932. case default
  8933. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  8934. TRACEBACK; status=1; return
  8935. end select
  8936. if ( status == FAIL ) then
  8937. write (gol,'("reading hdf4 data set:")'); call goErr
  8938. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  8939. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  8940. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  8941. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  8942. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  8943. write (gol,'(" size : ",i6)') size(values); call goErr
  8944. TRACEBACK; status=1; return
  8945. end if
  8946. #endif
  8947. #ifdef with_netcdf
  8948. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8949. case ( MDF_NETCDF, MDF_NETCDF4 )
  8950. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8951. ! read values, converted automatically:
  8952. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  8953. start, count, stride, map )
  8954. IF_NF90_NOT_OK_RETURN(status=1)
  8955. #endif
  8956. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8957. case default
  8958. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  8959. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  8960. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  8961. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  8962. TRACEBACK; status=1; return
  8963. end select
  8964. end do ! file types
  8965. ! ok
  8966. status = 0
  8967. end subroutine MDF_Get_Var_i2_1d
  8968. ! ***
  8969. subroutine MDF_Put_Var_i2_2d( hid, varid, values, status, &
  8970. start, count, stride, map )
  8971. #ifdef with_hdf5_beta
  8972. use HDF5, only : HID_T, HSIZE_T
  8973. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  8974. use HDF5, only : H5T_NATIVE_CHARACTER
  8975. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  8976. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  8977. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  8978. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  8979. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  8980. #endif
  8981. #ifdef with_netcdf
  8982. use NetCDF, only : NF90_Put_Var
  8983. #endif
  8984. ! --- in/out -------------------------------------
  8985. integer, intent(in) :: hid
  8986. integer, intent(in) :: varid
  8987. integer(2), intent(in) :: values(:,:)
  8988. integer, intent(out) :: status
  8989. integer, intent(in), optional :: start (:)
  8990. integer, intent(in), optional :: count (:)
  8991. integer, intent(in), optional :: stride(:)
  8992. integer, intent(in), optional :: map (:)
  8993. ! --- const --------------------------------------
  8994. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_2d'
  8995. ! --- external -----------------------------------
  8996. #ifdef with_hdf4
  8997. integer(hdf4_wpi), external :: sfWData
  8998. #endif
  8999. ! --- local --------------------------------------
  9000. type(MDF_File), pointer :: filep
  9001. type(MDF_Var), pointer :: varp
  9002. integer :: iftype
  9003. integer :: ftype
  9004. #ifdef with_hdf4
  9005. integer :: hdf4_offset(MAX_RANK)
  9006. integer :: hdf4_stride(MAX_RANK)
  9007. integer :: hdf4_count(MAX_RANK)
  9008. #endif
  9009. #ifdef with_hdf5_beta
  9010. !integer(HID_T) :: hdf5_type_id
  9011. integer(HID_T) :: hdf5_file_space_id
  9012. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  9013. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  9014. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  9015. #endif
  9016. integer(1), allocatable :: values_int1(:,:)
  9017. integer(2), allocatable :: values_int2(:,:)
  9018. integer(4), allocatable :: values_int4(:,:)
  9019. integer(8), allocatable :: values_int8(:,:)
  9020. real(4), allocatable :: values_real4(:,:)
  9021. real(8), allocatable :: values_real8(:,:)
  9022. ! --- begin --------------------------------------
  9023. ! pointer to file structure:
  9024. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  9025. IF_NOT_OK_RETURN(status=1)
  9026. ! pointer to variable structure:
  9027. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  9028. IF_NOT_OK_RETURN(status=1)
  9029. ! check ...
  9030. if ( size(shape(values)) > varp%ndim ) then
  9031. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  9032. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  9033. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  9034. TRACEBACK; status=1; return
  9035. end if
  9036. ! check ...
  9037. if ( present(start ) ) then
  9038. if ( size(start ) /= varp%ndim ) then
  9039. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9040. write (gol,'(" size start : ",i6)') size(start ); call goErr
  9041. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9042. TRACEBACK; status=1; return
  9043. end if
  9044. end if
  9045. if ( present(count ) ) then
  9046. if ( size(count ) /= varp%ndim ) then
  9047. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9048. write (gol,'(" size count : ",i6)') size(count ); call goErr
  9049. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9050. TRACEBACK; status=1; return
  9051. end if
  9052. end if
  9053. if ( present(stride ) ) then
  9054. if ( size(stride ) /= varp%ndim ) then
  9055. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9056. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  9057. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9058. TRACEBACK; status=1; return
  9059. end if
  9060. end if
  9061. if ( present(map ) ) then
  9062. if ( size(map ) /= varp%ndim ) then
  9063. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9064. write (gol,'(" size map : ",i6)') size(map ); call goErr
  9065. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9066. TRACEBACK; status=1; return
  9067. end if
  9068. end if
  9069. ! loop over file types:
  9070. do iftype = 1, filep%nftype
  9071. ! current type:
  9072. ftype = filep%ftypes(iftype)
  9073. ! select appropriate routine for each type:
  9074. select case ( ftype )
  9075. #ifdef with_hdf4
  9076. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9077. case ( MDF_HDF4 )
  9078. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9079. ! check ...
  9080. if ( present(map ) ) then
  9081. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  9082. TRACEBACK; status=1; return
  9083. end if
  9084. ! fill offset (zero based!) and stride with default values:
  9085. hdf4_offset = 0
  9086. hdf4_stride = 1
  9087. ! count is by default the shape; padd with singleton dimensions:
  9088. hdf4_count = 1; hdf4_count(1:2) = shape(values)
  9089. ! replace by optional arguments if necessary:
  9090. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  9091. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  9092. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  9093. ! test target type;
  9094. ! convert to required kind before entering sfWData,
  9095. ! otherwise segmentation faults on some machines ...
  9096. select case ( varp%xtype )
  9097. case ( MDF_BYTE )
  9098. allocate( values_int1(size(values,1),size(values,2)) )
  9099. values_int1 = int(values,kind=1)
  9100. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9101. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  9102. deallocate( values_int1 )
  9103. case ( MDF_SHORT )
  9104. allocate( values_int2(size(values,1),size(values,2)) )
  9105. values_int2 = int(values,kind=2)
  9106. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9107. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  9108. deallocate( values_int2 )
  9109. case ( MDF_INT )
  9110. allocate( values_int4(size(values,1),size(values,2)) )
  9111. values_int4 = int(values,kind=4)
  9112. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9113. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  9114. deallocate( values_int4 )
  9115. case ( MDF_FLOAT )
  9116. allocate( values_real4(size(values,1),size(values,2)) )
  9117. values_real4 = real(values,kind=4)
  9118. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9119. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  9120. deallocate( values_real4 )
  9121. case ( MDF_DOUBLE )
  9122. allocate( values_real8(size(values,1),size(values,2)) )
  9123. values_real8 = real(values,kind=8)
  9124. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9125. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  9126. deallocate( values_real8 )
  9127. case default
  9128. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  9129. TRACEBACK; status=1; return
  9130. end select
  9131. if ( status == FAIL ) then
  9132. write (gol,'("writing hdf4 data set:")'); call goErr
  9133. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  9134. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  9135. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  9136. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  9137. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  9138. write (gol,'(" size : ",i12)') size(values); call goErr
  9139. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  9140. TRACEBACK; status=1; return
  9141. end if
  9142. #endif
  9143. #ifdef with_hdf5_beta
  9144. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9145. case ( MDF_HDF5 )
  9146. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9147. ! check ...
  9148. if ( present(map ) ) then
  9149. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  9150. TRACEBACK; status=1; return
  9151. end if
  9152. ! fill offset (zero based!), stride, and count :
  9153. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  9154. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  9155. hdf5_count = 1 ! default singleton dimension
  9156. if ( present(count) ) then
  9157. hdf5_count(1:varp%ndim) = count
  9158. else
  9159. hdf5_count(1:2) = shape(values)
  9160. end if
  9161. ! new dimension:
  9162. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  9163. ! target data space in file:
  9164. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  9165. IF_NOT_OK_RETURN(status=1)
  9166. ! chunked dataset ?
  9167. if ( varp%hdf5_chunked ) then
  9168. ! reset extend:
  9169. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  9170. IF_NOT_OK_RETURN(status=1)
  9171. end if
  9172. ! select hyperslab:
  9173. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  9174. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  9175. stride=hdf5_stride(1:varp%ndim) )
  9176. ! write data:
  9177. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  9178. int(shape(values),kind=HSIZE_T), status, &
  9179. file_space_id=hdf5_file_space_id )
  9180. IF_NOT_OK_RETURN(status=1)
  9181. ! release data space:
  9182. call H5SClose_f( hdf5_file_space_id, status )
  9183. IF_NOT_OK_RETURN(status=1)
  9184. #endif
  9185. #ifdef with_netcdf
  9186. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9187. case ( MDF_NETCDF, MDF_NETCDF4 )
  9188. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9189. ! test target type:
  9190. ! convert to required kind before entering NF90_Put_Var,
  9191. ! otherwise segmentation faults on some machines ...
  9192. select case ( varp%xtype )
  9193. case ( MDF_BYTE )
  9194. allocate( values_int1(size(values,1),size(values,2)) )
  9195. values_int1 = int(values,kind=1)
  9196. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  9197. start, count, stride, map )
  9198. IF_NF90_NOT_OK_RETURN(status=1)
  9199. deallocate( values_int1 )
  9200. case ( MDF_SHORT )
  9201. allocate( values_int2(size(values,1),size(values,2)) )
  9202. values_int2 = int(values,kind=2)
  9203. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  9204. start, count, stride, map )
  9205. IF_NF90_NOT_OK_RETURN(status=1)
  9206. deallocate( values_int2 )
  9207. case ( MDF_INT )
  9208. allocate( values_int4(size(values,1),size(values,2)) )
  9209. values_int4 = int(values,kind=4)
  9210. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  9211. start, count, stride, map )
  9212. IF_NF90_NOT_OK_RETURN(status=1)
  9213. deallocate( values_int4 )
  9214. case ( MDF_FLOAT )
  9215. allocate( values_real4(size(values,1),size(values,2)) )
  9216. values_real4 = real(values,kind=4)
  9217. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  9218. start, count, stride, map )
  9219. IF_NF90_NOT_OK_RETURN(status=1)
  9220. deallocate( values_real4 )
  9221. case ( MDF_DOUBLE )
  9222. allocate( values_real8(size(values,1),size(values,2)) )
  9223. values_real8 = real(values,kind=8)
  9224. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  9225. start, count, stride, map )
  9226. IF_NF90_NOT_OK_RETURN(status=1)
  9227. deallocate( values_real8 )
  9228. case default
  9229. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  9230. TRACEBACK; status=1; return
  9231. end select
  9232. ! just put; let netcdf library convert the right kind:
  9233. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  9234. ! start, count, stride, map )
  9235. !IF_NF90_NOT_OK_RETURN(status=1)
  9236. #endif
  9237. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9238. case default
  9239. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9240. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  9241. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  9242. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  9243. TRACEBACK; status=1; return
  9244. end select
  9245. end do ! file types
  9246. ! ok
  9247. status = 0
  9248. end subroutine MDF_Put_Var_i2_2d
  9249. ! ***
  9250. subroutine MDF_Get_Var_i2_2d( hid, varid, values, status, &
  9251. start, count, stride, map )
  9252. #ifdef with_netcdf
  9253. use NetCDF, only : NF90_Get_Var
  9254. #endif
  9255. ! --- in/out -------------------------------------
  9256. integer, intent(in) :: hid
  9257. integer, intent(in) :: varid
  9258. integer(2), intent(out) :: values(:,:)
  9259. integer, intent(out) :: status
  9260. integer, intent(in), optional :: start (:)
  9261. integer, intent(in), optional :: count (:)
  9262. integer, intent(in), optional :: stride(:)
  9263. integer, intent(in), optional :: map (:)
  9264. ! --- const --------------------------------------
  9265. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_2d'
  9266. ! --- external -----------------------------------
  9267. #ifdef with_hdf4
  9268. integer(hdf4_wpi), external :: sfRData
  9269. #endif
  9270. ! --- local --------------------------------------
  9271. type(MDF_File), pointer :: filep
  9272. type(MDF_Var), pointer :: varp
  9273. integer :: iftype
  9274. integer :: ftype
  9275. #ifdef with_hdf4
  9276. integer :: hdf4_offset(MAX_RANK)
  9277. integer :: hdf4_stride(MAX_RANK)
  9278. integer :: hdf4_count(MAX_RANK)
  9279. integer(1), allocatable :: values_int1(:,:)
  9280. integer(2), allocatable :: values_int2(:,:)
  9281. integer(4), allocatable :: values_int4(:,:)
  9282. integer(8), allocatable :: values_int8(:,:)
  9283. real(4), allocatable :: values_real4(:,:)
  9284. real(8), allocatable :: values_real8(:,:)
  9285. #endif
  9286. ! --- begin --------------------------------------
  9287. ! pointer to file structure:
  9288. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  9289. IF_NOT_OK_RETURN(status=1)
  9290. ! pointer to variable structure:
  9291. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  9292. IF_NOT_OK_RETURN(status=1)
  9293. ! check ...
  9294. if ( size(shape(values)) > varp%ndim ) then
  9295. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  9296. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  9297. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  9298. TRACEBACK; status=1; return
  9299. end if
  9300. ! check ...
  9301. if ( present(start ) ) then
  9302. if ( size(start ) /= varp%ndim ) then
  9303. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9304. write (gol,'(" size start : ",i6)') size(start ); call goErr
  9305. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9306. TRACEBACK; status=1; return
  9307. end if
  9308. end if
  9309. if ( present(count ) ) then
  9310. if ( size(count ) /= varp%ndim ) then
  9311. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9312. write (gol,'(" size count : ",i6)') size(count ); call goErr
  9313. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9314. TRACEBACK; status=1; return
  9315. end if
  9316. end if
  9317. if ( present(stride ) ) then
  9318. if ( size(stride ) /= varp%ndim ) then
  9319. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9320. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  9321. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9322. TRACEBACK; status=1; return
  9323. end if
  9324. end if
  9325. if ( present(map ) ) then
  9326. if ( size(map ) /= varp%ndim ) then
  9327. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9328. write (gol,'(" size map : ",i6)') size(map ); call goErr
  9329. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9330. TRACEBACK; status=1; return
  9331. end if
  9332. end if
  9333. ! loop over file types:
  9334. do iftype = 1, filep%nftype
  9335. ! current type:
  9336. ftype = filep%ftypes(iftype)
  9337. ! select appropriate routine for each type:
  9338. select case ( ftype )
  9339. #ifdef with_hdf4
  9340. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9341. case ( MDF_HDF4 )
  9342. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9343. ! check ...
  9344. if ( present(map ) ) then
  9345. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  9346. TRACEBACK; status=1; return
  9347. end if
  9348. ! fill offset (zero based!), stride, and count :
  9349. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  9350. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  9351. hdf4_count = 1 ! default singleton dimension
  9352. hdf4_count(1:2) = shape(values)
  9353. ! test source type:
  9354. select case ( varp%hdf4_xtype )
  9355. case ( DFNT_INT8 )
  9356. allocate( values_int1(size(values,1),size(values,2)) )
  9357. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  9358. values = int(values_int1,kind=2)
  9359. deallocate( values_int1 )
  9360. case ( DFNT_INT16 )
  9361. allocate( values_int2(size(values,1),size(values,2)) )
  9362. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  9363. values = int(values_int2,kind=2)
  9364. deallocate( values_int2 )
  9365. case ( DFNT_INT32 )
  9366. allocate( values_int4(size(values,1),size(values,2)) )
  9367. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  9368. values = int(values_int4,kind=2)
  9369. deallocate( values_int4 )
  9370. case ( DFNT_INT64 )
  9371. allocate( values_int8(size(values,1),size(values,2)) )
  9372. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  9373. values = int(values_int8,kind=2)
  9374. deallocate( values_int8 )
  9375. case ( DFNT_FLOAT32 )
  9376. allocate( values_real4(size(values,1),size(values,2)) )
  9377. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  9378. values = int(values_real4,kind=2)
  9379. deallocate( values_real4 )
  9380. case ( DFNT_FLOAT64 )
  9381. allocate( values_real8(size(values,1),size(values,2)) )
  9382. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  9383. values = int(values_real8,kind=2)
  9384. deallocate( values_real8 )
  9385. case default
  9386. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  9387. TRACEBACK; status=1; return
  9388. end select
  9389. if ( status == FAIL ) then
  9390. write (gol,'("reading hdf4 data set:")'); call goErr
  9391. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  9392. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  9393. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  9394. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  9395. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  9396. write (gol,'(" size : ",i6)') size(values); call goErr
  9397. TRACEBACK; status=1; return
  9398. end if
  9399. #endif
  9400. #ifdef with_netcdf
  9401. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9402. case ( MDF_NETCDF, MDF_NETCDF4 )
  9403. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9404. ! read values, converted automatically:
  9405. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  9406. start, count, stride, map )
  9407. IF_NF90_NOT_OK_RETURN(status=1)
  9408. #endif
  9409. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9410. case default
  9411. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9412. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  9413. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  9414. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  9415. TRACEBACK; status=1; return
  9416. end select
  9417. end do ! file types
  9418. ! ok
  9419. status = 0
  9420. end subroutine MDF_Get_Var_i2_2d
  9421. ! ***
  9422. subroutine MDF_Put_Var_i2_3d( hid, varid, values, status, &
  9423. start, count, stride, map )
  9424. #ifdef with_hdf5_beta
  9425. use HDF5, only : HID_T, HSIZE_T
  9426. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  9427. use HDF5, only : H5T_NATIVE_CHARACTER
  9428. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  9429. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  9430. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  9431. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  9432. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  9433. #endif
  9434. #ifdef with_netcdf
  9435. use NetCDF, only : NF90_Put_Var
  9436. #endif
  9437. ! --- in/out -------------------------------------
  9438. integer, intent(in) :: hid
  9439. integer, intent(in) :: varid
  9440. integer(2), intent(in) :: values(:,:,:)
  9441. integer, intent(out) :: status
  9442. integer, intent(in), optional :: start (:)
  9443. integer, intent(in), optional :: count (:)
  9444. integer, intent(in), optional :: stride(:)
  9445. integer, intent(in), optional :: map (:)
  9446. ! --- const --------------------------------------
  9447. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_3d'
  9448. ! --- external -----------------------------------
  9449. #ifdef with_hdf4
  9450. integer(hdf4_wpi), external :: sfWData
  9451. #endif
  9452. ! --- local --------------------------------------
  9453. type(MDF_File), pointer :: filep
  9454. type(MDF_Var), pointer :: varp
  9455. integer :: iftype
  9456. integer :: ftype
  9457. #ifdef with_hdf4
  9458. integer :: hdf4_offset(MAX_RANK)
  9459. integer :: hdf4_stride(MAX_RANK)
  9460. integer :: hdf4_count(MAX_RANK)
  9461. #endif
  9462. #ifdef with_hdf5_beta
  9463. !integer(HID_T) :: hdf5_type_id
  9464. integer(HID_T) :: hdf5_file_space_id
  9465. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  9466. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  9467. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  9468. #endif
  9469. integer(1), allocatable :: values_int1(:,:,:)
  9470. integer(2), allocatable :: values_int2(:,:,:)
  9471. integer(4), allocatable :: values_int4(:,:,:)
  9472. integer(8), allocatable :: values_int8(:,:,:)
  9473. real(4), allocatable :: values_real4(:,:,:)
  9474. real(8), allocatable :: values_real8(:,:,:)
  9475. ! --- begin --------------------------------------
  9476. ! pointer to file structure:
  9477. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  9478. IF_NOT_OK_RETURN(status=1)
  9479. ! pointer to variable structure:
  9480. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  9481. IF_NOT_OK_RETURN(status=1)
  9482. ! check ...
  9483. if ( size(shape(values)) > varp%ndim ) then
  9484. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  9485. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  9486. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  9487. TRACEBACK; status=1; return
  9488. end if
  9489. ! check ...
  9490. if ( present(start ) ) then
  9491. if ( size(start ) /= varp%ndim ) then
  9492. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9493. write (gol,'(" size start : ",i6)') size(start ); call goErr
  9494. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9495. TRACEBACK; status=1; return
  9496. end if
  9497. end if
  9498. if ( present(count ) ) then
  9499. if ( size(count ) /= varp%ndim ) then
  9500. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9501. write (gol,'(" size count : ",i6)') size(count ); call goErr
  9502. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9503. TRACEBACK; status=1; return
  9504. end if
  9505. end if
  9506. if ( present(stride ) ) then
  9507. if ( size(stride ) /= varp%ndim ) then
  9508. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9509. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  9510. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9511. TRACEBACK; status=1; return
  9512. end if
  9513. end if
  9514. if ( present(map ) ) then
  9515. if ( size(map ) /= varp%ndim ) then
  9516. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9517. write (gol,'(" size map : ",i6)') size(map ); call goErr
  9518. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9519. TRACEBACK; status=1; return
  9520. end if
  9521. end if
  9522. ! loop over file types:
  9523. do iftype = 1, filep%nftype
  9524. ! current type:
  9525. ftype = filep%ftypes(iftype)
  9526. ! select appropriate routine for each type:
  9527. select case ( ftype )
  9528. #ifdef with_hdf4
  9529. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9530. case ( MDF_HDF4 )
  9531. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9532. ! check ...
  9533. if ( present(map ) ) then
  9534. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  9535. TRACEBACK; status=1; return
  9536. end if
  9537. ! fill offset (zero based!) and stride with default values:
  9538. hdf4_offset = 0
  9539. hdf4_stride = 1
  9540. ! count is by default the shape; padd with singleton dimensions:
  9541. hdf4_count = 1; hdf4_count(1:3) = shape(values)
  9542. ! replace by optional arguments if necessary:
  9543. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  9544. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  9545. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  9546. ! test target type;
  9547. ! convert to required kind before entering sfWData,
  9548. ! otherwise segmentation faults on some machines ...
  9549. select case ( varp%xtype )
  9550. case ( MDF_BYTE )
  9551. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  9552. values_int1 = int(values,kind=1)
  9553. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9554. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  9555. deallocate( values_int1 )
  9556. case ( MDF_SHORT )
  9557. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  9558. values_int2 = int(values,kind=2)
  9559. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9560. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  9561. deallocate( values_int2 )
  9562. case ( MDF_INT )
  9563. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  9564. values_int4 = int(values,kind=4)
  9565. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9566. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  9567. deallocate( values_int4 )
  9568. case ( MDF_FLOAT )
  9569. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  9570. values_real4 = real(values,kind=4)
  9571. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9572. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  9573. deallocate( values_real4 )
  9574. case ( MDF_DOUBLE )
  9575. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  9576. values_real8 = real(values,kind=8)
  9577. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  9578. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  9579. deallocate( values_real8 )
  9580. case default
  9581. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  9582. TRACEBACK; status=1; return
  9583. end select
  9584. if ( status == FAIL ) then
  9585. write (gol,'("writing hdf4 data set:")'); call goErr
  9586. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  9587. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  9588. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  9589. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  9590. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  9591. write (gol,'(" size : ",i12)') size(values); call goErr
  9592. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  9593. TRACEBACK; status=1; return
  9594. end if
  9595. #endif
  9596. #ifdef with_hdf5_beta
  9597. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9598. case ( MDF_HDF5 )
  9599. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9600. ! check ...
  9601. if ( present(map ) ) then
  9602. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  9603. TRACEBACK; status=1; return
  9604. end if
  9605. ! fill offset (zero based!), stride, and count :
  9606. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  9607. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  9608. hdf5_count = 1 ! default singleton dimension
  9609. if ( present(count) ) then
  9610. hdf5_count(1:varp%ndim) = count
  9611. else
  9612. hdf5_count(1:3) = shape(values)
  9613. end if
  9614. ! new dimension:
  9615. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  9616. ! target data space in file:
  9617. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  9618. IF_NOT_OK_RETURN(status=1)
  9619. ! chunked dataset ?
  9620. if ( varp%hdf5_chunked ) then
  9621. ! reset extend:
  9622. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  9623. IF_NOT_OK_RETURN(status=1)
  9624. end if
  9625. ! select hyperslab:
  9626. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  9627. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  9628. stride=hdf5_stride(1:varp%ndim) )
  9629. ! write data:
  9630. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  9631. int(shape(values),kind=HSIZE_T), status, &
  9632. file_space_id=hdf5_file_space_id )
  9633. IF_NOT_OK_RETURN(status=1)
  9634. ! release data space:
  9635. call H5SClose_f( hdf5_file_space_id, status )
  9636. IF_NOT_OK_RETURN(status=1)
  9637. #endif
  9638. #ifdef with_netcdf
  9639. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9640. case ( MDF_NETCDF, MDF_NETCDF4 )
  9641. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9642. ! test target type:
  9643. ! convert to required kind before entering NF90_Put_Var,
  9644. ! otherwise segmentation faults on some machines ...
  9645. select case ( varp%xtype )
  9646. case ( MDF_BYTE )
  9647. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  9648. values_int1 = int(values,kind=1)
  9649. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  9650. start, count, stride, map )
  9651. IF_NF90_NOT_OK_RETURN(status=1)
  9652. deallocate( values_int1 )
  9653. case ( MDF_SHORT )
  9654. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  9655. values_int2 = int(values,kind=2)
  9656. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  9657. start, count, stride, map )
  9658. IF_NF90_NOT_OK_RETURN(status=1)
  9659. deallocate( values_int2 )
  9660. case ( MDF_INT )
  9661. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  9662. values_int4 = int(values,kind=4)
  9663. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  9664. start, count, stride, map )
  9665. IF_NF90_NOT_OK_RETURN(status=1)
  9666. deallocate( values_int4 )
  9667. case ( MDF_FLOAT )
  9668. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  9669. values_real4 = real(values,kind=4)
  9670. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  9671. start, count, stride, map )
  9672. IF_NF90_NOT_OK_RETURN(status=1)
  9673. deallocate( values_real4 )
  9674. case ( MDF_DOUBLE )
  9675. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  9676. values_real8 = real(values,kind=8)
  9677. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  9678. start, count, stride, map )
  9679. IF_NF90_NOT_OK_RETURN(status=1)
  9680. deallocate( values_real8 )
  9681. case default
  9682. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  9683. TRACEBACK; status=1; return
  9684. end select
  9685. ! just put; let netcdf library convert the right kind:
  9686. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  9687. ! start, count, stride, map )
  9688. !IF_NF90_NOT_OK_RETURN(status=1)
  9689. #endif
  9690. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9691. case default
  9692. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9693. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  9694. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  9695. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  9696. TRACEBACK; status=1; return
  9697. end select
  9698. end do ! file types
  9699. ! ok
  9700. status = 0
  9701. end subroutine MDF_Put_Var_i2_3d
  9702. ! ***
  9703. subroutine MDF_Get_Var_i2_3d( hid, varid, values, status, &
  9704. start, count, stride, map )
  9705. #ifdef with_netcdf
  9706. use NetCDF, only : NF90_Get_Var
  9707. #endif
  9708. ! --- in/out -------------------------------------
  9709. integer, intent(in) :: hid
  9710. integer, intent(in) :: varid
  9711. integer(2), intent(out) :: values(:,:,:)
  9712. integer, intent(out) :: status
  9713. integer, intent(in), optional :: start (:)
  9714. integer, intent(in), optional :: count (:)
  9715. integer, intent(in), optional :: stride(:)
  9716. integer, intent(in), optional :: map (:)
  9717. ! --- const --------------------------------------
  9718. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_3d'
  9719. ! --- external -----------------------------------
  9720. #ifdef with_hdf4
  9721. integer(hdf4_wpi), external :: sfRData
  9722. #endif
  9723. ! --- local --------------------------------------
  9724. type(MDF_File), pointer :: filep
  9725. type(MDF_Var), pointer :: varp
  9726. integer :: iftype
  9727. integer :: ftype
  9728. #ifdef with_hdf4
  9729. integer :: hdf4_offset(MAX_RANK)
  9730. integer :: hdf4_stride(MAX_RANK)
  9731. integer :: hdf4_count(MAX_RANK)
  9732. integer(1), allocatable :: values_int1(:,:,:)
  9733. integer(2), allocatable :: values_int2(:,:,:)
  9734. integer(4), allocatable :: values_int4(:,:,:)
  9735. integer(8), allocatable :: values_int8(:,:,:)
  9736. real(4), allocatable :: values_real4(:,:,:)
  9737. real(8), allocatable :: values_real8(:,:,:)
  9738. #endif
  9739. ! --- begin --------------------------------------
  9740. ! pointer to file structure:
  9741. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  9742. IF_NOT_OK_RETURN(status=1)
  9743. ! pointer to variable structure:
  9744. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  9745. IF_NOT_OK_RETURN(status=1)
  9746. ! check ...
  9747. if ( size(shape(values)) > varp%ndim ) then
  9748. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  9749. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  9750. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  9751. TRACEBACK; status=1; return
  9752. end if
  9753. ! check ...
  9754. if ( present(start ) ) then
  9755. if ( size(start ) /= varp%ndim ) then
  9756. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9757. write (gol,'(" size start : ",i6)') size(start ); call goErr
  9758. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9759. TRACEBACK; status=1; return
  9760. end if
  9761. end if
  9762. if ( present(count ) ) then
  9763. if ( size(count ) /= varp%ndim ) then
  9764. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9765. write (gol,'(" size count : ",i6)') size(count ); call goErr
  9766. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9767. TRACEBACK; status=1; return
  9768. end if
  9769. end if
  9770. if ( present(stride ) ) then
  9771. if ( size(stride ) /= varp%ndim ) then
  9772. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9773. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  9774. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9775. TRACEBACK; status=1; return
  9776. end if
  9777. end if
  9778. if ( present(map ) ) then
  9779. if ( size(map ) /= varp%ndim ) then
  9780. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9781. write (gol,'(" size map : ",i6)') size(map ); call goErr
  9782. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9783. TRACEBACK; status=1; return
  9784. end if
  9785. end if
  9786. ! loop over file types:
  9787. do iftype = 1, filep%nftype
  9788. ! current type:
  9789. ftype = filep%ftypes(iftype)
  9790. ! select appropriate routine for each type:
  9791. select case ( ftype )
  9792. #ifdef with_hdf4
  9793. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9794. case ( MDF_HDF4 )
  9795. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9796. ! check ...
  9797. if ( present(map ) ) then
  9798. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  9799. TRACEBACK; status=1; return
  9800. end if
  9801. ! fill offset (zero based!), stride, and count :
  9802. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  9803. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  9804. hdf4_count = 1 ! default singleton dimension
  9805. hdf4_count(1:3) = shape(values)
  9806. ! test source type:
  9807. select case ( varp%hdf4_xtype )
  9808. case ( DFNT_INT8 )
  9809. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  9810. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  9811. values = int(values_int1,kind=2)
  9812. deallocate( values_int1 )
  9813. case ( DFNT_INT16 )
  9814. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  9815. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  9816. values = int(values_int2,kind=2)
  9817. deallocate( values_int2 )
  9818. case ( DFNT_INT32 )
  9819. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  9820. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  9821. values = int(values_int4,kind=2)
  9822. deallocate( values_int4 )
  9823. case ( DFNT_INT64 )
  9824. allocate( values_int8(size(values,1),size(values,2),size(values,3)) )
  9825. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  9826. values = int(values_int8,kind=2)
  9827. deallocate( values_int8 )
  9828. case ( DFNT_FLOAT32 )
  9829. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  9830. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  9831. values = int(values_real4,kind=2)
  9832. deallocate( values_real4 )
  9833. case ( DFNT_FLOAT64 )
  9834. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  9835. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  9836. values = int(values_real8,kind=2)
  9837. deallocate( values_real8 )
  9838. case default
  9839. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  9840. TRACEBACK; status=1; return
  9841. end select
  9842. if ( status == FAIL ) then
  9843. write (gol,'("reading hdf4 data set:")'); call goErr
  9844. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  9845. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  9846. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  9847. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  9848. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  9849. write (gol,'(" size : ",i6)') size(values); call goErr
  9850. TRACEBACK; status=1; return
  9851. end if
  9852. #endif
  9853. #ifdef with_netcdf
  9854. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9855. case ( MDF_NETCDF, MDF_NETCDF4 )
  9856. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9857. ! read values, converted automatically:
  9858. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  9859. start, count, stride, map )
  9860. IF_NF90_NOT_OK_RETURN(status=1)
  9861. #endif
  9862. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9863. case default
  9864. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9865. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  9866. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  9867. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  9868. TRACEBACK; status=1; return
  9869. end select
  9870. end do ! file types
  9871. ! ok
  9872. status = 0
  9873. end subroutine MDF_Get_Var_i2_3d
  9874. ! ***
  9875. subroutine MDF_Put_Var_i2_4d( hid, varid, values, status, &
  9876. start, count, stride, map )
  9877. #ifdef with_hdf5_beta
  9878. use HDF5, only : HID_T, HSIZE_T
  9879. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  9880. use HDF5, only : H5T_NATIVE_CHARACTER
  9881. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  9882. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  9883. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  9884. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  9885. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  9886. #endif
  9887. #ifdef with_netcdf
  9888. use NetCDF, only : NF90_Put_Var
  9889. #endif
  9890. ! --- in/out -------------------------------------
  9891. integer, intent(in) :: hid
  9892. integer, intent(in) :: varid
  9893. integer(2), intent(in) :: values(:,:,:,:)
  9894. integer, intent(out) :: status
  9895. integer, intent(in), optional :: start (:)
  9896. integer, intent(in), optional :: count (:)
  9897. integer, intent(in), optional :: stride(:)
  9898. integer, intent(in), optional :: map (:)
  9899. ! --- const --------------------------------------
  9900. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_4d'
  9901. ! --- external -----------------------------------
  9902. #ifdef with_hdf4
  9903. integer(hdf4_wpi), external :: sfWData
  9904. #endif
  9905. ! --- local --------------------------------------
  9906. type(MDF_File), pointer :: filep
  9907. type(MDF_Var), pointer :: varp
  9908. integer :: iftype
  9909. integer :: ftype
  9910. #ifdef with_hdf4
  9911. integer :: hdf4_offset(MAX_RANK)
  9912. integer :: hdf4_stride(MAX_RANK)
  9913. integer :: hdf4_count(MAX_RANK)
  9914. #endif
  9915. #ifdef with_hdf5_beta
  9916. !integer(HID_T) :: hdf5_type_id
  9917. integer(HID_T) :: hdf5_file_space_id
  9918. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  9919. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  9920. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  9921. #endif
  9922. integer(1), allocatable :: values_int1(:,:,:,:)
  9923. integer(2), allocatable :: values_int2(:,:,:,:)
  9924. integer(4), allocatable :: values_int4(:,:,:,:)
  9925. integer(8), allocatable :: values_int8(:,:,:,:)
  9926. real(4), allocatable :: values_real4(:,:,:,:)
  9927. real(8), allocatable :: values_real8(:,:,:,:)
  9928. ! --- begin --------------------------------------
  9929. ! pointer to file structure:
  9930. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  9931. IF_NOT_OK_RETURN(status=1)
  9932. ! pointer to variable structure:
  9933. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  9934. IF_NOT_OK_RETURN(status=1)
  9935. ! check ...
  9936. if ( size(shape(values)) > varp%ndim ) then
  9937. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  9938. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  9939. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  9940. TRACEBACK; status=1; return
  9941. end if
  9942. ! check ...
  9943. if ( present(start ) ) then
  9944. if ( size(start ) /= varp%ndim ) then
  9945. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9946. write (gol,'(" size start : ",i6)') size(start ); call goErr
  9947. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9948. TRACEBACK; status=1; return
  9949. end if
  9950. end if
  9951. if ( present(count ) ) then
  9952. if ( size(count ) /= varp%ndim ) then
  9953. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9954. write (gol,'(" size count : ",i6)') size(count ); call goErr
  9955. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9956. TRACEBACK; status=1; return
  9957. end if
  9958. end if
  9959. if ( present(stride ) ) then
  9960. if ( size(stride ) /= varp%ndim ) then
  9961. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9962. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  9963. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9964. TRACEBACK; status=1; return
  9965. end if
  9966. end if
  9967. if ( present(map ) ) then
  9968. if ( size(map ) /= varp%ndim ) then
  9969. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  9970. write (gol,'(" size map : ",i6)') size(map ); call goErr
  9971. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  9972. TRACEBACK; status=1; return
  9973. end if
  9974. end if
  9975. ! loop over file types:
  9976. do iftype = 1, filep%nftype
  9977. ! current type:
  9978. ftype = filep%ftypes(iftype)
  9979. ! select appropriate routine for each type:
  9980. select case ( ftype )
  9981. #ifdef with_hdf4
  9982. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9983. case ( MDF_HDF4 )
  9984. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  9985. ! check ...
  9986. if ( present(map ) ) then
  9987. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  9988. TRACEBACK; status=1; return
  9989. end if
  9990. ! fill offset (zero based!) and stride with default values:
  9991. hdf4_offset = 0
  9992. hdf4_stride = 1
  9993. ! count is by default the shape; padd with singleton dimensions:
  9994. hdf4_count = 1; hdf4_count(1:4) = shape(values)
  9995. ! replace by optional arguments if necessary:
  9996. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  9997. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  9998. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  9999. ! test target type;
  10000. ! convert to required kind before entering sfWData,
  10001. ! otherwise segmentation faults on some machines ...
  10002. select case ( varp%xtype )
  10003. case ( MDF_BYTE )
  10004. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10005. values_int1 = int(values,kind=1)
  10006. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10007. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  10008. deallocate( values_int1 )
  10009. case ( MDF_SHORT )
  10010. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10011. values_int2 = int(values,kind=2)
  10012. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10013. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  10014. deallocate( values_int2 )
  10015. case ( MDF_INT )
  10016. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10017. values_int4 = int(values,kind=4)
  10018. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10019. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  10020. deallocate( values_int4 )
  10021. case ( MDF_FLOAT )
  10022. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10023. values_real4 = real(values,kind=4)
  10024. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10025. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  10026. deallocate( values_real4 )
  10027. case ( MDF_DOUBLE )
  10028. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10029. values_real8 = real(values,kind=8)
  10030. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10031. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  10032. deallocate( values_real8 )
  10033. case default
  10034. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  10035. TRACEBACK; status=1; return
  10036. end select
  10037. if ( status == FAIL ) then
  10038. write (gol,'("writing hdf4 data set:")'); call goErr
  10039. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  10040. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  10041. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  10042. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  10043. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  10044. write (gol,'(" size : ",i12)') size(values); call goErr
  10045. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  10046. TRACEBACK; status=1; return
  10047. end if
  10048. #endif
  10049. #ifdef with_hdf5_beta
  10050. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10051. case ( MDF_HDF5 )
  10052. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10053. ! check ...
  10054. if ( present(map ) ) then
  10055. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  10056. TRACEBACK; status=1; return
  10057. end if
  10058. ! fill offset (zero based!), stride, and count :
  10059. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  10060. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  10061. hdf5_count = 1 ! default singleton dimension
  10062. if ( present(count) ) then
  10063. hdf5_count(1:varp%ndim) = count
  10064. else
  10065. hdf5_count(1:4) = shape(values)
  10066. end if
  10067. ! new dimension:
  10068. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  10069. ! target data space in file:
  10070. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  10071. IF_NOT_OK_RETURN(status=1)
  10072. ! chunked dataset ?
  10073. if ( varp%hdf5_chunked ) then
  10074. ! reset extend:
  10075. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  10076. IF_NOT_OK_RETURN(status=1)
  10077. end if
  10078. ! select hyperslab:
  10079. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  10080. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  10081. stride=hdf5_stride(1:varp%ndim) )
  10082. ! write data:
  10083. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  10084. int(shape(values),kind=HSIZE_T), status, &
  10085. file_space_id=hdf5_file_space_id )
  10086. IF_NOT_OK_RETURN(status=1)
  10087. ! release data space:
  10088. call H5SClose_f( hdf5_file_space_id, status )
  10089. IF_NOT_OK_RETURN(status=1)
  10090. #endif
  10091. #ifdef with_netcdf
  10092. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10093. case ( MDF_NETCDF, MDF_NETCDF4 )
  10094. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10095. ! test target type:
  10096. ! convert to required kind before entering NF90_Put_Var,
  10097. ! otherwise segmentation faults on some machines ...
  10098. select case ( varp%xtype )
  10099. case ( MDF_BYTE )
  10100. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10101. values_int1 = int(values,kind=1)
  10102. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  10103. start, count, stride, map )
  10104. IF_NF90_NOT_OK_RETURN(status=1)
  10105. deallocate( values_int1 )
  10106. case ( MDF_SHORT )
  10107. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10108. values_int2 = int(values,kind=2)
  10109. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  10110. start, count, stride, map )
  10111. IF_NF90_NOT_OK_RETURN(status=1)
  10112. deallocate( values_int2 )
  10113. case ( MDF_INT )
  10114. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10115. values_int4 = int(values,kind=4)
  10116. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  10117. start, count, stride, map )
  10118. IF_NF90_NOT_OK_RETURN(status=1)
  10119. deallocate( values_int4 )
  10120. case ( MDF_FLOAT )
  10121. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10122. values_real4 = real(values,kind=4)
  10123. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  10124. start, count, stride, map )
  10125. IF_NF90_NOT_OK_RETURN(status=1)
  10126. deallocate( values_real4 )
  10127. case ( MDF_DOUBLE )
  10128. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10129. values_real8 = real(values,kind=8)
  10130. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  10131. start, count, stride, map )
  10132. IF_NF90_NOT_OK_RETURN(status=1)
  10133. deallocate( values_real8 )
  10134. case default
  10135. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  10136. TRACEBACK; status=1; return
  10137. end select
  10138. ! just put; let netcdf library convert the right kind:
  10139. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  10140. ! start, count, stride, map )
  10141. !IF_NF90_NOT_OK_RETURN(status=1)
  10142. #endif
  10143. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10144. case default
  10145. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10146. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  10147. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  10148. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  10149. TRACEBACK; status=1; return
  10150. end select
  10151. end do ! file types
  10152. ! ok
  10153. status = 0
  10154. end subroutine MDF_Put_Var_i2_4d
  10155. ! ***
  10156. subroutine MDF_Get_Var_i2_4d( hid, varid, values, status, &
  10157. start, count, stride, map )
  10158. #ifdef with_netcdf
  10159. use NetCDF, only : NF90_Get_Var
  10160. #endif
  10161. ! --- in/out -------------------------------------
  10162. integer, intent(in) :: hid
  10163. integer, intent(in) :: varid
  10164. integer(2), intent(out) :: values(:,:,:,:)
  10165. integer, intent(out) :: status
  10166. integer, intent(in), optional :: start (:)
  10167. integer, intent(in), optional :: count (:)
  10168. integer, intent(in), optional :: stride(:)
  10169. integer, intent(in), optional :: map (:)
  10170. ! --- const --------------------------------------
  10171. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_4d'
  10172. ! --- external -----------------------------------
  10173. #ifdef with_hdf4
  10174. integer(hdf4_wpi), external :: sfRData
  10175. #endif
  10176. ! --- local --------------------------------------
  10177. type(MDF_File), pointer :: filep
  10178. type(MDF_Var), pointer :: varp
  10179. integer :: iftype
  10180. integer :: ftype
  10181. #ifdef with_hdf4
  10182. integer :: hdf4_offset(MAX_RANK)
  10183. integer :: hdf4_stride(MAX_RANK)
  10184. integer :: hdf4_count(MAX_RANK)
  10185. integer(1), allocatable :: values_int1(:,:,:,:)
  10186. integer(2), allocatable :: values_int2(:,:,:,:)
  10187. integer(4), allocatable :: values_int4(:,:,:,:)
  10188. integer(8), allocatable :: values_int8(:,:,:,:)
  10189. real(4), allocatable :: values_real4(:,:,:,:)
  10190. real(8), allocatable :: values_real8(:,:,:,:)
  10191. #endif
  10192. ! --- begin --------------------------------------
  10193. ! pointer to file structure:
  10194. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  10195. IF_NOT_OK_RETURN(status=1)
  10196. ! pointer to variable structure:
  10197. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  10198. IF_NOT_OK_RETURN(status=1)
  10199. ! check ...
  10200. if ( size(shape(values)) > varp%ndim ) then
  10201. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  10202. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  10203. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  10204. TRACEBACK; status=1; return
  10205. end if
  10206. ! check ...
  10207. if ( present(start ) ) then
  10208. if ( size(start ) /= varp%ndim ) then
  10209. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10210. write (gol,'(" size start : ",i6)') size(start ); call goErr
  10211. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10212. TRACEBACK; status=1; return
  10213. end if
  10214. end if
  10215. if ( present(count ) ) then
  10216. if ( size(count ) /= varp%ndim ) then
  10217. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10218. write (gol,'(" size count : ",i6)') size(count ); call goErr
  10219. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10220. TRACEBACK; status=1; return
  10221. end if
  10222. end if
  10223. if ( present(stride ) ) then
  10224. if ( size(stride ) /= varp%ndim ) then
  10225. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10226. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  10227. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10228. TRACEBACK; status=1; return
  10229. end if
  10230. end if
  10231. if ( present(map ) ) then
  10232. if ( size(map ) /= varp%ndim ) then
  10233. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10234. write (gol,'(" size map : ",i6)') size(map ); call goErr
  10235. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10236. TRACEBACK; status=1; return
  10237. end if
  10238. end if
  10239. ! loop over file types:
  10240. do iftype = 1, filep%nftype
  10241. ! current type:
  10242. ftype = filep%ftypes(iftype)
  10243. ! select appropriate routine for each type:
  10244. select case ( ftype )
  10245. #ifdef with_hdf4
  10246. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10247. case ( MDF_HDF4 )
  10248. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10249. ! check ...
  10250. if ( present(map ) ) then
  10251. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  10252. TRACEBACK; status=1; return
  10253. end if
  10254. ! fill offset (zero based!), stride, and count :
  10255. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  10256. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  10257. hdf4_count = 1 ! default singleton dimension
  10258. hdf4_count(1:4) = shape(values)
  10259. ! test source type:
  10260. select case ( varp%hdf4_xtype )
  10261. case ( DFNT_INT8 )
  10262. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10263. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  10264. values = int(values_int1,kind=2)
  10265. deallocate( values_int1 )
  10266. case ( DFNT_INT16 )
  10267. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10268. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  10269. values = int(values_int2,kind=2)
  10270. deallocate( values_int2 )
  10271. case ( DFNT_INT32 )
  10272. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10273. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  10274. values = int(values_int4,kind=2)
  10275. deallocate( values_int4 )
  10276. case ( DFNT_INT64 )
  10277. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10278. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  10279. values = int(values_int8,kind=2)
  10280. deallocate( values_int8 )
  10281. case ( DFNT_FLOAT32 )
  10282. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10283. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  10284. values = int(values_real4,kind=2)
  10285. deallocate( values_real4 )
  10286. case ( DFNT_FLOAT64 )
  10287. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  10288. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  10289. values = int(values_real8,kind=2)
  10290. deallocate( values_real8 )
  10291. case default
  10292. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  10293. TRACEBACK; status=1; return
  10294. end select
  10295. if ( status == FAIL ) then
  10296. write (gol,'("reading hdf4 data set:")'); call goErr
  10297. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  10298. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  10299. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  10300. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  10301. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  10302. write (gol,'(" size : ",i6)') size(values); call goErr
  10303. TRACEBACK; status=1; return
  10304. end if
  10305. #endif
  10306. #ifdef with_netcdf
  10307. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10308. case ( MDF_NETCDF, MDF_NETCDF4 )
  10309. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10310. ! read values, converted automatically:
  10311. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  10312. start, count, stride, map )
  10313. IF_NF90_NOT_OK_RETURN(status=1)
  10314. #endif
  10315. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10316. case default
  10317. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10318. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  10319. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  10320. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  10321. TRACEBACK; status=1; return
  10322. end select
  10323. end do ! file types
  10324. ! ok
  10325. status = 0
  10326. end subroutine MDF_Get_Var_i2_4d
  10327. ! ***
  10328. subroutine MDF_Put_Var_i2_5d( hid, varid, values, status, &
  10329. start, count, stride, map )
  10330. #ifdef with_hdf5_beta
  10331. use HDF5, only : HID_T, HSIZE_T
  10332. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  10333. use HDF5, only : H5T_NATIVE_CHARACTER
  10334. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  10335. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  10336. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  10337. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  10338. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  10339. #endif
  10340. #ifdef with_netcdf
  10341. use NetCDF, only : NF90_Put_Var
  10342. #endif
  10343. ! --- in/out -------------------------------------
  10344. integer, intent(in) :: hid
  10345. integer, intent(in) :: varid
  10346. integer(2), intent(in) :: values(:,:,:,:,:)
  10347. integer, intent(out) :: status
  10348. integer, intent(in), optional :: start (:)
  10349. integer, intent(in), optional :: count (:)
  10350. integer, intent(in), optional :: stride(:)
  10351. integer, intent(in), optional :: map (:)
  10352. ! --- const --------------------------------------
  10353. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_5d'
  10354. ! --- external -----------------------------------
  10355. #ifdef with_hdf4
  10356. integer(hdf4_wpi), external :: sfWData
  10357. #endif
  10358. ! --- local --------------------------------------
  10359. type(MDF_File), pointer :: filep
  10360. type(MDF_Var), pointer :: varp
  10361. integer :: iftype
  10362. integer :: ftype
  10363. #ifdef with_hdf4
  10364. integer :: hdf4_offset(MAX_RANK)
  10365. integer :: hdf4_stride(MAX_RANK)
  10366. integer :: hdf4_count(MAX_RANK)
  10367. #endif
  10368. #ifdef with_hdf5_beta
  10369. !integer(HID_T) :: hdf5_type_id
  10370. integer(HID_T) :: hdf5_file_space_id
  10371. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  10372. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  10373. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  10374. #endif
  10375. integer(1), allocatable :: values_int1(:,:,:,:,:)
  10376. integer(2), allocatable :: values_int2(:,:,:,:,:)
  10377. integer(4), allocatable :: values_int4(:,:,:,:,:)
  10378. integer(8), allocatable :: values_int8(:,:,:,:,:)
  10379. real(4), allocatable :: values_real4(:,:,:,:,:)
  10380. real(8), allocatable :: values_real8(:,:,:,:,:)
  10381. ! --- begin --------------------------------------
  10382. ! pointer to file structure:
  10383. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  10384. IF_NOT_OK_RETURN(status=1)
  10385. ! pointer to variable structure:
  10386. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  10387. IF_NOT_OK_RETURN(status=1)
  10388. ! check ...
  10389. if ( size(shape(values)) > varp%ndim ) then
  10390. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  10391. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  10392. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  10393. TRACEBACK; status=1; return
  10394. end if
  10395. ! check ...
  10396. if ( present(start ) ) then
  10397. if ( size(start ) /= varp%ndim ) then
  10398. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10399. write (gol,'(" size start : ",i6)') size(start ); call goErr
  10400. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10401. TRACEBACK; status=1; return
  10402. end if
  10403. end if
  10404. if ( present(count ) ) then
  10405. if ( size(count ) /= varp%ndim ) then
  10406. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10407. write (gol,'(" size count : ",i6)') size(count ); call goErr
  10408. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10409. TRACEBACK; status=1; return
  10410. end if
  10411. end if
  10412. if ( present(stride ) ) then
  10413. if ( size(stride ) /= varp%ndim ) then
  10414. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10415. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  10416. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10417. TRACEBACK; status=1; return
  10418. end if
  10419. end if
  10420. if ( present(map ) ) then
  10421. if ( size(map ) /= varp%ndim ) then
  10422. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10423. write (gol,'(" size map : ",i6)') size(map ); call goErr
  10424. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10425. TRACEBACK; status=1; return
  10426. end if
  10427. end if
  10428. ! loop over file types:
  10429. do iftype = 1, filep%nftype
  10430. ! current type:
  10431. ftype = filep%ftypes(iftype)
  10432. ! select appropriate routine for each type:
  10433. select case ( ftype )
  10434. #ifdef with_hdf4
  10435. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10436. case ( MDF_HDF4 )
  10437. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10438. ! check ...
  10439. if ( present(map ) ) then
  10440. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  10441. TRACEBACK; status=1; return
  10442. end if
  10443. ! fill offset (zero based!) and stride with default values:
  10444. hdf4_offset = 0
  10445. hdf4_stride = 1
  10446. ! count is by default the shape; padd with singleton dimensions:
  10447. hdf4_count = 1; hdf4_count(1:5) = shape(values)
  10448. ! replace by optional arguments if necessary:
  10449. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  10450. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  10451. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  10452. ! test target type;
  10453. ! convert to required kind before entering sfWData,
  10454. ! otherwise segmentation faults on some machines ...
  10455. select case ( varp%xtype )
  10456. case ( MDF_BYTE )
  10457. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10458. values_int1 = int(values,kind=1)
  10459. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10460. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  10461. deallocate( values_int1 )
  10462. case ( MDF_SHORT )
  10463. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10464. values_int2 = int(values,kind=2)
  10465. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10466. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  10467. deallocate( values_int2 )
  10468. case ( MDF_INT )
  10469. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10470. values_int4 = int(values,kind=4)
  10471. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10472. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  10473. deallocate( values_int4 )
  10474. case ( MDF_FLOAT )
  10475. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10476. values_real4 = real(values,kind=4)
  10477. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10478. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  10479. deallocate( values_real4 )
  10480. case ( MDF_DOUBLE )
  10481. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10482. values_real8 = real(values,kind=8)
  10483. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10484. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  10485. deallocate( values_real8 )
  10486. case default
  10487. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  10488. TRACEBACK; status=1; return
  10489. end select
  10490. if ( status == FAIL ) then
  10491. write (gol,'("writing hdf4 data set:")'); call goErr
  10492. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  10493. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  10494. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  10495. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  10496. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  10497. write (gol,'(" size : ",i12)') size(values); call goErr
  10498. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  10499. TRACEBACK; status=1; return
  10500. end if
  10501. #endif
  10502. #ifdef with_hdf5_beta
  10503. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10504. case ( MDF_HDF5 )
  10505. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10506. ! check ...
  10507. if ( present(map ) ) then
  10508. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  10509. TRACEBACK; status=1; return
  10510. end if
  10511. ! fill offset (zero based!), stride, and count :
  10512. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  10513. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  10514. hdf5_count = 1 ! default singleton dimension
  10515. if ( present(count) ) then
  10516. hdf5_count(1:varp%ndim) = count
  10517. else
  10518. hdf5_count(1:5) = shape(values)
  10519. end if
  10520. ! new dimension:
  10521. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  10522. ! target data space in file:
  10523. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  10524. IF_NOT_OK_RETURN(status=1)
  10525. ! chunked dataset ?
  10526. if ( varp%hdf5_chunked ) then
  10527. ! reset extend:
  10528. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  10529. IF_NOT_OK_RETURN(status=1)
  10530. end if
  10531. ! select hyperslab:
  10532. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  10533. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  10534. stride=hdf5_stride(1:varp%ndim) )
  10535. ! write data:
  10536. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  10537. int(shape(values),kind=HSIZE_T), status, &
  10538. file_space_id=hdf5_file_space_id )
  10539. IF_NOT_OK_RETURN(status=1)
  10540. ! release data space:
  10541. call H5SClose_f( hdf5_file_space_id, status )
  10542. IF_NOT_OK_RETURN(status=1)
  10543. #endif
  10544. #ifdef with_netcdf
  10545. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10546. case ( MDF_NETCDF, MDF_NETCDF4 )
  10547. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10548. ! test target type:
  10549. ! convert to required kind before entering NF90_Put_Var,
  10550. ! otherwise segmentation faults on some machines ...
  10551. select case ( varp%xtype )
  10552. case ( MDF_BYTE )
  10553. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10554. values_int1 = int(values,kind=1)
  10555. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  10556. start, count, stride, map )
  10557. IF_NF90_NOT_OK_RETURN(status=1)
  10558. deallocate( values_int1 )
  10559. case ( MDF_SHORT )
  10560. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10561. values_int2 = int(values,kind=2)
  10562. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  10563. start, count, stride, map )
  10564. IF_NF90_NOT_OK_RETURN(status=1)
  10565. deallocate( values_int2 )
  10566. case ( MDF_INT )
  10567. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10568. values_int4 = int(values,kind=4)
  10569. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  10570. start, count, stride, map )
  10571. IF_NF90_NOT_OK_RETURN(status=1)
  10572. deallocate( values_int4 )
  10573. case ( MDF_FLOAT )
  10574. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10575. values_real4 = real(values,kind=4)
  10576. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  10577. start, count, stride, map )
  10578. IF_NF90_NOT_OK_RETURN(status=1)
  10579. deallocate( values_real4 )
  10580. case ( MDF_DOUBLE )
  10581. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10582. values_real8 = real(values,kind=8)
  10583. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  10584. start, count, stride, map )
  10585. IF_NF90_NOT_OK_RETURN(status=1)
  10586. deallocate( values_real8 )
  10587. case default
  10588. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  10589. TRACEBACK; status=1; return
  10590. end select
  10591. ! just put; let netcdf library convert the right kind:
  10592. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  10593. ! start, count, stride, map )
  10594. !IF_NF90_NOT_OK_RETURN(status=1)
  10595. #endif
  10596. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10597. case default
  10598. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10599. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  10600. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  10601. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  10602. TRACEBACK; status=1; return
  10603. end select
  10604. end do ! file types
  10605. ! ok
  10606. status = 0
  10607. end subroutine MDF_Put_Var_i2_5d
  10608. ! ***
  10609. subroutine MDF_Get_Var_i2_5d( hid, varid, values, status, &
  10610. start, count, stride, map )
  10611. #ifdef with_netcdf
  10612. use NetCDF, only : NF90_Get_Var
  10613. #endif
  10614. ! --- in/out -------------------------------------
  10615. integer, intent(in) :: hid
  10616. integer, intent(in) :: varid
  10617. integer(2), intent(out) :: values(:,:,:,:,:)
  10618. integer, intent(out) :: status
  10619. integer, intent(in), optional :: start (:)
  10620. integer, intent(in), optional :: count (:)
  10621. integer, intent(in), optional :: stride(:)
  10622. integer, intent(in), optional :: map (:)
  10623. ! --- const --------------------------------------
  10624. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_5d'
  10625. ! --- external -----------------------------------
  10626. #ifdef with_hdf4
  10627. integer(hdf4_wpi), external :: sfRData
  10628. #endif
  10629. ! --- local --------------------------------------
  10630. type(MDF_File), pointer :: filep
  10631. type(MDF_Var), pointer :: varp
  10632. integer :: iftype
  10633. integer :: ftype
  10634. #ifdef with_hdf4
  10635. integer :: hdf4_offset(MAX_RANK)
  10636. integer :: hdf4_stride(MAX_RANK)
  10637. integer :: hdf4_count(MAX_RANK)
  10638. integer(1), allocatable :: values_int1(:,:,:,:,:)
  10639. integer(2), allocatable :: values_int2(:,:,:,:,:)
  10640. integer(4), allocatable :: values_int4(:,:,:,:,:)
  10641. integer(8), allocatable :: values_int8(:,:,:,:,:)
  10642. real(4), allocatable :: values_real4(:,:,:,:,:)
  10643. real(8), allocatable :: values_real8(:,:,:,:,:)
  10644. #endif
  10645. ! --- begin --------------------------------------
  10646. ! pointer to file structure:
  10647. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  10648. IF_NOT_OK_RETURN(status=1)
  10649. ! pointer to variable structure:
  10650. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  10651. IF_NOT_OK_RETURN(status=1)
  10652. ! check ...
  10653. if ( size(shape(values)) > varp%ndim ) then
  10654. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  10655. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  10656. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  10657. TRACEBACK; status=1; return
  10658. end if
  10659. ! check ...
  10660. if ( present(start ) ) then
  10661. if ( size(start ) /= varp%ndim ) then
  10662. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10663. write (gol,'(" size start : ",i6)') size(start ); call goErr
  10664. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10665. TRACEBACK; status=1; return
  10666. end if
  10667. end if
  10668. if ( present(count ) ) then
  10669. if ( size(count ) /= varp%ndim ) then
  10670. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10671. write (gol,'(" size count : ",i6)') size(count ); call goErr
  10672. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10673. TRACEBACK; status=1; return
  10674. end if
  10675. end if
  10676. if ( present(stride ) ) then
  10677. if ( size(stride ) /= varp%ndim ) then
  10678. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10679. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  10680. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10681. TRACEBACK; status=1; return
  10682. end if
  10683. end if
  10684. if ( present(map ) ) then
  10685. if ( size(map ) /= varp%ndim ) then
  10686. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10687. write (gol,'(" size map : ",i6)') size(map ); call goErr
  10688. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10689. TRACEBACK; status=1; return
  10690. end if
  10691. end if
  10692. ! loop over file types:
  10693. do iftype = 1, filep%nftype
  10694. ! current type:
  10695. ftype = filep%ftypes(iftype)
  10696. ! select appropriate routine for each type:
  10697. select case ( ftype )
  10698. #ifdef with_hdf4
  10699. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10700. case ( MDF_HDF4 )
  10701. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10702. ! check ...
  10703. if ( present(map ) ) then
  10704. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  10705. TRACEBACK; status=1; return
  10706. end if
  10707. ! fill offset (zero based!), stride, and count :
  10708. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  10709. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  10710. hdf4_count = 1 ! default singleton dimension
  10711. hdf4_count(1:5) = shape(values)
  10712. ! test source type:
  10713. select case ( varp%hdf4_xtype )
  10714. case ( DFNT_INT8 )
  10715. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10716. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  10717. values = int(values_int1,kind=2)
  10718. deallocate( values_int1 )
  10719. case ( DFNT_INT16 )
  10720. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10721. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  10722. values = int(values_int2,kind=2)
  10723. deallocate( values_int2 )
  10724. case ( DFNT_INT32 )
  10725. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10726. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  10727. values = int(values_int4,kind=2)
  10728. deallocate( values_int4 )
  10729. case ( DFNT_INT64 )
  10730. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10731. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  10732. values = int(values_int8,kind=2)
  10733. deallocate( values_int8 )
  10734. case ( DFNT_FLOAT32 )
  10735. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10736. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  10737. values = int(values_real4,kind=2)
  10738. deallocate( values_real4 )
  10739. case ( DFNT_FLOAT64 )
  10740. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  10741. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  10742. values = int(values_real8,kind=2)
  10743. deallocate( values_real8 )
  10744. case default
  10745. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  10746. TRACEBACK; status=1; return
  10747. end select
  10748. if ( status == FAIL ) then
  10749. write (gol,'("reading hdf4 data set:")'); call goErr
  10750. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  10751. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  10752. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  10753. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  10754. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  10755. write (gol,'(" size : ",i6)') size(values); call goErr
  10756. TRACEBACK; status=1; return
  10757. end if
  10758. #endif
  10759. #ifdef with_netcdf
  10760. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10761. case ( MDF_NETCDF, MDF_NETCDF4 )
  10762. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10763. ! read values, converted automatically:
  10764. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  10765. start, count, stride, map )
  10766. IF_NF90_NOT_OK_RETURN(status=1)
  10767. #endif
  10768. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10769. case default
  10770. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10771. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  10772. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  10773. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  10774. TRACEBACK; status=1; return
  10775. end select
  10776. end do ! file types
  10777. ! ok
  10778. status = 0
  10779. end subroutine MDF_Get_Var_i2_5d
  10780. ! ***
  10781. subroutine MDF_Put_Var_i2_6d( hid, varid, values, status, &
  10782. start, count, stride, map )
  10783. #ifdef with_hdf5_beta
  10784. use HDF5, only : HID_T, HSIZE_T
  10785. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  10786. use HDF5, only : H5T_NATIVE_CHARACTER
  10787. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  10788. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  10789. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  10790. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  10791. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  10792. #endif
  10793. #ifdef with_netcdf
  10794. use NetCDF, only : NF90_Put_Var
  10795. #endif
  10796. ! --- in/out -------------------------------------
  10797. integer, intent(in) :: hid
  10798. integer, intent(in) :: varid
  10799. integer(2), intent(in) :: values(:,:,:,:,:,:)
  10800. integer, intent(out) :: status
  10801. integer, intent(in), optional :: start (:)
  10802. integer, intent(in), optional :: count (:)
  10803. integer, intent(in), optional :: stride(:)
  10804. integer, intent(in), optional :: map (:)
  10805. ! --- const --------------------------------------
  10806. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_6d'
  10807. ! --- external -----------------------------------
  10808. #ifdef with_hdf4
  10809. integer(hdf4_wpi), external :: sfWData
  10810. #endif
  10811. ! --- local --------------------------------------
  10812. type(MDF_File), pointer :: filep
  10813. type(MDF_Var), pointer :: varp
  10814. integer :: iftype
  10815. integer :: ftype
  10816. #ifdef with_hdf4
  10817. integer :: hdf4_offset(MAX_RANK)
  10818. integer :: hdf4_stride(MAX_RANK)
  10819. integer :: hdf4_count(MAX_RANK)
  10820. #endif
  10821. #ifdef with_hdf5_beta
  10822. !integer(HID_T) :: hdf5_type_id
  10823. integer(HID_T) :: hdf5_file_space_id
  10824. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  10825. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  10826. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  10827. #endif
  10828. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  10829. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  10830. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  10831. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  10832. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  10833. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  10834. ! --- begin --------------------------------------
  10835. ! pointer to file structure:
  10836. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  10837. IF_NOT_OK_RETURN(status=1)
  10838. ! pointer to variable structure:
  10839. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  10840. IF_NOT_OK_RETURN(status=1)
  10841. ! check ...
  10842. if ( size(shape(values)) > varp%ndim ) then
  10843. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  10844. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  10845. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  10846. TRACEBACK; status=1; return
  10847. end if
  10848. ! check ...
  10849. if ( present(start ) ) then
  10850. if ( size(start ) /= varp%ndim ) then
  10851. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10852. write (gol,'(" size start : ",i6)') size(start ); call goErr
  10853. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10854. TRACEBACK; status=1; return
  10855. end if
  10856. end if
  10857. if ( present(count ) ) then
  10858. if ( size(count ) /= varp%ndim ) then
  10859. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10860. write (gol,'(" size count : ",i6)') size(count ); call goErr
  10861. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10862. TRACEBACK; status=1; return
  10863. end if
  10864. end if
  10865. if ( present(stride ) ) then
  10866. if ( size(stride ) /= varp%ndim ) then
  10867. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10868. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  10869. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10870. TRACEBACK; status=1; return
  10871. end if
  10872. end if
  10873. if ( present(map ) ) then
  10874. if ( size(map ) /= varp%ndim ) then
  10875. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  10876. write (gol,'(" size map : ",i6)') size(map ); call goErr
  10877. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  10878. TRACEBACK; status=1; return
  10879. end if
  10880. end if
  10881. ! loop over file types:
  10882. do iftype = 1, filep%nftype
  10883. ! current type:
  10884. ftype = filep%ftypes(iftype)
  10885. ! select appropriate routine for each type:
  10886. select case ( ftype )
  10887. #ifdef with_hdf4
  10888. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10889. case ( MDF_HDF4 )
  10890. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10891. ! check ...
  10892. if ( present(map ) ) then
  10893. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  10894. TRACEBACK; status=1; return
  10895. end if
  10896. ! fill offset (zero based!) and stride with default values:
  10897. hdf4_offset = 0
  10898. hdf4_stride = 1
  10899. ! count is by default the shape; padd with singleton dimensions:
  10900. hdf4_count = 1; hdf4_count(1:6) = shape(values)
  10901. ! replace by optional arguments if necessary:
  10902. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  10903. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  10904. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  10905. ! test target type;
  10906. ! convert to required kind before entering sfWData,
  10907. ! otherwise segmentation faults on some machines ...
  10908. select case ( varp%xtype )
  10909. case ( MDF_BYTE )
  10910. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  10911. values_int1 = int(values,kind=1)
  10912. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10913. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  10914. deallocate( values_int1 )
  10915. case ( MDF_SHORT )
  10916. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  10917. values_int2 = int(values,kind=2)
  10918. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10919. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  10920. deallocate( values_int2 )
  10921. case ( MDF_INT )
  10922. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  10923. values_int4 = int(values,kind=4)
  10924. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10925. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  10926. deallocate( values_int4 )
  10927. case ( MDF_FLOAT )
  10928. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  10929. values_real4 = real(values,kind=4)
  10930. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10931. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  10932. deallocate( values_real4 )
  10933. case ( MDF_DOUBLE )
  10934. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  10935. values_real8 = real(values,kind=8)
  10936. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  10937. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  10938. deallocate( values_real8 )
  10939. case default
  10940. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  10941. TRACEBACK; status=1; return
  10942. end select
  10943. if ( status == FAIL ) then
  10944. write (gol,'("writing hdf4 data set:")'); call goErr
  10945. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  10946. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  10947. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  10948. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  10949. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  10950. write (gol,'(" size : ",i12)') size(values); call goErr
  10951. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  10952. TRACEBACK; status=1; return
  10953. end if
  10954. #endif
  10955. #ifdef with_hdf5_beta
  10956. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10957. case ( MDF_HDF5 )
  10958. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10959. ! check ...
  10960. if ( present(map ) ) then
  10961. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  10962. TRACEBACK; status=1; return
  10963. end if
  10964. ! fill offset (zero based!), stride, and count :
  10965. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  10966. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  10967. hdf5_count = 1 ! default singleton dimension
  10968. if ( present(count) ) then
  10969. hdf5_count(1:varp%ndim) = count
  10970. else
  10971. hdf5_count(1:6) = shape(values)
  10972. end if
  10973. ! new dimension:
  10974. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  10975. ! target data space in file:
  10976. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  10977. IF_NOT_OK_RETURN(status=1)
  10978. ! chunked dataset ?
  10979. if ( varp%hdf5_chunked ) then
  10980. ! reset extend:
  10981. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  10982. IF_NOT_OK_RETURN(status=1)
  10983. end if
  10984. ! select hyperslab:
  10985. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  10986. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  10987. stride=hdf5_stride(1:varp%ndim) )
  10988. ! write data:
  10989. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  10990. int(shape(values),kind=HSIZE_T), status, &
  10991. file_space_id=hdf5_file_space_id )
  10992. IF_NOT_OK_RETURN(status=1)
  10993. ! release data space:
  10994. call H5SClose_f( hdf5_file_space_id, status )
  10995. IF_NOT_OK_RETURN(status=1)
  10996. #endif
  10997. #ifdef with_netcdf
  10998. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  10999. case ( MDF_NETCDF, MDF_NETCDF4 )
  11000. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11001. ! test target type:
  11002. ! convert to required kind before entering NF90_Put_Var,
  11003. ! otherwise segmentation faults on some machines ...
  11004. select case ( varp%xtype )
  11005. case ( MDF_BYTE )
  11006. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11007. values_int1 = int(values,kind=1)
  11008. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  11009. start, count, stride, map )
  11010. IF_NF90_NOT_OK_RETURN(status=1)
  11011. deallocate( values_int1 )
  11012. case ( MDF_SHORT )
  11013. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11014. values_int2 = int(values,kind=2)
  11015. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  11016. start, count, stride, map )
  11017. IF_NF90_NOT_OK_RETURN(status=1)
  11018. deallocate( values_int2 )
  11019. case ( MDF_INT )
  11020. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11021. values_int4 = int(values,kind=4)
  11022. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  11023. start, count, stride, map )
  11024. IF_NF90_NOT_OK_RETURN(status=1)
  11025. deallocate( values_int4 )
  11026. case ( MDF_FLOAT )
  11027. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11028. values_real4 = real(values,kind=4)
  11029. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  11030. start, count, stride, map )
  11031. IF_NF90_NOT_OK_RETURN(status=1)
  11032. deallocate( values_real4 )
  11033. case ( MDF_DOUBLE )
  11034. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11035. values_real8 = real(values,kind=8)
  11036. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  11037. start, count, stride, map )
  11038. IF_NF90_NOT_OK_RETURN(status=1)
  11039. deallocate( values_real8 )
  11040. case default
  11041. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  11042. TRACEBACK; status=1; return
  11043. end select
  11044. ! just put; let netcdf library convert the right kind:
  11045. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  11046. ! start, count, stride, map )
  11047. !IF_NF90_NOT_OK_RETURN(status=1)
  11048. #endif
  11049. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11050. case default
  11051. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11052. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  11053. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  11054. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  11055. TRACEBACK; status=1; return
  11056. end select
  11057. end do ! file types
  11058. ! ok
  11059. status = 0
  11060. end subroutine MDF_Put_Var_i2_6d
  11061. ! ***
  11062. subroutine MDF_Get_Var_i2_6d( hid, varid, values, status, &
  11063. start, count, stride, map )
  11064. #ifdef with_netcdf
  11065. use NetCDF, only : NF90_Get_Var
  11066. #endif
  11067. ! --- in/out -------------------------------------
  11068. integer, intent(in) :: hid
  11069. integer, intent(in) :: varid
  11070. integer(2), intent(out) :: values(:,:,:,:,:,:)
  11071. integer, intent(out) :: status
  11072. integer, intent(in), optional :: start (:)
  11073. integer, intent(in), optional :: count (:)
  11074. integer, intent(in), optional :: stride(:)
  11075. integer, intent(in), optional :: map (:)
  11076. ! --- const --------------------------------------
  11077. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_6d'
  11078. ! --- external -----------------------------------
  11079. #ifdef with_hdf4
  11080. integer(hdf4_wpi), external :: sfRData
  11081. #endif
  11082. ! --- local --------------------------------------
  11083. type(MDF_File), pointer :: filep
  11084. type(MDF_Var), pointer :: varp
  11085. integer :: iftype
  11086. integer :: ftype
  11087. #ifdef with_hdf4
  11088. integer :: hdf4_offset(MAX_RANK)
  11089. integer :: hdf4_stride(MAX_RANK)
  11090. integer :: hdf4_count(MAX_RANK)
  11091. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  11092. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  11093. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  11094. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  11095. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  11096. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  11097. #endif
  11098. ! --- begin --------------------------------------
  11099. ! pointer to file structure:
  11100. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  11101. IF_NOT_OK_RETURN(status=1)
  11102. ! pointer to variable structure:
  11103. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  11104. IF_NOT_OK_RETURN(status=1)
  11105. ! check ...
  11106. if ( size(shape(values)) > varp%ndim ) then
  11107. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  11108. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  11109. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  11110. TRACEBACK; status=1; return
  11111. end if
  11112. ! check ...
  11113. if ( present(start ) ) then
  11114. if ( size(start ) /= varp%ndim ) then
  11115. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11116. write (gol,'(" size start : ",i6)') size(start ); call goErr
  11117. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11118. TRACEBACK; status=1; return
  11119. end if
  11120. end if
  11121. if ( present(count ) ) then
  11122. if ( size(count ) /= varp%ndim ) then
  11123. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11124. write (gol,'(" size count : ",i6)') size(count ); call goErr
  11125. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11126. TRACEBACK; status=1; return
  11127. end if
  11128. end if
  11129. if ( present(stride ) ) then
  11130. if ( size(stride ) /= varp%ndim ) then
  11131. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11132. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  11133. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11134. TRACEBACK; status=1; return
  11135. end if
  11136. end if
  11137. if ( present(map ) ) then
  11138. if ( size(map ) /= varp%ndim ) then
  11139. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11140. write (gol,'(" size map : ",i6)') size(map ); call goErr
  11141. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11142. TRACEBACK; status=1; return
  11143. end if
  11144. end if
  11145. ! loop over file types:
  11146. do iftype = 1, filep%nftype
  11147. ! current type:
  11148. ftype = filep%ftypes(iftype)
  11149. ! select appropriate routine for each type:
  11150. select case ( ftype )
  11151. #ifdef with_hdf4
  11152. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11153. case ( MDF_HDF4 )
  11154. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11155. ! check ...
  11156. if ( present(map ) ) then
  11157. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  11158. TRACEBACK; status=1; return
  11159. end if
  11160. ! fill offset (zero based!), stride, and count :
  11161. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  11162. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  11163. hdf4_count = 1 ! default singleton dimension
  11164. hdf4_count(1:6) = shape(values)
  11165. ! test source type:
  11166. select case ( varp%hdf4_xtype )
  11167. case ( DFNT_INT8 )
  11168. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11169. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  11170. values = int(values_int1,kind=2)
  11171. deallocate( values_int1 )
  11172. case ( DFNT_INT16 )
  11173. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11174. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  11175. values = int(values_int2,kind=2)
  11176. deallocate( values_int2 )
  11177. case ( DFNT_INT32 )
  11178. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11179. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  11180. values = int(values_int4,kind=2)
  11181. deallocate( values_int4 )
  11182. case ( DFNT_INT64 )
  11183. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11184. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  11185. values = int(values_int8,kind=2)
  11186. deallocate( values_int8 )
  11187. case ( DFNT_FLOAT32 )
  11188. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11189. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  11190. values = int(values_real4,kind=2)
  11191. deallocate( values_real4 )
  11192. case ( DFNT_FLOAT64 )
  11193. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  11194. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  11195. values = int(values_real8,kind=2)
  11196. deallocate( values_real8 )
  11197. case default
  11198. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  11199. TRACEBACK; status=1; return
  11200. end select
  11201. if ( status == FAIL ) then
  11202. write (gol,'("reading hdf4 data set:")'); call goErr
  11203. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  11204. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  11205. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  11206. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  11207. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  11208. write (gol,'(" size : ",i6)') size(values); call goErr
  11209. TRACEBACK; status=1; return
  11210. end if
  11211. #endif
  11212. #ifdef with_netcdf
  11213. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11214. case ( MDF_NETCDF, MDF_NETCDF4 )
  11215. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11216. ! read values, converted automatically:
  11217. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  11218. start, count, stride, map )
  11219. IF_NF90_NOT_OK_RETURN(status=1)
  11220. #endif
  11221. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11222. case default
  11223. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11224. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  11225. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  11226. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  11227. TRACEBACK; status=1; return
  11228. end select
  11229. end do ! file types
  11230. ! ok
  11231. status = 0
  11232. end subroutine MDF_Get_Var_i2_6d
  11233. ! ***
  11234. subroutine MDF_Put_Var_i2_7d( hid, varid, values, status, &
  11235. start, count, stride, map )
  11236. #ifdef with_hdf5_beta
  11237. use HDF5, only : HID_T, HSIZE_T
  11238. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  11239. use HDF5, only : H5T_NATIVE_CHARACTER
  11240. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  11241. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  11242. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  11243. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  11244. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  11245. #endif
  11246. #ifdef with_netcdf
  11247. use NetCDF, only : NF90_Put_Var
  11248. #endif
  11249. ! --- in/out -------------------------------------
  11250. integer, intent(in) :: hid
  11251. integer, intent(in) :: varid
  11252. integer(2), intent(in) :: values(:,:,:,:,:,:,:)
  11253. integer, intent(out) :: status
  11254. integer, intent(in), optional :: start (:)
  11255. integer, intent(in), optional :: count (:)
  11256. integer, intent(in), optional :: stride(:)
  11257. integer, intent(in), optional :: map (:)
  11258. ! --- const --------------------------------------
  11259. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i2_7d'
  11260. ! --- external -----------------------------------
  11261. #ifdef with_hdf4
  11262. integer(hdf4_wpi), external :: sfWData
  11263. #endif
  11264. ! --- local --------------------------------------
  11265. type(MDF_File), pointer :: filep
  11266. type(MDF_Var), pointer :: varp
  11267. integer :: iftype
  11268. integer :: ftype
  11269. #ifdef with_hdf4
  11270. integer :: hdf4_offset(MAX_RANK)
  11271. integer :: hdf4_stride(MAX_RANK)
  11272. integer :: hdf4_count(MAX_RANK)
  11273. #endif
  11274. #ifdef with_hdf5_beta
  11275. !integer(HID_T) :: hdf5_type_id
  11276. integer(HID_T) :: hdf5_file_space_id
  11277. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  11278. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  11279. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  11280. #endif
  11281. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  11282. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  11283. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  11284. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  11285. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  11286. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  11287. ! --- begin --------------------------------------
  11288. ! pointer to file structure:
  11289. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  11290. IF_NOT_OK_RETURN(status=1)
  11291. ! pointer to variable structure:
  11292. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  11293. IF_NOT_OK_RETURN(status=1)
  11294. ! check ...
  11295. if ( size(shape(values)) > varp%ndim ) then
  11296. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  11297. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  11298. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  11299. TRACEBACK; status=1; return
  11300. end if
  11301. ! check ...
  11302. if ( present(start ) ) then
  11303. if ( size(start ) /= varp%ndim ) then
  11304. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11305. write (gol,'(" size start : ",i6)') size(start ); call goErr
  11306. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11307. TRACEBACK; status=1; return
  11308. end if
  11309. end if
  11310. if ( present(count ) ) then
  11311. if ( size(count ) /= varp%ndim ) then
  11312. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11313. write (gol,'(" size count : ",i6)') size(count ); call goErr
  11314. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11315. TRACEBACK; status=1; return
  11316. end if
  11317. end if
  11318. if ( present(stride ) ) then
  11319. if ( size(stride ) /= varp%ndim ) then
  11320. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11321. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  11322. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11323. TRACEBACK; status=1; return
  11324. end if
  11325. end if
  11326. if ( present(map ) ) then
  11327. if ( size(map ) /= varp%ndim ) then
  11328. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11329. write (gol,'(" size map : ",i6)') size(map ); call goErr
  11330. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11331. TRACEBACK; status=1; return
  11332. end if
  11333. end if
  11334. ! loop over file types:
  11335. do iftype = 1, filep%nftype
  11336. ! current type:
  11337. ftype = filep%ftypes(iftype)
  11338. ! select appropriate routine for each type:
  11339. select case ( ftype )
  11340. #ifdef with_hdf4
  11341. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11342. case ( MDF_HDF4 )
  11343. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11344. ! check ...
  11345. if ( present(map ) ) then
  11346. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  11347. TRACEBACK; status=1; return
  11348. end if
  11349. ! fill offset (zero based!) and stride with default values:
  11350. hdf4_offset = 0
  11351. hdf4_stride = 1
  11352. ! count is by default the shape; padd with singleton dimensions:
  11353. hdf4_count = 1; hdf4_count(1:7) = shape(values)
  11354. ! replace by optional arguments if necessary:
  11355. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  11356. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  11357. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  11358. ! test target type;
  11359. ! convert to required kind before entering sfWData,
  11360. ! otherwise segmentation faults on some machines ...
  11361. select case ( varp%xtype )
  11362. case ( MDF_BYTE )
  11363. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11364. values_int1 = int(values,kind=1)
  11365. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11366. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  11367. deallocate( values_int1 )
  11368. case ( MDF_SHORT )
  11369. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11370. values_int2 = int(values,kind=2)
  11371. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11372. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  11373. deallocate( values_int2 )
  11374. case ( MDF_INT )
  11375. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11376. values_int4 = int(values,kind=4)
  11377. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11378. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  11379. deallocate( values_int4 )
  11380. case ( MDF_FLOAT )
  11381. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11382. values_real4 = real(values,kind=4)
  11383. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11384. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  11385. deallocate( values_real4 )
  11386. case ( MDF_DOUBLE )
  11387. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11388. values_real8 = real(values,kind=8)
  11389. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11390. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  11391. deallocate( values_real8 )
  11392. case default
  11393. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  11394. TRACEBACK; status=1; return
  11395. end select
  11396. if ( status == FAIL ) then
  11397. write (gol,'("writing hdf4 data set:")'); call goErr
  11398. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  11399. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  11400. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  11401. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  11402. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  11403. write (gol,'(" size : ",i12)') size(values); call goErr
  11404. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  11405. TRACEBACK; status=1; return
  11406. end if
  11407. #endif
  11408. #ifdef with_hdf5_beta
  11409. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11410. case ( MDF_HDF5 )
  11411. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11412. ! check ...
  11413. if ( present(map ) ) then
  11414. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  11415. TRACEBACK; status=1; return
  11416. end if
  11417. ! fill offset (zero based!), stride, and count :
  11418. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  11419. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  11420. hdf5_count = 1 ! default singleton dimension
  11421. if ( present(count) ) then
  11422. hdf5_count(1:varp%ndim) = count
  11423. else
  11424. hdf5_count(1:7) = shape(values)
  11425. end if
  11426. ! new dimension:
  11427. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  11428. ! target data space in file:
  11429. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  11430. IF_NOT_OK_RETURN(status=1)
  11431. ! chunked dataset ?
  11432. if ( varp%hdf5_chunked ) then
  11433. ! reset extend:
  11434. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  11435. IF_NOT_OK_RETURN(status=1)
  11436. end if
  11437. ! select hyperslab:
  11438. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  11439. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  11440. stride=hdf5_stride(1:varp%ndim) )
  11441. ! write data:
  11442. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, int(values), &
  11443. int(shape(values),kind=HSIZE_T), status, &
  11444. file_space_id=hdf5_file_space_id )
  11445. IF_NOT_OK_RETURN(status=1)
  11446. ! release data space:
  11447. call H5SClose_f( hdf5_file_space_id, status )
  11448. IF_NOT_OK_RETURN(status=1)
  11449. #endif
  11450. #ifdef with_netcdf
  11451. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11452. case ( MDF_NETCDF, MDF_NETCDF4 )
  11453. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11454. ! test target type:
  11455. ! convert to required kind before entering NF90_Put_Var,
  11456. ! otherwise segmentation faults on some machines ...
  11457. select case ( varp%xtype )
  11458. case ( MDF_BYTE )
  11459. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11460. values_int1 = int(values,kind=1)
  11461. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  11462. start, count, stride, map )
  11463. IF_NF90_NOT_OK_RETURN(status=1)
  11464. deallocate( values_int1 )
  11465. case ( MDF_SHORT )
  11466. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11467. values_int2 = int(values,kind=2)
  11468. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  11469. start, count, stride, map )
  11470. IF_NF90_NOT_OK_RETURN(status=1)
  11471. deallocate( values_int2 )
  11472. case ( MDF_INT )
  11473. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11474. values_int4 = int(values,kind=4)
  11475. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  11476. start, count, stride, map )
  11477. IF_NF90_NOT_OK_RETURN(status=1)
  11478. deallocate( values_int4 )
  11479. case ( MDF_FLOAT )
  11480. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11481. values_real4 = real(values,kind=4)
  11482. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  11483. start, count, stride, map )
  11484. IF_NF90_NOT_OK_RETURN(status=1)
  11485. deallocate( values_real4 )
  11486. case ( MDF_DOUBLE )
  11487. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11488. values_real8 = real(values,kind=8)
  11489. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  11490. start, count, stride, map )
  11491. IF_NF90_NOT_OK_RETURN(status=1)
  11492. deallocate( values_real8 )
  11493. case default
  11494. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  11495. TRACEBACK; status=1; return
  11496. end select
  11497. ! just put; let netcdf library convert the right kind:
  11498. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  11499. ! start, count, stride, map )
  11500. !IF_NF90_NOT_OK_RETURN(status=1)
  11501. #endif
  11502. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11503. case default
  11504. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11505. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  11506. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  11507. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  11508. TRACEBACK; status=1; return
  11509. end select
  11510. end do ! file types
  11511. ! ok
  11512. status = 0
  11513. end subroutine MDF_Put_Var_i2_7d
  11514. ! ***
  11515. subroutine MDF_Get_Var_i2_7d( hid, varid, values, status, &
  11516. start, count, stride, map )
  11517. #ifdef with_netcdf
  11518. use NetCDF, only : NF90_Get_Var
  11519. #endif
  11520. ! --- in/out -------------------------------------
  11521. integer, intent(in) :: hid
  11522. integer, intent(in) :: varid
  11523. integer(2), intent(out) :: values(:,:,:,:,:,:,:)
  11524. integer, intent(out) :: status
  11525. integer, intent(in), optional :: start (:)
  11526. integer, intent(in), optional :: count (:)
  11527. integer, intent(in), optional :: stride(:)
  11528. integer, intent(in), optional :: map (:)
  11529. ! --- const --------------------------------------
  11530. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i2_7d'
  11531. ! --- external -----------------------------------
  11532. #ifdef with_hdf4
  11533. integer(hdf4_wpi), external :: sfRData
  11534. #endif
  11535. ! --- local --------------------------------------
  11536. type(MDF_File), pointer :: filep
  11537. type(MDF_Var), pointer :: varp
  11538. integer :: iftype
  11539. integer :: ftype
  11540. #ifdef with_hdf4
  11541. integer :: hdf4_offset(MAX_RANK)
  11542. integer :: hdf4_stride(MAX_RANK)
  11543. integer :: hdf4_count(MAX_RANK)
  11544. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  11545. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  11546. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  11547. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  11548. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  11549. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  11550. #endif
  11551. ! --- begin --------------------------------------
  11552. ! pointer to file structure:
  11553. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  11554. IF_NOT_OK_RETURN(status=1)
  11555. ! pointer to variable structure:
  11556. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  11557. IF_NOT_OK_RETURN(status=1)
  11558. ! check ...
  11559. if ( size(shape(values)) > varp%ndim ) then
  11560. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  11561. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  11562. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  11563. TRACEBACK; status=1; return
  11564. end if
  11565. ! check ...
  11566. if ( present(start ) ) then
  11567. if ( size(start ) /= varp%ndim ) then
  11568. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11569. write (gol,'(" size start : ",i6)') size(start ); call goErr
  11570. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11571. TRACEBACK; status=1; return
  11572. end if
  11573. end if
  11574. if ( present(count ) ) then
  11575. if ( size(count ) /= varp%ndim ) then
  11576. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11577. write (gol,'(" size count : ",i6)') size(count ); call goErr
  11578. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11579. TRACEBACK; status=1; return
  11580. end if
  11581. end if
  11582. if ( present(stride ) ) then
  11583. if ( size(stride ) /= varp%ndim ) then
  11584. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11585. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  11586. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11587. TRACEBACK; status=1; return
  11588. end if
  11589. end if
  11590. if ( present(map ) ) then
  11591. if ( size(map ) /= varp%ndim ) then
  11592. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11593. write (gol,'(" size map : ",i6)') size(map ); call goErr
  11594. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11595. TRACEBACK; status=1; return
  11596. end if
  11597. end if
  11598. ! loop over file types:
  11599. do iftype = 1, filep%nftype
  11600. ! current type:
  11601. ftype = filep%ftypes(iftype)
  11602. ! select appropriate routine for each type:
  11603. select case ( ftype )
  11604. #ifdef with_hdf4
  11605. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11606. case ( MDF_HDF4 )
  11607. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11608. ! check ...
  11609. if ( present(map ) ) then
  11610. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  11611. TRACEBACK; status=1; return
  11612. end if
  11613. ! fill offset (zero based!), stride, and count :
  11614. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  11615. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  11616. hdf4_count = 1 ! default singleton dimension
  11617. hdf4_count(1:7) = shape(values)
  11618. ! test source type:
  11619. select case ( varp%hdf4_xtype )
  11620. case ( DFNT_INT8 )
  11621. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11622. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  11623. values = int(values_int1,kind=2)
  11624. deallocate( values_int1 )
  11625. case ( DFNT_INT16 )
  11626. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11627. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  11628. values = int(values_int2,kind=2)
  11629. deallocate( values_int2 )
  11630. case ( DFNT_INT32 )
  11631. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11632. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  11633. values = int(values_int4,kind=2)
  11634. deallocate( values_int4 )
  11635. case ( DFNT_INT64 )
  11636. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11637. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  11638. values = int(values_int8,kind=2)
  11639. deallocate( values_int8 )
  11640. case ( DFNT_FLOAT32 )
  11641. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11642. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  11643. values = int(values_real4,kind=2)
  11644. deallocate( values_real4 )
  11645. case ( DFNT_FLOAT64 )
  11646. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  11647. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  11648. values = int(values_real8,kind=2)
  11649. deallocate( values_real8 )
  11650. case default
  11651. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  11652. TRACEBACK; status=1; return
  11653. end select
  11654. if ( status == FAIL ) then
  11655. write (gol,'("reading hdf4 data set:")'); call goErr
  11656. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  11657. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  11658. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  11659. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  11660. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  11661. write (gol,'(" size : ",i6)') size(values); call goErr
  11662. TRACEBACK; status=1; return
  11663. end if
  11664. #endif
  11665. #ifdef with_netcdf
  11666. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11667. case ( MDF_NETCDF, MDF_NETCDF4 )
  11668. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11669. ! read values, converted automatically:
  11670. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  11671. start, count, stride, map )
  11672. IF_NF90_NOT_OK_RETURN(status=1)
  11673. #endif
  11674. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11675. case default
  11676. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11677. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  11678. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  11679. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  11680. TRACEBACK; status=1; return
  11681. end select
  11682. end do ! file types
  11683. ! ok
  11684. status = 0
  11685. end subroutine MDF_Get_Var_i2_7d
  11686. ! ***
  11687. subroutine MDF_Put_Var_i4_1d( hid, varid, values, status, &
  11688. start, count, stride, map )
  11689. #ifdef with_hdf5_beta
  11690. use HDF5, only : HID_T, HSIZE_T
  11691. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  11692. use HDF5, only : H5T_NATIVE_CHARACTER
  11693. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  11694. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  11695. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  11696. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  11697. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  11698. #endif
  11699. #ifdef with_netcdf
  11700. use NetCDF, only : NF90_Put_Var
  11701. #endif
  11702. ! --- in/out -------------------------------------
  11703. integer, intent(in) :: hid
  11704. integer, intent(in) :: varid
  11705. integer(4), intent(in) :: values(:)
  11706. integer, intent(out) :: status
  11707. integer, intent(in), optional :: start (:)
  11708. integer, intent(in), optional :: count (:)
  11709. integer, intent(in), optional :: stride(:)
  11710. integer, intent(in), optional :: map (:)
  11711. ! --- const --------------------------------------
  11712. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_1d'
  11713. ! --- external -----------------------------------
  11714. #ifdef with_hdf4
  11715. integer(hdf4_wpi), external :: sfWData
  11716. #endif
  11717. ! --- local --------------------------------------
  11718. type(MDF_File), pointer :: filep
  11719. type(MDF_Var), pointer :: varp
  11720. integer :: iftype
  11721. integer :: ftype
  11722. #ifdef with_hdf4
  11723. integer :: hdf4_offset(MAX_RANK)
  11724. integer :: hdf4_stride(MAX_RANK)
  11725. integer :: hdf4_count(MAX_RANK)
  11726. #endif
  11727. #ifdef with_hdf5_beta
  11728. !integer(HID_T) :: hdf5_type_id
  11729. integer(HID_T) :: hdf5_file_space_id
  11730. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  11731. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  11732. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  11733. #endif
  11734. integer(1), allocatable :: values_int1(:)
  11735. integer(2), allocatable :: values_int2(:)
  11736. integer(4), allocatable :: values_int4(:)
  11737. integer(8), allocatable :: values_int8(:)
  11738. real(4), allocatable :: values_real4(:)
  11739. real(8), allocatable :: values_real8(:)
  11740. ! --- begin --------------------------------------
  11741. ! pointer to file structure:
  11742. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  11743. IF_NOT_OK_RETURN(status=1)
  11744. ! pointer to variable structure:
  11745. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  11746. IF_NOT_OK_RETURN(status=1)
  11747. ! check ...
  11748. if ( size(shape(values)) > varp%ndim ) then
  11749. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  11750. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  11751. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  11752. TRACEBACK; status=1; return
  11753. end if
  11754. ! check ...
  11755. if ( present(start ) ) then
  11756. if ( size(start ) /= varp%ndim ) then
  11757. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11758. write (gol,'(" size start : ",i6)') size(start ); call goErr
  11759. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11760. TRACEBACK; status=1; return
  11761. end if
  11762. end if
  11763. if ( present(count ) ) then
  11764. if ( size(count ) /= varp%ndim ) then
  11765. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11766. write (gol,'(" size count : ",i6)') size(count ); call goErr
  11767. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11768. TRACEBACK; status=1; return
  11769. end if
  11770. end if
  11771. if ( present(stride ) ) then
  11772. if ( size(stride ) /= varp%ndim ) then
  11773. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11774. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  11775. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11776. TRACEBACK; status=1; return
  11777. end if
  11778. end if
  11779. if ( present(map ) ) then
  11780. if ( size(map ) /= varp%ndim ) then
  11781. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  11782. write (gol,'(" size map : ",i6)') size(map ); call goErr
  11783. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  11784. TRACEBACK; status=1; return
  11785. end if
  11786. end if
  11787. ! loop over file types:
  11788. do iftype = 1, filep%nftype
  11789. ! current type:
  11790. ftype = filep%ftypes(iftype)
  11791. ! select appropriate routine for each type:
  11792. select case ( ftype )
  11793. #ifdef with_hdf4
  11794. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11795. case ( MDF_HDF4 )
  11796. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11797. ! check ...
  11798. if ( present(map ) ) then
  11799. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  11800. TRACEBACK; status=1; return
  11801. end if
  11802. ! fill offset (zero based!) and stride with default values:
  11803. hdf4_offset = 0
  11804. hdf4_stride = 1
  11805. ! count is by default the shape; padd with singleton dimensions:
  11806. hdf4_count = 1; hdf4_count(1:1) = shape(values)
  11807. ! replace by optional arguments if necessary:
  11808. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  11809. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  11810. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  11811. ! test target type;
  11812. ! convert to required kind before entering sfWData,
  11813. ! otherwise segmentation faults on some machines ...
  11814. select case ( varp%xtype )
  11815. case ( MDF_BYTE )
  11816. allocate( values_int1(size(values,1)) )
  11817. values_int1 = int(values,kind=1)
  11818. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11819. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  11820. deallocate( values_int1 )
  11821. case ( MDF_SHORT )
  11822. allocate( values_int2(size(values,1)) )
  11823. values_int2 = int(values,kind=2)
  11824. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11825. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  11826. deallocate( values_int2 )
  11827. case ( MDF_INT )
  11828. allocate( values_int4(size(values,1)) )
  11829. values_int4 = int(values,kind=4)
  11830. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11831. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  11832. deallocate( values_int4 )
  11833. case ( MDF_FLOAT )
  11834. allocate( values_real4(size(values,1)) )
  11835. values_real4 = real(values,kind=4)
  11836. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11837. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  11838. deallocate( values_real4 )
  11839. case ( MDF_DOUBLE )
  11840. allocate( values_real8(size(values,1)) )
  11841. values_real8 = real(values,kind=8)
  11842. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  11843. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  11844. deallocate( values_real8 )
  11845. case default
  11846. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  11847. TRACEBACK; status=1; return
  11848. end select
  11849. if ( status == FAIL ) then
  11850. write (gol,'("writing hdf4 data set:")'); call goErr
  11851. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  11852. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  11853. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  11854. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  11855. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  11856. write (gol,'(" size : ",i12)') size(values); call goErr
  11857. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  11858. TRACEBACK; status=1; return
  11859. end if
  11860. #endif
  11861. #ifdef with_hdf5_beta
  11862. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11863. case ( MDF_HDF5 )
  11864. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11865. ! check ...
  11866. if ( present(map ) ) then
  11867. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  11868. TRACEBACK; status=1; return
  11869. end if
  11870. ! fill offset (zero based!), stride, and count :
  11871. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  11872. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  11873. hdf5_count = 1 ! default singleton dimension
  11874. if ( present(count) ) then
  11875. hdf5_count(1:varp%ndim) = count
  11876. else
  11877. hdf5_count(1:1) = shape(values)
  11878. end if
  11879. ! new dimension:
  11880. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  11881. ! target data space in file:
  11882. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  11883. IF_NOT_OK_RETURN(status=1)
  11884. ! chunked dataset ?
  11885. if ( varp%hdf5_chunked ) then
  11886. ! reset extend:
  11887. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  11888. IF_NOT_OK_RETURN(status=1)
  11889. end if
  11890. ! select hyperslab:
  11891. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  11892. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  11893. stride=hdf5_stride(1:varp%ndim) )
  11894. ! write data:
  11895. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  11896. int(shape(values),kind=HSIZE_T), status, &
  11897. file_space_id=hdf5_file_space_id )
  11898. IF_NOT_OK_RETURN(status=1)
  11899. ! release data space:
  11900. call H5SClose_f( hdf5_file_space_id, status )
  11901. IF_NOT_OK_RETURN(status=1)
  11902. #endif
  11903. #ifdef with_netcdf
  11904. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11905. case ( MDF_NETCDF, MDF_NETCDF4 )
  11906. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11907. ! test target type:
  11908. ! convert to required kind before entering NF90_Put_Var,
  11909. ! otherwise segmentation faults on some machines ...
  11910. select case ( varp%xtype )
  11911. case ( MDF_BYTE )
  11912. allocate( values_int1(size(values,1)) )
  11913. values_int1 = int(values,kind=1)
  11914. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  11915. start, count, stride, map )
  11916. IF_NF90_NOT_OK_RETURN(status=1)
  11917. deallocate( values_int1 )
  11918. case ( MDF_SHORT )
  11919. allocate( values_int2(size(values,1)) )
  11920. values_int2 = int(values,kind=2)
  11921. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  11922. start, count, stride, map )
  11923. IF_NF90_NOT_OK_RETURN(status=1)
  11924. deallocate( values_int2 )
  11925. case ( MDF_INT )
  11926. allocate( values_int4(size(values,1)) )
  11927. values_int4 = int(values,kind=4)
  11928. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  11929. start, count, stride, map )
  11930. IF_NF90_NOT_OK_RETURN(status=1)
  11931. deallocate( values_int4 )
  11932. case ( MDF_FLOAT )
  11933. allocate( values_real4(size(values,1)) )
  11934. values_real4 = real(values,kind=4)
  11935. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  11936. start, count, stride, map )
  11937. IF_NF90_NOT_OK_RETURN(status=1)
  11938. deallocate( values_real4 )
  11939. case ( MDF_DOUBLE )
  11940. allocate( values_real8(size(values,1)) )
  11941. values_real8 = real(values,kind=8)
  11942. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  11943. start, count, stride, map )
  11944. IF_NF90_NOT_OK_RETURN(status=1)
  11945. deallocate( values_real8 )
  11946. case default
  11947. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  11948. TRACEBACK; status=1; return
  11949. end select
  11950. ! just put; let netcdf library convert the right kind:
  11951. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  11952. ! start, count, stride, map )
  11953. !IF_NF90_NOT_OK_RETURN(status=1)
  11954. #endif
  11955. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11956. case default
  11957. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  11958. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  11959. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  11960. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  11961. TRACEBACK; status=1; return
  11962. end select
  11963. end do ! file types
  11964. ! ok
  11965. status = 0
  11966. end subroutine MDF_Put_Var_i4_1d
  11967. ! ***
  11968. subroutine MDF_Get_Var_i4_1d( hid, varid, values, status, &
  11969. start, count, stride, map )
  11970. #ifdef with_netcdf
  11971. use NetCDF, only : NF90_Get_Var
  11972. #endif
  11973. ! --- in/out -------------------------------------
  11974. integer, intent(in) :: hid
  11975. integer, intent(in) :: varid
  11976. integer(4), intent(out) :: values(:)
  11977. integer, intent(out) :: status
  11978. integer, intent(in), optional :: start (:)
  11979. integer, intent(in), optional :: count (:)
  11980. integer, intent(in), optional :: stride(:)
  11981. integer, intent(in), optional :: map (:)
  11982. ! --- const --------------------------------------
  11983. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_1d'
  11984. ! --- external -----------------------------------
  11985. #ifdef with_hdf4
  11986. integer(hdf4_wpi), external :: sfRData
  11987. #endif
  11988. ! --- local --------------------------------------
  11989. type(MDF_File), pointer :: filep
  11990. type(MDF_Var), pointer :: varp
  11991. integer :: iftype
  11992. integer :: ftype
  11993. #ifdef with_hdf4
  11994. integer :: hdf4_offset(MAX_RANK)
  11995. integer :: hdf4_stride(MAX_RANK)
  11996. integer :: hdf4_count(MAX_RANK)
  11997. integer(1), allocatable :: values_int1(:)
  11998. integer(2), allocatable :: values_int2(:)
  11999. integer(4), allocatable :: values_int4(:)
  12000. integer(8), allocatable :: values_int8(:)
  12001. real(4), allocatable :: values_real4(:)
  12002. real(8), allocatable :: values_real8(:)
  12003. #endif
  12004. ! --- begin --------------------------------------
  12005. ! pointer to file structure:
  12006. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  12007. IF_NOT_OK_RETURN(status=1)
  12008. ! pointer to variable structure:
  12009. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  12010. IF_NOT_OK_RETURN(status=1)
  12011. ! check ...
  12012. if ( size(shape(values)) > varp%ndim ) then
  12013. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  12014. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  12015. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  12016. TRACEBACK; status=1; return
  12017. end if
  12018. ! check ...
  12019. if ( present(start ) ) then
  12020. if ( size(start ) /= varp%ndim ) then
  12021. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12022. write (gol,'(" size start : ",i6)') size(start ); call goErr
  12023. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12024. TRACEBACK; status=1; return
  12025. end if
  12026. end if
  12027. if ( present(count ) ) then
  12028. if ( size(count ) /= varp%ndim ) then
  12029. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12030. write (gol,'(" size count : ",i6)') size(count ); call goErr
  12031. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12032. TRACEBACK; status=1; return
  12033. end if
  12034. end if
  12035. if ( present(stride ) ) then
  12036. if ( size(stride ) /= varp%ndim ) then
  12037. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12038. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  12039. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12040. TRACEBACK; status=1; return
  12041. end if
  12042. end if
  12043. if ( present(map ) ) then
  12044. if ( size(map ) /= varp%ndim ) then
  12045. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12046. write (gol,'(" size map : ",i6)') size(map ); call goErr
  12047. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12048. TRACEBACK; status=1; return
  12049. end if
  12050. end if
  12051. ! loop over file types:
  12052. do iftype = 1, filep%nftype
  12053. ! current type:
  12054. ftype = filep%ftypes(iftype)
  12055. ! select appropriate routine for each type:
  12056. select case ( ftype )
  12057. #ifdef with_hdf4
  12058. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12059. case ( MDF_HDF4 )
  12060. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12061. ! check ...
  12062. if ( present(map ) ) then
  12063. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  12064. TRACEBACK; status=1; return
  12065. end if
  12066. ! fill offset (zero based!), stride, and count :
  12067. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  12068. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  12069. hdf4_count = 1 ! default singleton dimension
  12070. hdf4_count(1:1) = shape(values)
  12071. ! test source type:
  12072. select case ( varp%hdf4_xtype )
  12073. case ( DFNT_INT8 )
  12074. allocate( values_int1(size(values,1)) )
  12075. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  12076. values = int(values_int1,kind=4)
  12077. deallocate( values_int1 )
  12078. case ( DFNT_INT16 )
  12079. allocate( values_int2(size(values,1)) )
  12080. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  12081. values = int(values_int2,kind=4)
  12082. deallocate( values_int2 )
  12083. case ( DFNT_INT32 )
  12084. allocate( values_int4(size(values,1)) )
  12085. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  12086. values = int(values_int4,kind=4)
  12087. deallocate( values_int4 )
  12088. case ( DFNT_INT64 )
  12089. allocate( values_int8(size(values,1)) )
  12090. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  12091. values = int(values_int8,kind=4)
  12092. deallocate( values_int8 )
  12093. case ( DFNT_FLOAT32 )
  12094. allocate( values_real4(size(values,1)) )
  12095. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  12096. values = int(values_real4,kind=4)
  12097. deallocate( values_real4 )
  12098. case ( DFNT_FLOAT64 )
  12099. allocate( values_real8(size(values,1)) )
  12100. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  12101. values = int(values_real8,kind=4)
  12102. deallocate( values_real8 )
  12103. case default
  12104. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  12105. TRACEBACK; status=1; return
  12106. end select
  12107. if ( status == FAIL ) then
  12108. write (gol,'("reading hdf4 data set:")'); call goErr
  12109. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  12110. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  12111. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  12112. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  12113. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  12114. write (gol,'(" size : ",i6)') size(values); call goErr
  12115. TRACEBACK; status=1; return
  12116. end if
  12117. #endif
  12118. #ifdef with_netcdf
  12119. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12120. case ( MDF_NETCDF, MDF_NETCDF4 )
  12121. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12122. ! read values, converted automatically:
  12123. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  12124. start, count, stride, map )
  12125. IF_NF90_NOT_OK_RETURN(status=1)
  12126. #endif
  12127. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12128. case default
  12129. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12130. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  12131. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  12132. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  12133. TRACEBACK; status=1; return
  12134. end select
  12135. end do ! file types
  12136. ! ok
  12137. status = 0
  12138. end subroutine MDF_Get_Var_i4_1d
  12139. ! ***
  12140. subroutine MDF_Put_Var_i4_2d( hid, varid, values, status, &
  12141. start, count, stride, map )
  12142. #ifdef with_hdf5_beta
  12143. use HDF5, only : HID_T, HSIZE_T
  12144. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  12145. use HDF5, only : H5T_NATIVE_CHARACTER
  12146. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  12147. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  12148. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  12149. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  12150. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  12151. #endif
  12152. #ifdef with_netcdf
  12153. use NetCDF, only : NF90_Put_Var
  12154. #endif
  12155. ! --- in/out -------------------------------------
  12156. integer, intent(in) :: hid
  12157. integer, intent(in) :: varid
  12158. integer(4), intent(in) :: values(:,:)
  12159. integer, intent(out) :: status
  12160. integer, intent(in), optional :: start (:)
  12161. integer, intent(in), optional :: count (:)
  12162. integer, intent(in), optional :: stride(:)
  12163. integer, intent(in), optional :: map (:)
  12164. ! --- const --------------------------------------
  12165. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_2d'
  12166. ! --- external -----------------------------------
  12167. #ifdef with_hdf4
  12168. integer(hdf4_wpi), external :: sfWData
  12169. #endif
  12170. ! --- local --------------------------------------
  12171. type(MDF_File), pointer :: filep
  12172. type(MDF_Var), pointer :: varp
  12173. integer :: iftype
  12174. integer :: ftype
  12175. #ifdef with_hdf4
  12176. integer :: hdf4_offset(MAX_RANK)
  12177. integer :: hdf4_stride(MAX_RANK)
  12178. integer :: hdf4_count(MAX_RANK)
  12179. #endif
  12180. #ifdef with_hdf5_beta
  12181. !integer(HID_T) :: hdf5_type_id
  12182. integer(HID_T) :: hdf5_file_space_id
  12183. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  12184. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  12185. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  12186. #endif
  12187. integer(1), allocatable :: values_int1(:,:)
  12188. integer(2), allocatable :: values_int2(:,:)
  12189. integer(4), allocatable :: values_int4(:,:)
  12190. integer(8), allocatable :: values_int8(:,:)
  12191. real(4), allocatable :: values_real4(:,:)
  12192. real(8), allocatable :: values_real8(:,:)
  12193. ! --- begin --------------------------------------
  12194. ! pointer to file structure:
  12195. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  12196. IF_NOT_OK_RETURN(status=1)
  12197. ! pointer to variable structure:
  12198. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  12199. IF_NOT_OK_RETURN(status=1)
  12200. ! check ...
  12201. if ( size(shape(values)) > varp%ndim ) then
  12202. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  12203. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  12204. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  12205. TRACEBACK; status=1; return
  12206. end if
  12207. ! check ...
  12208. if ( present(start ) ) then
  12209. if ( size(start ) /= varp%ndim ) then
  12210. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12211. write (gol,'(" size start : ",i6)') size(start ); call goErr
  12212. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12213. TRACEBACK; status=1; return
  12214. end if
  12215. end if
  12216. if ( present(count ) ) then
  12217. if ( size(count ) /= varp%ndim ) then
  12218. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12219. write (gol,'(" size count : ",i6)') size(count ); call goErr
  12220. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12221. TRACEBACK; status=1; return
  12222. end if
  12223. end if
  12224. if ( present(stride ) ) then
  12225. if ( size(stride ) /= varp%ndim ) then
  12226. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12227. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  12228. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12229. TRACEBACK; status=1; return
  12230. end if
  12231. end if
  12232. if ( present(map ) ) then
  12233. if ( size(map ) /= varp%ndim ) then
  12234. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12235. write (gol,'(" size map : ",i6)') size(map ); call goErr
  12236. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12237. TRACEBACK; status=1; return
  12238. end if
  12239. end if
  12240. ! loop over file types:
  12241. do iftype = 1, filep%nftype
  12242. ! current type:
  12243. ftype = filep%ftypes(iftype)
  12244. ! select appropriate routine for each type:
  12245. select case ( ftype )
  12246. #ifdef with_hdf4
  12247. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12248. case ( MDF_HDF4 )
  12249. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12250. ! check ...
  12251. if ( present(map ) ) then
  12252. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  12253. TRACEBACK; status=1; return
  12254. end if
  12255. ! fill offset (zero based!) and stride with default values:
  12256. hdf4_offset = 0
  12257. hdf4_stride = 1
  12258. ! count is by default the shape; padd with singleton dimensions:
  12259. hdf4_count = 1; hdf4_count(1:2) = shape(values)
  12260. ! replace by optional arguments if necessary:
  12261. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  12262. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  12263. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  12264. ! test target type;
  12265. ! convert to required kind before entering sfWData,
  12266. ! otherwise segmentation faults on some machines ...
  12267. select case ( varp%xtype )
  12268. case ( MDF_BYTE )
  12269. allocate( values_int1(size(values,1),size(values,2)) )
  12270. values_int1 = int(values,kind=1)
  12271. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12272. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  12273. deallocate( values_int1 )
  12274. case ( MDF_SHORT )
  12275. allocate( values_int2(size(values,1),size(values,2)) )
  12276. values_int2 = int(values,kind=2)
  12277. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12278. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  12279. deallocate( values_int2 )
  12280. case ( MDF_INT )
  12281. allocate( values_int4(size(values,1),size(values,2)) )
  12282. values_int4 = int(values,kind=4)
  12283. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12284. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  12285. deallocate( values_int4 )
  12286. case ( MDF_FLOAT )
  12287. allocate( values_real4(size(values,1),size(values,2)) )
  12288. values_real4 = real(values,kind=4)
  12289. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12290. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  12291. deallocate( values_real4 )
  12292. case ( MDF_DOUBLE )
  12293. allocate( values_real8(size(values,1),size(values,2)) )
  12294. values_real8 = real(values,kind=8)
  12295. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12296. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  12297. deallocate( values_real8 )
  12298. case default
  12299. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  12300. TRACEBACK; status=1; return
  12301. end select
  12302. if ( status == FAIL ) then
  12303. write (gol,'("writing hdf4 data set:")'); call goErr
  12304. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  12305. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  12306. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  12307. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  12308. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  12309. write (gol,'(" size : ",i12)') size(values); call goErr
  12310. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  12311. TRACEBACK; status=1; return
  12312. end if
  12313. #endif
  12314. #ifdef with_hdf5_beta
  12315. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12316. case ( MDF_HDF5 )
  12317. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12318. ! check ...
  12319. if ( present(map ) ) then
  12320. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  12321. TRACEBACK; status=1; return
  12322. end if
  12323. ! fill offset (zero based!), stride, and count :
  12324. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  12325. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  12326. hdf5_count = 1 ! default singleton dimension
  12327. if ( present(count) ) then
  12328. hdf5_count(1:varp%ndim) = count
  12329. else
  12330. hdf5_count(1:2) = shape(values)
  12331. end if
  12332. ! new dimension:
  12333. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  12334. ! target data space in file:
  12335. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  12336. IF_NOT_OK_RETURN(status=1)
  12337. ! chunked dataset ?
  12338. if ( varp%hdf5_chunked ) then
  12339. ! reset extend:
  12340. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  12341. IF_NOT_OK_RETURN(status=1)
  12342. end if
  12343. ! select hyperslab:
  12344. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  12345. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  12346. stride=hdf5_stride(1:varp%ndim) )
  12347. ! write data:
  12348. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  12349. int(shape(values),kind=HSIZE_T), status, &
  12350. file_space_id=hdf5_file_space_id )
  12351. IF_NOT_OK_RETURN(status=1)
  12352. ! release data space:
  12353. call H5SClose_f( hdf5_file_space_id, status )
  12354. IF_NOT_OK_RETURN(status=1)
  12355. #endif
  12356. #ifdef with_netcdf
  12357. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12358. case ( MDF_NETCDF, MDF_NETCDF4 )
  12359. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12360. ! test target type:
  12361. ! convert to required kind before entering NF90_Put_Var,
  12362. ! otherwise segmentation faults on some machines ...
  12363. select case ( varp%xtype )
  12364. case ( MDF_BYTE )
  12365. allocate( values_int1(size(values,1),size(values,2)) )
  12366. values_int1 = int(values,kind=1)
  12367. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  12368. start, count, stride, map )
  12369. IF_NF90_NOT_OK_RETURN(status=1)
  12370. deallocate( values_int1 )
  12371. case ( MDF_SHORT )
  12372. allocate( values_int2(size(values,1),size(values,2)) )
  12373. values_int2 = int(values,kind=2)
  12374. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  12375. start, count, stride, map )
  12376. IF_NF90_NOT_OK_RETURN(status=1)
  12377. deallocate( values_int2 )
  12378. case ( MDF_INT )
  12379. allocate( values_int4(size(values,1),size(values,2)) )
  12380. values_int4 = int(values,kind=4)
  12381. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  12382. start, count, stride, map )
  12383. IF_NF90_NOT_OK_RETURN(status=1)
  12384. deallocate( values_int4 )
  12385. case ( MDF_FLOAT )
  12386. allocate( values_real4(size(values,1),size(values,2)) )
  12387. values_real4 = real(values,kind=4)
  12388. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  12389. start, count, stride, map )
  12390. IF_NF90_NOT_OK_RETURN(status=1)
  12391. deallocate( values_real4 )
  12392. case ( MDF_DOUBLE )
  12393. allocate( values_real8(size(values,1),size(values,2)) )
  12394. values_real8 = real(values,kind=8)
  12395. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  12396. start, count, stride, map )
  12397. IF_NF90_NOT_OK_RETURN(status=1)
  12398. deallocate( values_real8 )
  12399. case default
  12400. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  12401. TRACEBACK; status=1; return
  12402. end select
  12403. ! just put; let netcdf library convert the right kind:
  12404. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  12405. ! start, count, stride, map )
  12406. !IF_NF90_NOT_OK_RETURN(status=1)
  12407. #endif
  12408. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12409. case default
  12410. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12411. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  12412. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  12413. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  12414. TRACEBACK; status=1; return
  12415. end select
  12416. end do ! file types
  12417. ! ok
  12418. status = 0
  12419. end subroutine MDF_Put_Var_i4_2d
  12420. ! ***
  12421. subroutine MDF_Get_Var_i4_2d( hid, varid, values, status, &
  12422. start, count, stride, map )
  12423. #ifdef with_netcdf
  12424. use NetCDF, only : NF90_Get_Var
  12425. #endif
  12426. ! --- in/out -------------------------------------
  12427. integer, intent(in) :: hid
  12428. integer, intent(in) :: varid
  12429. integer(4), intent(out) :: values(:,:)
  12430. integer, intent(out) :: status
  12431. integer, intent(in), optional :: start (:)
  12432. integer, intent(in), optional :: count (:)
  12433. integer, intent(in), optional :: stride(:)
  12434. integer, intent(in), optional :: map (:)
  12435. ! --- const --------------------------------------
  12436. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_2d'
  12437. ! --- external -----------------------------------
  12438. #ifdef with_hdf4
  12439. integer(hdf4_wpi), external :: sfRData
  12440. #endif
  12441. ! --- local --------------------------------------
  12442. type(MDF_File), pointer :: filep
  12443. type(MDF_Var), pointer :: varp
  12444. integer :: iftype
  12445. integer :: ftype
  12446. #ifdef with_hdf4
  12447. integer :: hdf4_offset(MAX_RANK)
  12448. integer :: hdf4_stride(MAX_RANK)
  12449. integer :: hdf4_count(MAX_RANK)
  12450. integer(1), allocatable :: values_int1(:,:)
  12451. integer(2), allocatable :: values_int2(:,:)
  12452. integer(4), allocatable :: values_int4(:,:)
  12453. integer(8), allocatable :: values_int8(:,:)
  12454. real(4), allocatable :: values_real4(:,:)
  12455. real(8), allocatable :: values_real8(:,:)
  12456. #endif
  12457. ! --- begin --------------------------------------
  12458. ! pointer to file structure:
  12459. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  12460. IF_NOT_OK_RETURN(status=1)
  12461. ! pointer to variable structure:
  12462. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  12463. IF_NOT_OK_RETURN(status=1)
  12464. ! check ...
  12465. if ( size(shape(values)) > varp%ndim ) then
  12466. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  12467. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  12468. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  12469. TRACEBACK; status=1; return
  12470. end if
  12471. ! check ...
  12472. if ( present(start ) ) then
  12473. if ( size(start ) /= varp%ndim ) then
  12474. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12475. write (gol,'(" size start : ",i6)') size(start ); call goErr
  12476. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12477. TRACEBACK; status=1; return
  12478. end if
  12479. end if
  12480. if ( present(count ) ) then
  12481. if ( size(count ) /= varp%ndim ) then
  12482. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12483. write (gol,'(" size count : ",i6)') size(count ); call goErr
  12484. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12485. TRACEBACK; status=1; return
  12486. end if
  12487. end if
  12488. if ( present(stride ) ) then
  12489. if ( size(stride ) /= varp%ndim ) then
  12490. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12491. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  12492. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12493. TRACEBACK; status=1; return
  12494. end if
  12495. end if
  12496. if ( present(map ) ) then
  12497. if ( size(map ) /= varp%ndim ) then
  12498. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12499. write (gol,'(" size map : ",i6)') size(map ); call goErr
  12500. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12501. TRACEBACK; status=1; return
  12502. end if
  12503. end if
  12504. ! loop over file types:
  12505. do iftype = 1, filep%nftype
  12506. ! current type:
  12507. ftype = filep%ftypes(iftype)
  12508. ! select appropriate routine for each type:
  12509. select case ( ftype )
  12510. #ifdef with_hdf4
  12511. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12512. case ( MDF_HDF4 )
  12513. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12514. ! check ...
  12515. if ( present(map ) ) then
  12516. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  12517. TRACEBACK; status=1; return
  12518. end if
  12519. ! fill offset (zero based!), stride, and count :
  12520. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  12521. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  12522. hdf4_count = 1 ! default singleton dimension
  12523. hdf4_count(1:2) = shape(values)
  12524. ! test source type:
  12525. select case ( varp%hdf4_xtype )
  12526. case ( DFNT_INT8 )
  12527. allocate( values_int1(size(values,1),size(values,2)) )
  12528. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  12529. values = int(values_int1,kind=4)
  12530. deallocate( values_int1 )
  12531. case ( DFNT_INT16 )
  12532. allocate( values_int2(size(values,1),size(values,2)) )
  12533. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  12534. values = int(values_int2,kind=4)
  12535. deallocate( values_int2 )
  12536. case ( DFNT_INT32 )
  12537. allocate( values_int4(size(values,1),size(values,2)) )
  12538. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  12539. values = int(values_int4,kind=4)
  12540. deallocate( values_int4 )
  12541. case ( DFNT_INT64 )
  12542. allocate( values_int8(size(values,1),size(values,2)) )
  12543. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  12544. values = int(values_int8,kind=4)
  12545. deallocate( values_int8 )
  12546. case ( DFNT_FLOAT32 )
  12547. allocate( values_real4(size(values,1),size(values,2)) )
  12548. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  12549. values = int(values_real4,kind=4)
  12550. deallocate( values_real4 )
  12551. case ( DFNT_FLOAT64 )
  12552. allocate( values_real8(size(values,1),size(values,2)) )
  12553. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  12554. values = int(values_real8,kind=4)
  12555. deallocate( values_real8 )
  12556. case default
  12557. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  12558. TRACEBACK; status=1; return
  12559. end select
  12560. if ( status == FAIL ) then
  12561. write (gol,'("reading hdf4 data set:")'); call goErr
  12562. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  12563. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  12564. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  12565. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  12566. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  12567. write (gol,'(" size : ",i6)') size(values); call goErr
  12568. TRACEBACK; status=1; return
  12569. end if
  12570. #endif
  12571. #ifdef with_netcdf
  12572. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12573. case ( MDF_NETCDF, MDF_NETCDF4 )
  12574. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12575. ! read values, converted automatically:
  12576. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  12577. start, count, stride, map )
  12578. IF_NF90_NOT_OK_RETURN(status=1)
  12579. #endif
  12580. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12581. case default
  12582. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12583. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  12584. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  12585. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  12586. TRACEBACK; status=1; return
  12587. end select
  12588. end do ! file types
  12589. ! ok
  12590. status = 0
  12591. end subroutine MDF_Get_Var_i4_2d
  12592. ! ***
  12593. subroutine MDF_Put_Var_i4_3d( hid, varid, values, status, &
  12594. start, count, stride, map )
  12595. #ifdef with_hdf5_beta
  12596. use HDF5, only : HID_T, HSIZE_T
  12597. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  12598. use HDF5, only : H5T_NATIVE_CHARACTER
  12599. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  12600. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  12601. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  12602. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  12603. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  12604. #endif
  12605. #ifdef with_netcdf
  12606. use NetCDF, only : NF90_Put_Var
  12607. #endif
  12608. ! --- in/out -------------------------------------
  12609. integer, intent(in) :: hid
  12610. integer, intent(in) :: varid
  12611. integer(4), intent(in) :: values(:,:,:)
  12612. integer, intent(out) :: status
  12613. integer, intent(in), optional :: start (:)
  12614. integer, intent(in), optional :: count (:)
  12615. integer, intent(in), optional :: stride(:)
  12616. integer, intent(in), optional :: map (:)
  12617. ! --- const --------------------------------------
  12618. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_3d'
  12619. ! --- external -----------------------------------
  12620. #ifdef with_hdf4
  12621. integer(hdf4_wpi), external :: sfWData
  12622. #endif
  12623. ! --- local --------------------------------------
  12624. type(MDF_File), pointer :: filep
  12625. type(MDF_Var), pointer :: varp
  12626. integer :: iftype
  12627. integer :: ftype
  12628. #ifdef with_hdf4
  12629. integer :: hdf4_offset(MAX_RANK)
  12630. integer :: hdf4_stride(MAX_RANK)
  12631. integer :: hdf4_count(MAX_RANK)
  12632. #endif
  12633. #ifdef with_hdf5_beta
  12634. !integer(HID_T) :: hdf5_type_id
  12635. integer(HID_T) :: hdf5_file_space_id
  12636. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  12637. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  12638. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  12639. #endif
  12640. integer(1), allocatable :: values_int1(:,:,:)
  12641. integer(2), allocatable :: values_int2(:,:,:)
  12642. integer(4), allocatable :: values_int4(:,:,:)
  12643. integer(8), allocatable :: values_int8(:,:,:)
  12644. real(4), allocatable :: values_real4(:,:,:)
  12645. real(8), allocatable :: values_real8(:,:,:)
  12646. ! --- begin --------------------------------------
  12647. ! pointer to file structure:
  12648. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  12649. IF_NOT_OK_RETURN(status=1)
  12650. ! pointer to variable structure:
  12651. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  12652. IF_NOT_OK_RETURN(status=1)
  12653. ! check ...
  12654. if ( size(shape(values)) > varp%ndim ) then
  12655. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  12656. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  12657. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  12658. TRACEBACK; status=1; return
  12659. end if
  12660. ! check ...
  12661. if ( present(start ) ) then
  12662. if ( size(start ) /= varp%ndim ) then
  12663. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12664. write (gol,'(" size start : ",i6)') size(start ); call goErr
  12665. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12666. TRACEBACK; status=1; return
  12667. end if
  12668. end if
  12669. if ( present(count ) ) then
  12670. if ( size(count ) /= varp%ndim ) then
  12671. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12672. write (gol,'(" size count : ",i6)') size(count ); call goErr
  12673. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12674. TRACEBACK; status=1; return
  12675. end if
  12676. end if
  12677. if ( present(stride ) ) then
  12678. if ( size(stride ) /= varp%ndim ) then
  12679. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12680. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  12681. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12682. TRACEBACK; status=1; return
  12683. end if
  12684. end if
  12685. if ( present(map ) ) then
  12686. if ( size(map ) /= varp%ndim ) then
  12687. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12688. write (gol,'(" size map : ",i6)') size(map ); call goErr
  12689. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12690. TRACEBACK; status=1; return
  12691. end if
  12692. end if
  12693. ! loop over file types:
  12694. do iftype = 1, filep%nftype
  12695. ! current type:
  12696. ftype = filep%ftypes(iftype)
  12697. ! select appropriate routine for each type:
  12698. select case ( ftype )
  12699. #ifdef with_hdf4
  12700. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12701. case ( MDF_HDF4 )
  12702. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12703. ! check ...
  12704. if ( present(map ) ) then
  12705. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  12706. TRACEBACK; status=1; return
  12707. end if
  12708. ! fill offset (zero based!) and stride with default values:
  12709. hdf4_offset = 0
  12710. hdf4_stride = 1
  12711. ! count is by default the shape; padd with singleton dimensions:
  12712. hdf4_count = 1; hdf4_count(1:3) = shape(values)
  12713. ! replace by optional arguments if necessary:
  12714. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  12715. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  12716. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  12717. ! test target type;
  12718. ! convert to required kind before entering sfWData,
  12719. ! otherwise segmentation faults on some machines ...
  12720. select case ( varp%xtype )
  12721. case ( MDF_BYTE )
  12722. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  12723. values_int1 = int(values,kind=1)
  12724. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12725. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  12726. deallocate( values_int1 )
  12727. case ( MDF_SHORT )
  12728. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  12729. values_int2 = int(values,kind=2)
  12730. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12731. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  12732. deallocate( values_int2 )
  12733. case ( MDF_INT )
  12734. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  12735. values_int4 = int(values,kind=4)
  12736. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12737. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  12738. deallocate( values_int4 )
  12739. case ( MDF_FLOAT )
  12740. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  12741. values_real4 = real(values,kind=4)
  12742. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12743. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  12744. deallocate( values_real4 )
  12745. case ( MDF_DOUBLE )
  12746. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  12747. values_real8 = real(values,kind=8)
  12748. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  12749. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  12750. deallocate( values_real8 )
  12751. case default
  12752. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  12753. TRACEBACK; status=1; return
  12754. end select
  12755. if ( status == FAIL ) then
  12756. write (gol,'("writing hdf4 data set:")'); call goErr
  12757. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  12758. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  12759. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  12760. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  12761. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  12762. write (gol,'(" size : ",i12)') size(values); call goErr
  12763. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  12764. TRACEBACK; status=1; return
  12765. end if
  12766. #endif
  12767. #ifdef with_hdf5_beta
  12768. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12769. case ( MDF_HDF5 )
  12770. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12771. ! check ...
  12772. if ( present(map ) ) then
  12773. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  12774. TRACEBACK; status=1; return
  12775. end if
  12776. ! fill offset (zero based!), stride, and count :
  12777. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  12778. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  12779. hdf5_count = 1 ! default singleton dimension
  12780. if ( present(count) ) then
  12781. hdf5_count(1:varp%ndim) = count
  12782. else
  12783. hdf5_count(1:3) = shape(values)
  12784. end if
  12785. ! new dimension:
  12786. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  12787. ! target data space in file:
  12788. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  12789. IF_NOT_OK_RETURN(status=1)
  12790. ! chunked dataset ?
  12791. if ( varp%hdf5_chunked ) then
  12792. ! reset extend:
  12793. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  12794. IF_NOT_OK_RETURN(status=1)
  12795. end if
  12796. ! select hyperslab:
  12797. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  12798. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  12799. stride=hdf5_stride(1:varp%ndim) )
  12800. ! write data:
  12801. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  12802. int(shape(values),kind=HSIZE_T), status, &
  12803. file_space_id=hdf5_file_space_id )
  12804. IF_NOT_OK_RETURN(status=1)
  12805. ! release data space:
  12806. call H5SClose_f( hdf5_file_space_id, status )
  12807. IF_NOT_OK_RETURN(status=1)
  12808. #endif
  12809. #ifdef with_netcdf
  12810. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12811. case ( MDF_NETCDF, MDF_NETCDF4 )
  12812. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12813. ! test target type:
  12814. ! convert to required kind before entering NF90_Put_Var,
  12815. ! otherwise segmentation faults on some machines ...
  12816. select case ( varp%xtype )
  12817. case ( MDF_BYTE )
  12818. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  12819. values_int1 = int(values,kind=1)
  12820. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  12821. start, count, stride, map )
  12822. IF_NF90_NOT_OK_RETURN(status=1)
  12823. deallocate( values_int1 )
  12824. case ( MDF_SHORT )
  12825. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  12826. values_int2 = int(values,kind=2)
  12827. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  12828. start, count, stride, map )
  12829. IF_NF90_NOT_OK_RETURN(status=1)
  12830. deallocate( values_int2 )
  12831. case ( MDF_INT )
  12832. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  12833. values_int4 = int(values,kind=4)
  12834. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  12835. start, count, stride, map )
  12836. IF_NF90_NOT_OK_RETURN(status=1)
  12837. deallocate( values_int4 )
  12838. case ( MDF_FLOAT )
  12839. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  12840. values_real4 = real(values,kind=4)
  12841. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  12842. start, count, stride, map )
  12843. IF_NF90_NOT_OK_RETURN(status=1)
  12844. deallocate( values_real4 )
  12845. case ( MDF_DOUBLE )
  12846. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  12847. values_real8 = real(values,kind=8)
  12848. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  12849. start, count, stride, map )
  12850. IF_NF90_NOT_OK_RETURN(status=1)
  12851. deallocate( values_real8 )
  12852. case default
  12853. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  12854. TRACEBACK; status=1; return
  12855. end select
  12856. ! just put; let netcdf library convert the right kind:
  12857. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  12858. ! start, count, stride, map )
  12859. !IF_NF90_NOT_OK_RETURN(status=1)
  12860. #endif
  12861. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12862. case default
  12863. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12864. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  12865. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  12866. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  12867. TRACEBACK; status=1; return
  12868. end select
  12869. end do ! file types
  12870. ! ok
  12871. status = 0
  12872. end subroutine MDF_Put_Var_i4_3d
  12873. ! ***
  12874. subroutine MDF_Get_Var_i4_3d( hid, varid, values, status, &
  12875. start, count, stride, map )
  12876. #ifdef with_netcdf
  12877. use NetCDF, only : NF90_Get_Var
  12878. #endif
  12879. ! --- in/out -------------------------------------
  12880. integer, intent(in) :: hid
  12881. integer, intent(in) :: varid
  12882. integer(4), intent(out) :: values(:,:,:)
  12883. integer, intent(out) :: status
  12884. integer, intent(in), optional :: start (:)
  12885. integer, intent(in), optional :: count (:)
  12886. integer, intent(in), optional :: stride(:)
  12887. integer, intent(in), optional :: map (:)
  12888. ! --- const --------------------------------------
  12889. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_3d'
  12890. ! --- external -----------------------------------
  12891. #ifdef with_hdf4
  12892. integer(hdf4_wpi), external :: sfRData
  12893. #endif
  12894. ! --- local --------------------------------------
  12895. type(MDF_File), pointer :: filep
  12896. type(MDF_Var), pointer :: varp
  12897. integer :: iftype
  12898. integer :: ftype
  12899. #ifdef with_hdf4
  12900. integer :: hdf4_offset(MAX_RANK)
  12901. integer :: hdf4_stride(MAX_RANK)
  12902. integer :: hdf4_count(MAX_RANK)
  12903. integer(1), allocatable :: values_int1(:,:,:)
  12904. integer(2), allocatable :: values_int2(:,:,:)
  12905. integer(4), allocatable :: values_int4(:,:,:)
  12906. integer(8), allocatable :: values_int8(:,:,:)
  12907. real(4), allocatable :: values_real4(:,:,:)
  12908. real(8), allocatable :: values_real8(:,:,:)
  12909. #endif
  12910. ! --- begin --------------------------------------
  12911. ! pointer to file structure:
  12912. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  12913. IF_NOT_OK_RETURN(status=1)
  12914. ! pointer to variable structure:
  12915. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  12916. IF_NOT_OK_RETURN(status=1)
  12917. ! check ...
  12918. if ( size(shape(values)) > varp%ndim ) then
  12919. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  12920. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  12921. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  12922. TRACEBACK; status=1; return
  12923. end if
  12924. ! check ...
  12925. if ( present(start ) ) then
  12926. if ( size(start ) /= varp%ndim ) then
  12927. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12928. write (gol,'(" size start : ",i6)') size(start ); call goErr
  12929. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12930. TRACEBACK; status=1; return
  12931. end if
  12932. end if
  12933. if ( present(count ) ) then
  12934. if ( size(count ) /= varp%ndim ) then
  12935. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12936. write (gol,'(" size count : ",i6)') size(count ); call goErr
  12937. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12938. TRACEBACK; status=1; return
  12939. end if
  12940. end if
  12941. if ( present(stride ) ) then
  12942. if ( size(stride ) /= varp%ndim ) then
  12943. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12944. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  12945. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12946. TRACEBACK; status=1; return
  12947. end if
  12948. end if
  12949. if ( present(map ) ) then
  12950. if ( size(map ) /= varp%ndim ) then
  12951. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  12952. write (gol,'(" size map : ",i6)') size(map ); call goErr
  12953. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  12954. TRACEBACK; status=1; return
  12955. end if
  12956. end if
  12957. ! loop over file types:
  12958. do iftype = 1, filep%nftype
  12959. ! current type:
  12960. ftype = filep%ftypes(iftype)
  12961. ! select appropriate routine for each type:
  12962. select case ( ftype )
  12963. #ifdef with_hdf4
  12964. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12965. case ( MDF_HDF4 )
  12966. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  12967. ! check ...
  12968. if ( present(map ) ) then
  12969. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  12970. TRACEBACK; status=1; return
  12971. end if
  12972. ! fill offset (zero based!), stride, and count :
  12973. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  12974. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  12975. hdf4_count = 1 ! default singleton dimension
  12976. hdf4_count(1:3) = shape(values)
  12977. ! test source type:
  12978. select case ( varp%hdf4_xtype )
  12979. case ( DFNT_INT8 )
  12980. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  12981. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  12982. values = int(values_int1,kind=4)
  12983. deallocate( values_int1 )
  12984. case ( DFNT_INT16 )
  12985. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  12986. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  12987. values = int(values_int2,kind=4)
  12988. deallocate( values_int2 )
  12989. case ( DFNT_INT32 )
  12990. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  12991. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  12992. values = int(values_int4,kind=4)
  12993. deallocate( values_int4 )
  12994. case ( DFNT_INT64 )
  12995. allocate( values_int8(size(values,1),size(values,2),size(values,3)) )
  12996. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  12997. values = int(values_int8,kind=4)
  12998. deallocate( values_int8 )
  12999. case ( DFNT_FLOAT32 )
  13000. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  13001. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  13002. values = int(values_real4,kind=4)
  13003. deallocate( values_real4 )
  13004. case ( DFNT_FLOAT64 )
  13005. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  13006. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  13007. values = int(values_real8,kind=4)
  13008. deallocate( values_real8 )
  13009. case default
  13010. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  13011. TRACEBACK; status=1; return
  13012. end select
  13013. if ( status == FAIL ) then
  13014. write (gol,'("reading hdf4 data set:")'); call goErr
  13015. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  13016. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  13017. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  13018. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  13019. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  13020. write (gol,'(" size : ",i6)') size(values); call goErr
  13021. TRACEBACK; status=1; return
  13022. end if
  13023. #endif
  13024. #ifdef with_netcdf
  13025. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13026. case ( MDF_NETCDF, MDF_NETCDF4 )
  13027. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13028. ! read values, converted automatically:
  13029. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  13030. start, count, stride, map )
  13031. IF_NF90_NOT_OK_RETURN(status=1)
  13032. #endif
  13033. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13034. case default
  13035. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13036. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  13037. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  13038. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  13039. TRACEBACK; status=1; return
  13040. end select
  13041. end do ! file types
  13042. ! ok
  13043. status = 0
  13044. end subroutine MDF_Get_Var_i4_3d
  13045. ! ***
  13046. subroutine MDF_Put_Var_i4_4d( hid, varid, values, status, &
  13047. start, count, stride, map )
  13048. #ifdef with_hdf5_beta
  13049. use HDF5, only : HID_T, HSIZE_T
  13050. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  13051. use HDF5, only : H5T_NATIVE_CHARACTER
  13052. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  13053. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  13054. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  13055. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  13056. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  13057. #endif
  13058. #ifdef with_netcdf
  13059. use NetCDF, only : NF90_Put_Var
  13060. #endif
  13061. ! --- in/out -------------------------------------
  13062. integer, intent(in) :: hid
  13063. integer, intent(in) :: varid
  13064. integer(4), intent(in) :: values(:,:,:,:)
  13065. integer, intent(out) :: status
  13066. integer, intent(in), optional :: start (:)
  13067. integer, intent(in), optional :: count (:)
  13068. integer, intent(in), optional :: stride(:)
  13069. integer, intent(in), optional :: map (:)
  13070. ! --- const --------------------------------------
  13071. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_4d'
  13072. ! --- external -----------------------------------
  13073. #ifdef with_hdf4
  13074. integer(hdf4_wpi), external :: sfWData
  13075. #endif
  13076. ! --- local --------------------------------------
  13077. type(MDF_File), pointer :: filep
  13078. type(MDF_Var), pointer :: varp
  13079. integer :: iftype
  13080. integer :: ftype
  13081. #ifdef with_hdf4
  13082. integer :: hdf4_offset(MAX_RANK)
  13083. integer :: hdf4_stride(MAX_RANK)
  13084. integer :: hdf4_count(MAX_RANK)
  13085. #endif
  13086. #ifdef with_hdf5_beta
  13087. !integer(HID_T) :: hdf5_type_id
  13088. integer(HID_T) :: hdf5_file_space_id
  13089. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  13090. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  13091. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  13092. #endif
  13093. integer(1), allocatable :: values_int1(:,:,:,:)
  13094. integer(2), allocatable :: values_int2(:,:,:,:)
  13095. integer(4), allocatable :: values_int4(:,:,:,:)
  13096. integer(8), allocatable :: values_int8(:,:,:,:)
  13097. real(4), allocatable :: values_real4(:,:,:,:)
  13098. real(8), allocatable :: values_real8(:,:,:,:)
  13099. ! --- begin --------------------------------------
  13100. ! pointer to file structure:
  13101. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  13102. IF_NOT_OK_RETURN(status=1)
  13103. ! pointer to variable structure:
  13104. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  13105. IF_NOT_OK_RETURN(status=1)
  13106. ! check ...
  13107. if ( size(shape(values)) > varp%ndim ) then
  13108. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  13109. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  13110. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  13111. TRACEBACK; status=1; return
  13112. end if
  13113. ! check ...
  13114. if ( present(start ) ) then
  13115. if ( size(start ) /= varp%ndim ) then
  13116. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13117. write (gol,'(" size start : ",i6)') size(start ); call goErr
  13118. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13119. TRACEBACK; status=1; return
  13120. end if
  13121. end if
  13122. if ( present(count ) ) then
  13123. if ( size(count ) /= varp%ndim ) then
  13124. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13125. write (gol,'(" size count : ",i6)') size(count ); call goErr
  13126. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13127. TRACEBACK; status=1; return
  13128. end if
  13129. end if
  13130. if ( present(stride ) ) then
  13131. if ( size(stride ) /= varp%ndim ) then
  13132. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13133. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  13134. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13135. TRACEBACK; status=1; return
  13136. end if
  13137. end if
  13138. if ( present(map ) ) then
  13139. if ( size(map ) /= varp%ndim ) then
  13140. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13141. write (gol,'(" size map : ",i6)') size(map ); call goErr
  13142. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13143. TRACEBACK; status=1; return
  13144. end if
  13145. end if
  13146. ! loop over file types:
  13147. do iftype = 1, filep%nftype
  13148. ! current type:
  13149. ftype = filep%ftypes(iftype)
  13150. ! select appropriate routine for each type:
  13151. select case ( ftype )
  13152. #ifdef with_hdf4
  13153. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13154. case ( MDF_HDF4 )
  13155. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13156. ! check ...
  13157. if ( present(map ) ) then
  13158. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  13159. TRACEBACK; status=1; return
  13160. end if
  13161. ! fill offset (zero based!) and stride with default values:
  13162. hdf4_offset = 0
  13163. hdf4_stride = 1
  13164. ! count is by default the shape; padd with singleton dimensions:
  13165. hdf4_count = 1; hdf4_count(1:4) = shape(values)
  13166. ! replace by optional arguments if necessary:
  13167. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  13168. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  13169. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  13170. ! test target type;
  13171. ! convert to required kind before entering sfWData,
  13172. ! otherwise segmentation faults on some machines ...
  13173. select case ( varp%xtype )
  13174. case ( MDF_BYTE )
  13175. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13176. values_int1 = int(values,kind=1)
  13177. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13178. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  13179. deallocate( values_int1 )
  13180. case ( MDF_SHORT )
  13181. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13182. values_int2 = int(values,kind=2)
  13183. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13184. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  13185. deallocate( values_int2 )
  13186. case ( MDF_INT )
  13187. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13188. values_int4 = int(values,kind=4)
  13189. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13190. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  13191. deallocate( values_int4 )
  13192. case ( MDF_FLOAT )
  13193. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13194. values_real4 = real(values,kind=4)
  13195. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13196. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  13197. deallocate( values_real4 )
  13198. case ( MDF_DOUBLE )
  13199. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13200. values_real8 = real(values,kind=8)
  13201. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13202. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  13203. deallocate( values_real8 )
  13204. case default
  13205. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  13206. TRACEBACK; status=1; return
  13207. end select
  13208. if ( status == FAIL ) then
  13209. write (gol,'("writing hdf4 data set:")'); call goErr
  13210. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  13211. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  13212. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  13213. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  13214. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  13215. write (gol,'(" size : ",i12)') size(values); call goErr
  13216. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  13217. TRACEBACK; status=1; return
  13218. end if
  13219. #endif
  13220. #ifdef with_hdf5_beta
  13221. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13222. case ( MDF_HDF5 )
  13223. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13224. ! check ...
  13225. if ( present(map ) ) then
  13226. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  13227. TRACEBACK; status=1; return
  13228. end if
  13229. ! fill offset (zero based!), stride, and count :
  13230. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  13231. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  13232. hdf5_count = 1 ! default singleton dimension
  13233. if ( present(count) ) then
  13234. hdf5_count(1:varp%ndim) = count
  13235. else
  13236. hdf5_count(1:4) = shape(values)
  13237. end if
  13238. ! new dimension:
  13239. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  13240. ! target data space in file:
  13241. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  13242. IF_NOT_OK_RETURN(status=1)
  13243. ! chunked dataset ?
  13244. if ( varp%hdf5_chunked ) then
  13245. ! reset extend:
  13246. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  13247. IF_NOT_OK_RETURN(status=1)
  13248. end if
  13249. ! select hyperslab:
  13250. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  13251. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  13252. stride=hdf5_stride(1:varp%ndim) )
  13253. ! write data:
  13254. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  13255. int(shape(values),kind=HSIZE_T), status, &
  13256. file_space_id=hdf5_file_space_id )
  13257. IF_NOT_OK_RETURN(status=1)
  13258. ! release data space:
  13259. call H5SClose_f( hdf5_file_space_id, status )
  13260. IF_NOT_OK_RETURN(status=1)
  13261. #endif
  13262. #ifdef with_netcdf
  13263. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13264. case ( MDF_NETCDF, MDF_NETCDF4 )
  13265. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13266. ! test target type:
  13267. ! convert to required kind before entering NF90_Put_Var,
  13268. ! otherwise segmentation faults on some machines ...
  13269. select case ( varp%xtype )
  13270. case ( MDF_BYTE )
  13271. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13272. values_int1 = int(values,kind=1)
  13273. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  13274. start, count, stride, map )
  13275. IF_NF90_NOT_OK_RETURN(status=1)
  13276. deallocate( values_int1 )
  13277. case ( MDF_SHORT )
  13278. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13279. values_int2 = int(values,kind=2)
  13280. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  13281. start, count, stride, map )
  13282. IF_NF90_NOT_OK_RETURN(status=1)
  13283. deallocate( values_int2 )
  13284. case ( MDF_INT )
  13285. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13286. values_int4 = int(values,kind=4)
  13287. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  13288. start, count, stride, map )
  13289. IF_NF90_NOT_OK_RETURN(status=1)
  13290. deallocate( values_int4 )
  13291. case ( MDF_FLOAT )
  13292. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13293. values_real4 = real(values,kind=4)
  13294. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  13295. start, count, stride, map )
  13296. IF_NF90_NOT_OK_RETURN(status=1)
  13297. deallocate( values_real4 )
  13298. case ( MDF_DOUBLE )
  13299. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13300. values_real8 = real(values,kind=8)
  13301. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  13302. start, count, stride, map )
  13303. IF_NF90_NOT_OK_RETURN(status=1)
  13304. deallocate( values_real8 )
  13305. case default
  13306. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  13307. TRACEBACK; status=1; return
  13308. end select
  13309. ! just put; let netcdf library convert the right kind:
  13310. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  13311. ! start, count, stride, map )
  13312. !IF_NF90_NOT_OK_RETURN(status=1)
  13313. #endif
  13314. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13315. case default
  13316. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13317. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  13318. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  13319. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  13320. TRACEBACK; status=1; return
  13321. end select
  13322. end do ! file types
  13323. ! ok
  13324. status = 0
  13325. end subroutine MDF_Put_Var_i4_4d
  13326. ! ***
  13327. subroutine MDF_Get_Var_i4_4d( hid, varid, values, status, &
  13328. start, count, stride, map )
  13329. #ifdef with_netcdf
  13330. use NetCDF, only : NF90_Get_Var
  13331. #endif
  13332. ! --- in/out -------------------------------------
  13333. integer, intent(in) :: hid
  13334. integer, intent(in) :: varid
  13335. integer(4), intent(out) :: values(:,:,:,:)
  13336. integer, intent(out) :: status
  13337. integer, intent(in), optional :: start (:)
  13338. integer, intent(in), optional :: count (:)
  13339. integer, intent(in), optional :: stride(:)
  13340. integer, intent(in), optional :: map (:)
  13341. ! --- const --------------------------------------
  13342. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_4d'
  13343. ! --- external -----------------------------------
  13344. #ifdef with_hdf4
  13345. integer(hdf4_wpi), external :: sfRData
  13346. #endif
  13347. ! --- local --------------------------------------
  13348. type(MDF_File), pointer :: filep
  13349. type(MDF_Var), pointer :: varp
  13350. integer :: iftype
  13351. integer :: ftype
  13352. #ifdef with_hdf4
  13353. integer :: hdf4_offset(MAX_RANK)
  13354. integer :: hdf4_stride(MAX_RANK)
  13355. integer :: hdf4_count(MAX_RANK)
  13356. integer(1), allocatable :: values_int1(:,:,:,:)
  13357. integer(2), allocatable :: values_int2(:,:,:,:)
  13358. integer(4), allocatable :: values_int4(:,:,:,:)
  13359. integer(8), allocatable :: values_int8(:,:,:,:)
  13360. real(4), allocatable :: values_real4(:,:,:,:)
  13361. real(8), allocatable :: values_real8(:,:,:,:)
  13362. #endif
  13363. ! --- begin --------------------------------------
  13364. ! pointer to file structure:
  13365. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  13366. IF_NOT_OK_RETURN(status=1)
  13367. ! pointer to variable structure:
  13368. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  13369. IF_NOT_OK_RETURN(status=1)
  13370. ! check ...
  13371. if ( size(shape(values)) > varp%ndim ) then
  13372. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  13373. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  13374. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  13375. TRACEBACK; status=1; return
  13376. end if
  13377. ! check ...
  13378. if ( present(start ) ) then
  13379. if ( size(start ) /= varp%ndim ) then
  13380. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13381. write (gol,'(" size start : ",i6)') size(start ); call goErr
  13382. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13383. TRACEBACK; status=1; return
  13384. end if
  13385. end if
  13386. if ( present(count ) ) then
  13387. if ( size(count ) /= varp%ndim ) then
  13388. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13389. write (gol,'(" size count : ",i6)') size(count ); call goErr
  13390. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13391. TRACEBACK; status=1; return
  13392. end if
  13393. end if
  13394. if ( present(stride ) ) then
  13395. if ( size(stride ) /= varp%ndim ) then
  13396. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13397. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  13398. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13399. TRACEBACK; status=1; return
  13400. end if
  13401. end if
  13402. if ( present(map ) ) then
  13403. if ( size(map ) /= varp%ndim ) then
  13404. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13405. write (gol,'(" size map : ",i6)') size(map ); call goErr
  13406. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13407. TRACEBACK; status=1; return
  13408. end if
  13409. end if
  13410. ! loop over file types:
  13411. do iftype = 1, filep%nftype
  13412. ! current type:
  13413. ftype = filep%ftypes(iftype)
  13414. ! select appropriate routine for each type:
  13415. select case ( ftype )
  13416. #ifdef with_hdf4
  13417. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13418. case ( MDF_HDF4 )
  13419. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13420. ! check ...
  13421. if ( present(map ) ) then
  13422. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  13423. TRACEBACK; status=1; return
  13424. end if
  13425. ! fill offset (zero based!), stride, and count :
  13426. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  13427. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  13428. hdf4_count = 1 ! default singleton dimension
  13429. hdf4_count(1:4) = shape(values)
  13430. ! test source type:
  13431. select case ( varp%hdf4_xtype )
  13432. case ( DFNT_INT8 )
  13433. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13434. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  13435. values = int(values_int1,kind=4)
  13436. deallocate( values_int1 )
  13437. case ( DFNT_INT16 )
  13438. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13439. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  13440. values = int(values_int2,kind=4)
  13441. deallocate( values_int2 )
  13442. case ( DFNT_INT32 )
  13443. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13444. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  13445. values = int(values_int4,kind=4)
  13446. deallocate( values_int4 )
  13447. case ( DFNT_INT64 )
  13448. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13449. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  13450. values = int(values_int8,kind=4)
  13451. deallocate( values_int8 )
  13452. case ( DFNT_FLOAT32 )
  13453. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13454. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  13455. values = int(values_real4,kind=4)
  13456. deallocate( values_real4 )
  13457. case ( DFNT_FLOAT64 )
  13458. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  13459. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  13460. values = int(values_real8,kind=4)
  13461. deallocate( values_real8 )
  13462. case default
  13463. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  13464. TRACEBACK; status=1; return
  13465. end select
  13466. if ( status == FAIL ) then
  13467. write (gol,'("reading hdf4 data set:")'); call goErr
  13468. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  13469. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  13470. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  13471. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  13472. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  13473. write (gol,'(" size : ",i6)') size(values); call goErr
  13474. TRACEBACK; status=1; return
  13475. end if
  13476. #endif
  13477. #ifdef with_netcdf
  13478. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13479. case ( MDF_NETCDF, MDF_NETCDF4 )
  13480. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13481. ! read values, converted automatically:
  13482. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  13483. start, count, stride, map )
  13484. IF_NF90_NOT_OK_RETURN(status=1)
  13485. #endif
  13486. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13487. case default
  13488. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13489. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  13490. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  13491. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  13492. TRACEBACK; status=1; return
  13493. end select
  13494. end do ! file types
  13495. ! ok
  13496. status = 0
  13497. end subroutine MDF_Get_Var_i4_4d
  13498. ! ***
  13499. subroutine MDF_Put_Var_i4_5d( hid, varid, values, status, &
  13500. start, count, stride, map )
  13501. #ifdef with_hdf5_beta
  13502. use HDF5, only : HID_T, HSIZE_T
  13503. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  13504. use HDF5, only : H5T_NATIVE_CHARACTER
  13505. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  13506. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  13507. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  13508. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  13509. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  13510. #endif
  13511. #ifdef with_netcdf
  13512. use NetCDF, only : NF90_Put_Var
  13513. #endif
  13514. ! --- in/out -------------------------------------
  13515. integer, intent(in) :: hid
  13516. integer, intent(in) :: varid
  13517. integer(4), intent(in) :: values(:,:,:,:,:)
  13518. integer, intent(out) :: status
  13519. integer, intent(in), optional :: start (:)
  13520. integer, intent(in), optional :: count (:)
  13521. integer, intent(in), optional :: stride(:)
  13522. integer, intent(in), optional :: map (:)
  13523. ! --- const --------------------------------------
  13524. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_5d'
  13525. ! --- external -----------------------------------
  13526. #ifdef with_hdf4
  13527. integer(hdf4_wpi), external :: sfWData
  13528. #endif
  13529. ! --- local --------------------------------------
  13530. type(MDF_File), pointer :: filep
  13531. type(MDF_Var), pointer :: varp
  13532. integer :: iftype
  13533. integer :: ftype
  13534. #ifdef with_hdf4
  13535. integer :: hdf4_offset(MAX_RANK)
  13536. integer :: hdf4_stride(MAX_RANK)
  13537. integer :: hdf4_count(MAX_RANK)
  13538. #endif
  13539. #ifdef with_hdf5_beta
  13540. !integer(HID_T) :: hdf5_type_id
  13541. integer(HID_T) :: hdf5_file_space_id
  13542. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  13543. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  13544. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  13545. #endif
  13546. integer(1), allocatable :: values_int1(:,:,:,:,:)
  13547. integer(2), allocatable :: values_int2(:,:,:,:,:)
  13548. integer(4), allocatable :: values_int4(:,:,:,:,:)
  13549. integer(8), allocatable :: values_int8(:,:,:,:,:)
  13550. real(4), allocatable :: values_real4(:,:,:,:,:)
  13551. real(8), allocatable :: values_real8(:,:,:,:,:)
  13552. ! --- begin --------------------------------------
  13553. ! pointer to file structure:
  13554. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  13555. IF_NOT_OK_RETURN(status=1)
  13556. ! pointer to variable structure:
  13557. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  13558. IF_NOT_OK_RETURN(status=1)
  13559. ! check ...
  13560. if ( size(shape(values)) > varp%ndim ) then
  13561. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  13562. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  13563. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  13564. TRACEBACK; status=1; return
  13565. end if
  13566. ! check ...
  13567. if ( present(start ) ) then
  13568. if ( size(start ) /= varp%ndim ) then
  13569. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13570. write (gol,'(" size start : ",i6)') size(start ); call goErr
  13571. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13572. TRACEBACK; status=1; return
  13573. end if
  13574. end if
  13575. if ( present(count ) ) then
  13576. if ( size(count ) /= varp%ndim ) then
  13577. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13578. write (gol,'(" size count : ",i6)') size(count ); call goErr
  13579. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13580. TRACEBACK; status=1; return
  13581. end if
  13582. end if
  13583. if ( present(stride ) ) then
  13584. if ( size(stride ) /= varp%ndim ) then
  13585. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13586. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  13587. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13588. TRACEBACK; status=1; return
  13589. end if
  13590. end if
  13591. if ( present(map ) ) then
  13592. if ( size(map ) /= varp%ndim ) then
  13593. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13594. write (gol,'(" size map : ",i6)') size(map ); call goErr
  13595. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13596. TRACEBACK; status=1; return
  13597. end if
  13598. end if
  13599. ! loop over file types:
  13600. do iftype = 1, filep%nftype
  13601. ! current type:
  13602. ftype = filep%ftypes(iftype)
  13603. ! select appropriate routine for each type:
  13604. select case ( ftype )
  13605. #ifdef with_hdf4
  13606. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13607. case ( MDF_HDF4 )
  13608. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13609. ! check ...
  13610. if ( present(map ) ) then
  13611. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  13612. TRACEBACK; status=1; return
  13613. end if
  13614. ! fill offset (zero based!) and stride with default values:
  13615. hdf4_offset = 0
  13616. hdf4_stride = 1
  13617. ! count is by default the shape; padd with singleton dimensions:
  13618. hdf4_count = 1; hdf4_count(1:5) = shape(values)
  13619. ! replace by optional arguments if necessary:
  13620. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  13621. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  13622. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  13623. ! test target type;
  13624. ! convert to required kind before entering sfWData,
  13625. ! otherwise segmentation faults on some machines ...
  13626. select case ( varp%xtype )
  13627. case ( MDF_BYTE )
  13628. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13629. values_int1 = int(values,kind=1)
  13630. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13631. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  13632. deallocate( values_int1 )
  13633. case ( MDF_SHORT )
  13634. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13635. values_int2 = int(values,kind=2)
  13636. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13637. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  13638. deallocate( values_int2 )
  13639. case ( MDF_INT )
  13640. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13641. values_int4 = int(values,kind=4)
  13642. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13643. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  13644. deallocate( values_int4 )
  13645. case ( MDF_FLOAT )
  13646. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13647. values_real4 = real(values,kind=4)
  13648. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13649. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  13650. deallocate( values_real4 )
  13651. case ( MDF_DOUBLE )
  13652. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13653. values_real8 = real(values,kind=8)
  13654. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  13655. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  13656. deallocate( values_real8 )
  13657. case default
  13658. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  13659. TRACEBACK; status=1; return
  13660. end select
  13661. if ( status == FAIL ) then
  13662. write (gol,'("writing hdf4 data set:")'); call goErr
  13663. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  13664. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  13665. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  13666. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  13667. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  13668. write (gol,'(" size : ",i12)') size(values); call goErr
  13669. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  13670. TRACEBACK; status=1; return
  13671. end if
  13672. #endif
  13673. #ifdef with_hdf5_beta
  13674. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13675. case ( MDF_HDF5 )
  13676. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13677. ! check ...
  13678. if ( present(map ) ) then
  13679. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  13680. TRACEBACK; status=1; return
  13681. end if
  13682. ! fill offset (zero based!), stride, and count :
  13683. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  13684. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  13685. hdf5_count = 1 ! default singleton dimension
  13686. if ( present(count) ) then
  13687. hdf5_count(1:varp%ndim) = count
  13688. else
  13689. hdf5_count(1:5) = shape(values)
  13690. end if
  13691. ! new dimension:
  13692. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  13693. ! target data space in file:
  13694. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  13695. IF_NOT_OK_RETURN(status=1)
  13696. ! chunked dataset ?
  13697. if ( varp%hdf5_chunked ) then
  13698. ! reset extend:
  13699. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  13700. IF_NOT_OK_RETURN(status=1)
  13701. end if
  13702. ! select hyperslab:
  13703. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  13704. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  13705. stride=hdf5_stride(1:varp%ndim) )
  13706. ! write data:
  13707. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  13708. int(shape(values),kind=HSIZE_T), status, &
  13709. file_space_id=hdf5_file_space_id )
  13710. IF_NOT_OK_RETURN(status=1)
  13711. ! release data space:
  13712. call H5SClose_f( hdf5_file_space_id, status )
  13713. IF_NOT_OK_RETURN(status=1)
  13714. #endif
  13715. #ifdef with_netcdf
  13716. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13717. case ( MDF_NETCDF, MDF_NETCDF4 )
  13718. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13719. ! test target type:
  13720. ! convert to required kind before entering NF90_Put_Var,
  13721. ! otherwise segmentation faults on some machines ...
  13722. select case ( varp%xtype )
  13723. case ( MDF_BYTE )
  13724. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13725. values_int1 = int(values,kind=1)
  13726. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  13727. start, count, stride, map )
  13728. IF_NF90_NOT_OK_RETURN(status=1)
  13729. deallocate( values_int1 )
  13730. case ( MDF_SHORT )
  13731. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13732. values_int2 = int(values,kind=2)
  13733. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  13734. start, count, stride, map )
  13735. IF_NF90_NOT_OK_RETURN(status=1)
  13736. deallocate( values_int2 )
  13737. case ( MDF_INT )
  13738. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13739. values_int4 = int(values,kind=4)
  13740. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  13741. start, count, stride, map )
  13742. IF_NF90_NOT_OK_RETURN(status=1)
  13743. deallocate( values_int4 )
  13744. case ( MDF_FLOAT )
  13745. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13746. values_real4 = real(values,kind=4)
  13747. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  13748. start, count, stride, map )
  13749. IF_NF90_NOT_OK_RETURN(status=1)
  13750. deallocate( values_real4 )
  13751. case ( MDF_DOUBLE )
  13752. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13753. values_real8 = real(values,kind=8)
  13754. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  13755. start, count, stride, map )
  13756. IF_NF90_NOT_OK_RETURN(status=1)
  13757. deallocate( values_real8 )
  13758. case default
  13759. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  13760. TRACEBACK; status=1; return
  13761. end select
  13762. ! just put; let netcdf library convert the right kind:
  13763. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  13764. ! start, count, stride, map )
  13765. !IF_NF90_NOT_OK_RETURN(status=1)
  13766. #endif
  13767. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13768. case default
  13769. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13770. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  13771. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  13772. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  13773. TRACEBACK; status=1; return
  13774. end select
  13775. end do ! file types
  13776. ! ok
  13777. status = 0
  13778. end subroutine MDF_Put_Var_i4_5d
  13779. ! ***
  13780. subroutine MDF_Get_Var_i4_5d( hid, varid, values, status, &
  13781. start, count, stride, map )
  13782. #ifdef with_netcdf
  13783. use NetCDF, only : NF90_Get_Var
  13784. #endif
  13785. ! --- in/out -------------------------------------
  13786. integer, intent(in) :: hid
  13787. integer, intent(in) :: varid
  13788. integer(4), intent(out) :: values(:,:,:,:,:)
  13789. integer, intent(out) :: status
  13790. integer, intent(in), optional :: start (:)
  13791. integer, intent(in), optional :: count (:)
  13792. integer, intent(in), optional :: stride(:)
  13793. integer, intent(in), optional :: map (:)
  13794. ! --- const --------------------------------------
  13795. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_5d'
  13796. ! --- external -----------------------------------
  13797. #ifdef with_hdf4
  13798. integer(hdf4_wpi), external :: sfRData
  13799. #endif
  13800. ! --- local --------------------------------------
  13801. type(MDF_File), pointer :: filep
  13802. type(MDF_Var), pointer :: varp
  13803. integer :: iftype
  13804. integer :: ftype
  13805. #ifdef with_hdf4
  13806. integer :: hdf4_offset(MAX_RANK)
  13807. integer :: hdf4_stride(MAX_RANK)
  13808. integer :: hdf4_count(MAX_RANK)
  13809. integer(1), allocatable :: values_int1(:,:,:,:,:)
  13810. integer(2), allocatable :: values_int2(:,:,:,:,:)
  13811. integer(4), allocatable :: values_int4(:,:,:,:,:)
  13812. integer(8), allocatable :: values_int8(:,:,:,:,:)
  13813. real(4), allocatable :: values_real4(:,:,:,:,:)
  13814. real(8), allocatable :: values_real8(:,:,:,:,:)
  13815. #endif
  13816. ! --- begin --------------------------------------
  13817. ! pointer to file structure:
  13818. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  13819. IF_NOT_OK_RETURN(status=1)
  13820. ! pointer to variable structure:
  13821. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  13822. IF_NOT_OK_RETURN(status=1)
  13823. ! check ...
  13824. if ( size(shape(values)) > varp%ndim ) then
  13825. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  13826. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  13827. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  13828. TRACEBACK; status=1; return
  13829. end if
  13830. ! check ...
  13831. if ( present(start ) ) then
  13832. if ( size(start ) /= varp%ndim ) then
  13833. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13834. write (gol,'(" size start : ",i6)') size(start ); call goErr
  13835. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13836. TRACEBACK; status=1; return
  13837. end if
  13838. end if
  13839. if ( present(count ) ) then
  13840. if ( size(count ) /= varp%ndim ) then
  13841. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13842. write (gol,'(" size count : ",i6)') size(count ); call goErr
  13843. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13844. TRACEBACK; status=1; return
  13845. end if
  13846. end if
  13847. if ( present(stride ) ) then
  13848. if ( size(stride ) /= varp%ndim ) then
  13849. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13850. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  13851. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13852. TRACEBACK; status=1; return
  13853. end if
  13854. end if
  13855. if ( present(map ) ) then
  13856. if ( size(map ) /= varp%ndim ) then
  13857. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  13858. write (gol,'(" size map : ",i6)') size(map ); call goErr
  13859. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  13860. TRACEBACK; status=1; return
  13861. end if
  13862. end if
  13863. ! loop over file types:
  13864. do iftype = 1, filep%nftype
  13865. ! current type:
  13866. ftype = filep%ftypes(iftype)
  13867. ! select appropriate routine for each type:
  13868. select case ( ftype )
  13869. #ifdef with_hdf4
  13870. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13871. case ( MDF_HDF4 )
  13872. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13873. ! check ...
  13874. if ( present(map ) ) then
  13875. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  13876. TRACEBACK; status=1; return
  13877. end if
  13878. ! fill offset (zero based!), stride, and count :
  13879. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  13880. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  13881. hdf4_count = 1 ! default singleton dimension
  13882. hdf4_count(1:5) = shape(values)
  13883. ! test source type:
  13884. select case ( varp%hdf4_xtype )
  13885. case ( DFNT_INT8 )
  13886. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13887. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  13888. values = int(values_int1,kind=4)
  13889. deallocate( values_int1 )
  13890. case ( DFNT_INT16 )
  13891. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13892. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  13893. values = int(values_int2,kind=4)
  13894. deallocate( values_int2 )
  13895. case ( DFNT_INT32 )
  13896. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13897. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  13898. values = int(values_int4,kind=4)
  13899. deallocate( values_int4 )
  13900. case ( DFNT_INT64 )
  13901. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13902. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  13903. values = int(values_int8,kind=4)
  13904. deallocate( values_int8 )
  13905. case ( DFNT_FLOAT32 )
  13906. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13907. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  13908. values = int(values_real4,kind=4)
  13909. deallocate( values_real4 )
  13910. case ( DFNT_FLOAT64 )
  13911. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  13912. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  13913. values = int(values_real8,kind=4)
  13914. deallocate( values_real8 )
  13915. case default
  13916. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  13917. TRACEBACK; status=1; return
  13918. end select
  13919. if ( status == FAIL ) then
  13920. write (gol,'("reading hdf4 data set:")'); call goErr
  13921. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  13922. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  13923. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  13924. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  13925. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  13926. write (gol,'(" size : ",i6)') size(values); call goErr
  13927. TRACEBACK; status=1; return
  13928. end if
  13929. #endif
  13930. #ifdef with_netcdf
  13931. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13932. case ( MDF_NETCDF, MDF_NETCDF4 )
  13933. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13934. ! read values, converted automatically:
  13935. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  13936. start, count, stride, map )
  13937. IF_NF90_NOT_OK_RETURN(status=1)
  13938. #endif
  13939. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13940. case default
  13941. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  13942. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  13943. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  13944. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  13945. TRACEBACK; status=1; return
  13946. end select
  13947. end do ! file types
  13948. ! ok
  13949. status = 0
  13950. end subroutine MDF_Get_Var_i4_5d
  13951. ! ***
  13952. subroutine MDF_Put_Var_i4_6d( hid, varid, values, status, &
  13953. start, count, stride, map )
  13954. #ifdef with_hdf5_beta
  13955. use HDF5, only : HID_T, HSIZE_T
  13956. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  13957. use HDF5, only : H5T_NATIVE_CHARACTER
  13958. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  13959. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  13960. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  13961. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  13962. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  13963. #endif
  13964. #ifdef with_netcdf
  13965. use NetCDF, only : NF90_Put_Var
  13966. #endif
  13967. ! --- in/out -------------------------------------
  13968. integer, intent(in) :: hid
  13969. integer, intent(in) :: varid
  13970. integer(4), intent(in) :: values(:,:,:,:,:,:)
  13971. integer, intent(out) :: status
  13972. integer, intent(in), optional :: start (:)
  13973. integer, intent(in), optional :: count (:)
  13974. integer, intent(in), optional :: stride(:)
  13975. integer, intent(in), optional :: map (:)
  13976. ! --- const --------------------------------------
  13977. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_6d'
  13978. ! --- external -----------------------------------
  13979. #ifdef with_hdf4
  13980. integer(hdf4_wpi), external :: sfWData
  13981. #endif
  13982. ! --- local --------------------------------------
  13983. type(MDF_File), pointer :: filep
  13984. type(MDF_Var), pointer :: varp
  13985. integer :: iftype
  13986. integer :: ftype
  13987. #ifdef with_hdf4
  13988. integer :: hdf4_offset(MAX_RANK)
  13989. integer :: hdf4_stride(MAX_RANK)
  13990. integer :: hdf4_count(MAX_RANK)
  13991. #endif
  13992. #ifdef with_hdf5_beta
  13993. !integer(HID_T) :: hdf5_type_id
  13994. integer(HID_T) :: hdf5_file_space_id
  13995. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  13996. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  13997. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  13998. #endif
  13999. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  14000. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  14001. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  14002. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  14003. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  14004. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  14005. ! --- begin --------------------------------------
  14006. ! pointer to file structure:
  14007. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  14008. IF_NOT_OK_RETURN(status=1)
  14009. ! pointer to variable structure:
  14010. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  14011. IF_NOT_OK_RETURN(status=1)
  14012. ! check ...
  14013. if ( size(shape(values)) > varp%ndim ) then
  14014. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  14015. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  14016. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  14017. TRACEBACK; status=1; return
  14018. end if
  14019. ! check ...
  14020. if ( present(start ) ) then
  14021. if ( size(start ) /= varp%ndim ) then
  14022. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14023. write (gol,'(" size start : ",i6)') size(start ); call goErr
  14024. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14025. TRACEBACK; status=1; return
  14026. end if
  14027. end if
  14028. if ( present(count ) ) then
  14029. if ( size(count ) /= varp%ndim ) then
  14030. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14031. write (gol,'(" size count : ",i6)') size(count ); call goErr
  14032. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14033. TRACEBACK; status=1; return
  14034. end if
  14035. end if
  14036. if ( present(stride ) ) then
  14037. if ( size(stride ) /= varp%ndim ) then
  14038. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14039. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  14040. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14041. TRACEBACK; status=1; return
  14042. end if
  14043. end if
  14044. if ( present(map ) ) then
  14045. if ( size(map ) /= varp%ndim ) then
  14046. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14047. write (gol,'(" size map : ",i6)') size(map ); call goErr
  14048. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14049. TRACEBACK; status=1; return
  14050. end if
  14051. end if
  14052. ! loop over file types:
  14053. do iftype = 1, filep%nftype
  14054. ! current type:
  14055. ftype = filep%ftypes(iftype)
  14056. ! select appropriate routine for each type:
  14057. select case ( ftype )
  14058. #ifdef with_hdf4
  14059. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14060. case ( MDF_HDF4 )
  14061. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14062. ! check ...
  14063. if ( present(map ) ) then
  14064. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  14065. TRACEBACK; status=1; return
  14066. end if
  14067. ! fill offset (zero based!) and stride with default values:
  14068. hdf4_offset = 0
  14069. hdf4_stride = 1
  14070. ! count is by default the shape; padd with singleton dimensions:
  14071. hdf4_count = 1; hdf4_count(1:6) = shape(values)
  14072. ! replace by optional arguments if necessary:
  14073. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  14074. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  14075. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  14076. ! test target type;
  14077. ! convert to required kind before entering sfWData,
  14078. ! otherwise segmentation faults on some machines ...
  14079. select case ( varp%xtype )
  14080. case ( MDF_BYTE )
  14081. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14082. values_int1 = int(values,kind=1)
  14083. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14084. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  14085. deallocate( values_int1 )
  14086. case ( MDF_SHORT )
  14087. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14088. values_int2 = int(values,kind=2)
  14089. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14090. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  14091. deallocate( values_int2 )
  14092. case ( MDF_INT )
  14093. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14094. values_int4 = int(values,kind=4)
  14095. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14096. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  14097. deallocate( values_int4 )
  14098. case ( MDF_FLOAT )
  14099. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14100. values_real4 = real(values,kind=4)
  14101. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14102. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  14103. deallocate( values_real4 )
  14104. case ( MDF_DOUBLE )
  14105. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14106. values_real8 = real(values,kind=8)
  14107. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14108. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  14109. deallocate( values_real8 )
  14110. case default
  14111. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  14112. TRACEBACK; status=1; return
  14113. end select
  14114. if ( status == FAIL ) then
  14115. write (gol,'("writing hdf4 data set:")'); call goErr
  14116. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  14117. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  14118. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  14119. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  14120. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  14121. write (gol,'(" size : ",i12)') size(values); call goErr
  14122. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  14123. TRACEBACK; status=1; return
  14124. end if
  14125. #endif
  14126. #ifdef with_hdf5_beta
  14127. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14128. case ( MDF_HDF5 )
  14129. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14130. ! check ...
  14131. if ( present(map ) ) then
  14132. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  14133. TRACEBACK; status=1; return
  14134. end if
  14135. ! fill offset (zero based!), stride, and count :
  14136. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  14137. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  14138. hdf5_count = 1 ! default singleton dimension
  14139. if ( present(count) ) then
  14140. hdf5_count(1:varp%ndim) = count
  14141. else
  14142. hdf5_count(1:6) = shape(values)
  14143. end if
  14144. ! new dimension:
  14145. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  14146. ! target data space in file:
  14147. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  14148. IF_NOT_OK_RETURN(status=1)
  14149. ! chunked dataset ?
  14150. if ( varp%hdf5_chunked ) then
  14151. ! reset extend:
  14152. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  14153. IF_NOT_OK_RETURN(status=1)
  14154. end if
  14155. ! select hyperslab:
  14156. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  14157. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  14158. stride=hdf5_stride(1:varp%ndim) )
  14159. ! write data:
  14160. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  14161. int(shape(values),kind=HSIZE_T), status, &
  14162. file_space_id=hdf5_file_space_id )
  14163. IF_NOT_OK_RETURN(status=1)
  14164. ! release data space:
  14165. call H5SClose_f( hdf5_file_space_id, status )
  14166. IF_NOT_OK_RETURN(status=1)
  14167. #endif
  14168. #ifdef with_netcdf
  14169. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14170. case ( MDF_NETCDF, MDF_NETCDF4 )
  14171. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14172. ! test target type:
  14173. ! convert to required kind before entering NF90_Put_Var,
  14174. ! otherwise segmentation faults on some machines ...
  14175. select case ( varp%xtype )
  14176. case ( MDF_BYTE )
  14177. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14178. values_int1 = int(values,kind=1)
  14179. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  14180. start, count, stride, map )
  14181. IF_NF90_NOT_OK_RETURN(status=1)
  14182. deallocate( values_int1 )
  14183. case ( MDF_SHORT )
  14184. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14185. values_int2 = int(values,kind=2)
  14186. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  14187. start, count, stride, map )
  14188. IF_NF90_NOT_OK_RETURN(status=1)
  14189. deallocate( values_int2 )
  14190. case ( MDF_INT )
  14191. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14192. values_int4 = int(values,kind=4)
  14193. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  14194. start, count, stride, map )
  14195. IF_NF90_NOT_OK_RETURN(status=1)
  14196. deallocate( values_int4 )
  14197. case ( MDF_FLOAT )
  14198. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14199. values_real4 = real(values,kind=4)
  14200. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  14201. start, count, stride, map )
  14202. IF_NF90_NOT_OK_RETURN(status=1)
  14203. deallocate( values_real4 )
  14204. case ( MDF_DOUBLE )
  14205. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14206. values_real8 = real(values,kind=8)
  14207. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  14208. start, count, stride, map )
  14209. IF_NF90_NOT_OK_RETURN(status=1)
  14210. deallocate( values_real8 )
  14211. case default
  14212. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  14213. TRACEBACK; status=1; return
  14214. end select
  14215. ! just put; let netcdf library convert the right kind:
  14216. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  14217. ! start, count, stride, map )
  14218. !IF_NF90_NOT_OK_RETURN(status=1)
  14219. #endif
  14220. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14221. case default
  14222. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14223. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  14224. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  14225. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  14226. TRACEBACK; status=1; return
  14227. end select
  14228. end do ! file types
  14229. ! ok
  14230. status = 0
  14231. end subroutine MDF_Put_Var_i4_6d
  14232. ! ***
  14233. subroutine MDF_Get_Var_i4_6d( hid, varid, values, status, &
  14234. start, count, stride, map )
  14235. #ifdef with_netcdf
  14236. use NetCDF, only : NF90_Get_Var
  14237. #endif
  14238. ! --- in/out -------------------------------------
  14239. integer, intent(in) :: hid
  14240. integer, intent(in) :: varid
  14241. integer(4), intent(out) :: values(:,:,:,:,:,:)
  14242. integer, intent(out) :: status
  14243. integer, intent(in), optional :: start (:)
  14244. integer, intent(in), optional :: count (:)
  14245. integer, intent(in), optional :: stride(:)
  14246. integer, intent(in), optional :: map (:)
  14247. ! --- const --------------------------------------
  14248. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_6d'
  14249. ! --- external -----------------------------------
  14250. #ifdef with_hdf4
  14251. integer(hdf4_wpi), external :: sfRData
  14252. #endif
  14253. ! --- local --------------------------------------
  14254. type(MDF_File), pointer :: filep
  14255. type(MDF_Var), pointer :: varp
  14256. integer :: iftype
  14257. integer :: ftype
  14258. #ifdef with_hdf4
  14259. integer :: hdf4_offset(MAX_RANK)
  14260. integer :: hdf4_stride(MAX_RANK)
  14261. integer :: hdf4_count(MAX_RANK)
  14262. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  14263. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  14264. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  14265. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  14266. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  14267. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  14268. #endif
  14269. ! --- begin --------------------------------------
  14270. ! pointer to file structure:
  14271. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  14272. IF_NOT_OK_RETURN(status=1)
  14273. ! pointer to variable structure:
  14274. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  14275. IF_NOT_OK_RETURN(status=1)
  14276. ! check ...
  14277. if ( size(shape(values)) > varp%ndim ) then
  14278. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  14279. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  14280. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  14281. TRACEBACK; status=1; return
  14282. end if
  14283. ! check ...
  14284. if ( present(start ) ) then
  14285. if ( size(start ) /= varp%ndim ) then
  14286. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14287. write (gol,'(" size start : ",i6)') size(start ); call goErr
  14288. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14289. TRACEBACK; status=1; return
  14290. end if
  14291. end if
  14292. if ( present(count ) ) then
  14293. if ( size(count ) /= varp%ndim ) then
  14294. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14295. write (gol,'(" size count : ",i6)') size(count ); call goErr
  14296. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14297. TRACEBACK; status=1; return
  14298. end if
  14299. end if
  14300. if ( present(stride ) ) then
  14301. if ( size(stride ) /= varp%ndim ) then
  14302. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14303. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  14304. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14305. TRACEBACK; status=1; return
  14306. end if
  14307. end if
  14308. if ( present(map ) ) then
  14309. if ( size(map ) /= varp%ndim ) then
  14310. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14311. write (gol,'(" size map : ",i6)') size(map ); call goErr
  14312. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14313. TRACEBACK; status=1; return
  14314. end if
  14315. end if
  14316. ! loop over file types:
  14317. do iftype = 1, filep%nftype
  14318. ! current type:
  14319. ftype = filep%ftypes(iftype)
  14320. ! select appropriate routine for each type:
  14321. select case ( ftype )
  14322. #ifdef with_hdf4
  14323. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14324. case ( MDF_HDF4 )
  14325. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14326. ! check ...
  14327. if ( present(map ) ) then
  14328. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  14329. TRACEBACK; status=1; return
  14330. end if
  14331. ! fill offset (zero based!), stride, and count :
  14332. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  14333. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  14334. hdf4_count = 1 ! default singleton dimension
  14335. hdf4_count(1:6) = shape(values)
  14336. ! test source type:
  14337. select case ( varp%hdf4_xtype )
  14338. case ( DFNT_INT8 )
  14339. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14340. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  14341. values = int(values_int1,kind=4)
  14342. deallocate( values_int1 )
  14343. case ( DFNT_INT16 )
  14344. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14345. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  14346. values = int(values_int2,kind=4)
  14347. deallocate( values_int2 )
  14348. case ( DFNT_INT32 )
  14349. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14350. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  14351. values = int(values_int4,kind=4)
  14352. deallocate( values_int4 )
  14353. case ( DFNT_INT64 )
  14354. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14355. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  14356. values = int(values_int8,kind=4)
  14357. deallocate( values_int8 )
  14358. case ( DFNT_FLOAT32 )
  14359. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14360. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  14361. values = int(values_real4,kind=4)
  14362. deallocate( values_real4 )
  14363. case ( DFNT_FLOAT64 )
  14364. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  14365. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  14366. values = int(values_real8,kind=4)
  14367. deallocate( values_real8 )
  14368. case default
  14369. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  14370. TRACEBACK; status=1; return
  14371. end select
  14372. if ( status == FAIL ) then
  14373. write (gol,'("reading hdf4 data set:")'); call goErr
  14374. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  14375. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  14376. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  14377. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  14378. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  14379. write (gol,'(" size : ",i6)') size(values); call goErr
  14380. TRACEBACK; status=1; return
  14381. end if
  14382. #endif
  14383. #ifdef with_netcdf
  14384. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14385. case ( MDF_NETCDF, MDF_NETCDF4 )
  14386. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14387. ! read values, converted automatically:
  14388. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  14389. start, count, stride, map )
  14390. IF_NF90_NOT_OK_RETURN(status=1)
  14391. #endif
  14392. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14393. case default
  14394. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14395. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  14396. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  14397. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  14398. TRACEBACK; status=1; return
  14399. end select
  14400. end do ! file types
  14401. ! ok
  14402. status = 0
  14403. end subroutine MDF_Get_Var_i4_6d
  14404. ! ***
  14405. subroutine MDF_Put_Var_i4_7d( hid, varid, values, status, &
  14406. start, count, stride, map )
  14407. #ifdef with_hdf5_beta
  14408. use HDF5, only : HID_T, HSIZE_T
  14409. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  14410. use HDF5, only : H5T_NATIVE_CHARACTER
  14411. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  14412. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  14413. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  14414. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  14415. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  14416. #endif
  14417. #ifdef with_netcdf
  14418. use NetCDF, only : NF90_Put_Var
  14419. #endif
  14420. ! --- in/out -------------------------------------
  14421. integer, intent(in) :: hid
  14422. integer, intent(in) :: varid
  14423. integer(4), intent(in) :: values(:,:,:,:,:,:,:)
  14424. integer, intent(out) :: status
  14425. integer, intent(in), optional :: start (:)
  14426. integer, intent(in), optional :: count (:)
  14427. integer, intent(in), optional :: stride(:)
  14428. integer, intent(in), optional :: map (:)
  14429. ! --- const --------------------------------------
  14430. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_i4_7d'
  14431. ! --- external -----------------------------------
  14432. #ifdef with_hdf4
  14433. integer(hdf4_wpi), external :: sfWData
  14434. #endif
  14435. ! --- local --------------------------------------
  14436. type(MDF_File), pointer :: filep
  14437. type(MDF_Var), pointer :: varp
  14438. integer :: iftype
  14439. integer :: ftype
  14440. #ifdef with_hdf4
  14441. integer :: hdf4_offset(MAX_RANK)
  14442. integer :: hdf4_stride(MAX_RANK)
  14443. integer :: hdf4_count(MAX_RANK)
  14444. #endif
  14445. #ifdef with_hdf5_beta
  14446. !integer(HID_T) :: hdf5_type_id
  14447. integer(HID_T) :: hdf5_file_space_id
  14448. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  14449. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  14450. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  14451. #endif
  14452. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  14453. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  14454. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  14455. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  14456. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  14457. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  14458. ! --- begin --------------------------------------
  14459. ! pointer to file structure:
  14460. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  14461. IF_NOT_OK_RETURN(status=1)
  14462. ! pointer to variable structure:
  14463. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  14464. IF_NOT_OK_RETURN(status=1)
  14465. ! check ...
  14466. if ( size(shape(values)) > varp%ndim ) then
  14467. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  14468. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  14469. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  14470. TRACEBACK; status=1; return
  14471. end if
  14472. ! check ...
  14473. if ( present(start ) ) then
  14474. if ( size(start ) /= varp%ndim ) then
  14475. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14476. write (gol,'(" size start : ",i6)') size(start ); call goErr
  14477. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14478. TRACEBACK; status=1; return
  14479. end if
  14480. end if
  14481. if ( present(count ) ) then
  14482. if ( size(count ) /= varp%ndim ) then
  14483. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14484. write (gol,'(" size count : ",i6)') size(count ); call goErr
  14485. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14486. TRACEBACK; status=1; return
  14487. end if
  14488. end if
  14489. if ( present(stride ) ) then
  14490. if ( size(stride ) /= varp%ndim ) then
  14491. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14492. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  14493. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14494. TRACEBACK; status=1; return
  14495. end if
  14496. end if
  14497. if ( present(map ) ) then
  14498. if ( size(map ) /= varp%ndim ) then
  14499. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14500. write (gol,'(" size map : ",i6)') size(map ); call goErr
  14501. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14502. TRACEBACK; status=1; return
  14503. end if
  14504. end if
  14505. ! loop over file types:
  14506. do iftype = 1, filep%nftype
  14507. ! current type:
  14508. ftype = filep%ftypes(iftype)
  14509. ! select appropriate routine for each type:
  14510. select case ( ftype )
  14511. #ifdef with_hdf4
  14512. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14513. case ( MDF_HDF4 )
  14514. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14515. ! check ...
  14516. if ( present(map ) ) then
  14517. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  14518. TRACEBACK; status=1; return
  14519. end if
  14520. ! fill offset (zero based!) and stride with default values:
  14521. hdf4_offset = 0
  14522. hdf4_stride = 1
  14523. ! count is by default the shape; padd with singleton dimensions:
  14524. hdf4_count = 1; hdf4_count(1:7) = shape(values)
  14525. ! replace by optional arguments if necessary:
  14526. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  14527. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  14528. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  14529. ! test target type;
  14530. ! convert to required kind before entering sfWData,
  14531. ! otherwise segmentation faults on some machines ...
  14532. select case ( varp%xtype )
  14533. case ( MDF_BYTE )
  14534. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14535. values_int1 = int(values,kind=1)
  14536. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14537. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  14538. deallocate( values_int1 )
  14539. case ( MDF_SHORT )
  14540. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14541. values_int2 = int(values,kind=2)
  14542. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14543. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  14544. deallocate( values_int2 )
  14545. case ( MDF_INT )
  14546. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14547. values_int4 = int(values,kind=4)
  14548. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14549. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  14550. deallocate( values_int4 )
  14551. case ( MDF_FLOAT )
  14552. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14553. values_real4 = real(values,kind=4)
  14554. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14555. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  14556. deallocate( values_real4 )
  14557. case ( MDF_DOUBLE )
  14558. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14559. values_real8 = real(values,kind=8)
  14560. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14561. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  14562. deallocate( values_real8 )
  14563. case default
  14564. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  14565. TRACEBACK; status=1; return
  14566. end select
  14567. if ( status == FAIL ) then
  14568. write (gol,'("writing hdf4 data set:")'); call goErr
  14569. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  14570. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  14571. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  14572. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  14573. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  14574. write (gol,'(" size : ",i12)') size(values); call goErr
  14575. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  14576. TRACEBACK; status=1; return
  14577. end if
  14578. #endif
  14579. #ifdef with_hdf5_beta
  14580. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14581. case ( MDF_HDF5 )
  14582. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14583. ! check ...
  14584. if ( present(map ) ) then
  14585. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  14586. TRACEBACK; status=1; return
  14587. end if
  14588. ! fill offset (zero based!), stride, and count :
  14589. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  14590. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  14591. hdf5_count = 1 ! default singleton dimension
  14592. if ( present(count) ) then
  14593. hdf5_count(1:varp%ndim) = count
  14594. else
  14595. hdf5_count(1:7) = shape(values)
  14596. end if
  14597. ! new dimension:
  14598. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  14599. ! target data space in file:
  14600. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  14601. IF_NOT_OK_RETURN(status=1)
  14602. ! chunked dataset ?
  14603. if ( varp%hdf5_chunked ) then
  14604. ! reset extend:
  14605. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  14606. IF_NOT_OK_RETURN(status=1)
  14607. end if
  14608. ! select hyperslab:
  14609. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  14610. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  14611. stride=hdf5_stride(1:varp%ndim) )
  14612. ! write data:
  14613. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_INTEGER, values, &
  14614. int(shape(values),kind=HSIZE_T), status, &
  14615. file_space_id=hdf5_file_space_id )
  14616. IF_NOT_OK_RETURN(status=1)
  14617. ! release data space:
  14618. call H5SClose_f( hdf5_file_space_id, status )
  14619. IF_NOT_OK_RETURN(status=1)
  14620. #endif
  14621. #ifdef with_netcdf
  14622. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14623. case ( MDF_NETCDF, MDF_NETCDF4 )
  14624. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14625. ! test target type:
  14626. ! convert to required kind before entering NF90_Put_Var,
  14627. ! otherwise segmentation faults on some machines ...
  14628. select case ( varp%xtype )
  14629. case ( MDF_BYTE )
  14630. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14631. values_int1 = int(values,kind=1)
  14632. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  14633. start, count, stride, map )
  14634. IF_NF90_NOT_OK_RETURN(status=1)
  14635. deallocate( values_int1 )
  14636. case ( MDF_SHORT )
  14637. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14638. values_int2 = int(values,kind=2)
  14639. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  14640. start, count, stride, map )
  14641. IF_NF90_NOT_OK_RETURN(status=1)
  14642. deallocate( values_int2 )
  14643. case ( MDF_INT )
  14644. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14645. values_int4 = int(values,kind=4)
  14646. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  14647. start, count, stride, map )
  14648. IF_NF90_NOT_OK_RETURN(status=1)
  14649. deallocate( values_int4 )
  14650. case ( MDF_FLOAT )
  14651. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14652. values_real4 = real(values,kind=4)
  14653. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  14654. start, count, stride, map )
  14655. IF_NF90_NOT_OK_RETURN(status=1)
  14656. deallocate( values_real4 )
  14657. case ( MDF_DOUBLE )
  14658. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14659. values_real8 = real(values,kind=8)
  14660. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  14661. start, count, stride, map )
  14662. IF_NF90_NOT_OK_RETURN(status=1)
  14663. deallocate( values_real8 )
  14664. case default
  14665. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  14666. TRACEBACK; status=1; return
  14667. end select
  14668. ! just put; let netcdf library convert the right kind:
  14669. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  14670. ! start, count, stride, map )
  14671. !IF_NF90_NOT_OK_RETURN(status=1)
  14672. #endif
  14673. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14674. case default
  14675. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14676. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  14677. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  14678. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  14679. TRACEBACK; status=1; return
  14680. end select
  14681. end do ! file types
  14682. ! ok
  14683. status = 0
  14684. end subroutine MDF_Put_Var_i4_7d
  14685. ! ***
  14686. subroutine MDF_Get_Var_i4_7d( hid, varid, values, status, &
  14687. start, count, stride, map )
  14688. #ifdef with_netcdf
  14689. use NetCDF, only : NF90_Get_Var
  14690. #endif
  14691. ! --- in/out -------------------------------------
  14692. integer, intent(in) :: hid
  14693. integer, intent(in) :: varid
  14694. integer(4), intent(out) :: values(:,:,:,:,:,:,:)
  14695. integer, intent(out) :: status
  14696. integer, intent(in), optional :: start (:)
  14697. integer, intent(in), optional :: count (:)
  14698. integer, intent(in), optional :: stride(:)
  14699. integer, intent(in), optional :: map (:)
  14700. ! --- const --------------------------------------
  14701. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_i4_7d'
  14702. ! --- external -----------------------------------
  14703. #ifdef with_hdf4
  14704. integer(hdf4_wpi), external :: sfRData
  14705. #endif
  14706. ! --- local --------------------------------------
  14707. type(MDF_File), pointer :: filep
  14708. type(MDF_Var), pointer :: varp
  14709. integer :: iftype
  14710. integer :: ftype
  14711. #ifdef with_hdf4
  14712. integer :: hdf4_offset(MAX_RANK)
  14713. integer :: hdf4_stride(MAX_RANK)
  14714. integer :: hdf4_count(MAX_RANK)
  14715. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  14716. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  14717. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  14718. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  14719. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  14720. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  14721. #endif
  14722. ! --- begin --------------------------------------
  14723. ! pointer to file structure:
  14724. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  14725. IF_NOT_OK_RETURN(status=1)
  14726. ! pointer to variable structure:
  14727. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  14728. IF_NOT_OK_RETURN(status=1)
  14729. ! check ...
  14730. if ( size(shape(values)) > varp%ndim ) then
  14731. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  14732. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  14733. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  14734. TRACEBACK; status=1; return
  14735. end if
  14736. ! check ...
  14737. if ( present(start ) ) then
  14738. if ( size(start ) /= varp%ndim ) then
  14739. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14740. write (gol,'(" size start : ",i6)') size(start ); call goErr
  14741. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14742. TRACEBACK; status=1; return
  14743. end if
  14744. end if
  14745. if ( present(count ) ) then
  14746. if ( size(count ) /= varp%ndim ) then
  14747. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14748. write (gol,'(" size count : ",i6)') size(count ); call goErr
  14749. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14750. TRACEBACK; status=1; return
  14751. end if
  14752. end if
  14753. if ( present(stride ) ) then
  14754. if ( size(stride ) /= varp%ndim ) then
  14755. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14756. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  14757. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14758. TRACEBACK; status=1; return
  14759. end if
  14760. end if
  14761. if ( present(map ) ) then
  14762. if ( size(map ) /= varp%ndim ) then
  14763. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14764. write (gol,'(" size map : ",i6)') size(map ); call goErr
  14765. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14766. TRACEBACK; status=1; return
  14767. end if
  14768. end if
  14769. ! loop over file types:
  14770. do iftype = 1, filep%nftype
  14771. ! current type:
  14772. ftype = filep%ftypes(iftype)
  14773. ! select appropriate routine for each type:
  14774. select case ( ftype )
  14775. #ifdef with_hdf4
  14776. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14777. case ( MDF_HDF4 )
  14778. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14779. ! check ...
  14780. if ( present(map ) ) then
  14781. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  14782. TRACEBACK; status=1; return
  14783. end if
  14784. ! fill offset (zero based!), stride, and count :
  14785. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  14786. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  14787. hdf4_count = 1 ! default singleton dimension
  14788. hdf4_count(1:7) = shape(values)
  14789. ! test source type:
  14790. select case ( varp%hdf4_xtype )
  14791. case ( DFNT_INT8 )
  14792. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14793. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  14794. values = int(values_int1,kind=4)
  14795. deallocate( values_int1 )
  14796. case ( DFNT_INT16 )
  14797. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14798. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  14799. values = int(values_int2,kind=4)
  14800. deallocate( values_int2 )
  14801. case ( DFNT_INT32 )
  14802. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14803. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  14804. values = int(values_int4,kind=4)
  14805. deallocate( values_int4 )
  14806. case ( DFNT_INT64 )
  14807. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14808. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  14809. values = int(values_int8,kind=4)
  14810. deallocate( values_int8 )
  14811. case ( DFNT_FLOAT32 )
  14812. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14813. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  14814. values = int(values_real4,kind=4)
  14815. deallocate( values_real4 )
  14816. case ( DFNT_FLOAT64 )
  14817. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  14818. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  14819. values = int(values_real8,kind=4)
  14820. deallocate( values_real8 )
  14821. case default
  14822. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  14823. TRACEBACK; status=1; return
  14824. end select
  14825. if ( status == FAIL ) then
  14826. write (gol,'("reading hdf4 data set:")'); call goErr
  14827. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  14828. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  14829. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  14830. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  14831. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  14832. write (gol,'(" size : ",i6)') size(values); call goErr
  14833. TRACEBACK; status=1; return
  14834. end if
  14835. #endif
  14836. #ifdef with_netcdf
  14837. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14838. case ( MDF_NETCDF, MDF_NETCDF4 )
  14839. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14840. ! read values, converted automatically:
  14841. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  14842. start, count, stride, map )
  14843. IF_NF90_NOT_OK_RETURN(status=1)
  14844. #endif
  14845. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14846. case default
  14847. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14848. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  14849. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  14850. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  14851. TRACEBACK; status=1; return
  14852. end select
  14853. end do ! file types
  14854. ! ok
  14855. status = 0
  14856. end subroutine MDF_Get_Var_i4_7d
  14857. ! ***
  14858. subroutine MDF_Put_Var_r4_1d( hid, varid, values, status, &
  14859. start, count, stride, map )
  14860. #ifdef with_hdf5_beta
  14861. use HDF5, only : HID_T, HSIZE_T
  14862. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  14863. use HDF5, only : H5T_NATIVE_CHARACTER
  14864. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  14865. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  14866. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  14867. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  14868. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  14869. #endif
  14870. #ifdef with_netcdf
  14871. use NetCDF, only : NF90_Put_Var
  14872. #endif
  14873. ! --- in/out -------------------------------------
  14874. integer, intent(in) :: hid
  14875. integer, intent(in) :: varid
  14876. real(4), intent(in) :: values(:)
  14877. integer, intent(out) :: status
  14878. integer, intent(in), optional :: start (:)
  14879. integer, intent(in), optional :: count (:)
  14880. integer, intent(in), optional :: stride(:)
  14881. integer, intent(in), optional :: map (:)
  14882. ! --- const --------------------------------------
  14883. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_1d'
  14884. ! --- external -----------------------------------
  14885. #ifdef with_hdf4
  14886. integer(hdf4_wpi), external :: sfWData
  14887. #endif
  14888. ! --- local --------------------------------------
  14889. type(MDF_File), pointer :: filep
  14890. type(MDF_Var), pointer :: varp
  14891. integer :: iftype
  14892. integer :: ftype
  14893. #ifdef with_hdf4
  14894. integer :: hdf4_offset(MAX_RANK)
  14895. integer :: hdf4_stride(MAX_RANK)
  14896. integer :: hdf4_count(MAX_RANK)
  14897. #endif
  14898. #ifdef with_hdf5_beta
  14899. !integer(HID_T) :: hdf5_type_id
  14900. integer(HID_T) :: hdf5_file_space_id
  14901. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  14902. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  14903. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  14904. #endif
  14905. integer(1), allocatable :: values_int1(:)
  14906. integer(2), allocatable :: values_int2(:)
  14907. integer(4), allocatable :: values_int4(:)
  14908. integer(8), allocatable :: values_int8(:)
  14909. real(4), allocatable :: values_real4(:)
  14910. real(8), allocatable :: values_real8(:)
  14911. ! --- begin --------------------------------------
  14912. ! pointer to file structure:
  14913. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  14914. IF_NOT_OK_RETURN(status=1)
  14915. ! pointer to variable structure:
  14916. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  14917. IF_NOT_OK_RETURN(status=1)
  14918. ! check ...
  14919. if ( size(shape(values)) > varp%ndim ) then
  14920. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  14921. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  14922. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  14923. TRACEBACK; status=1; return
  14924. end if
  14925. ! check ...
  14926. if ( present(start ) ) then
  14927. if ( size(start ) /= varp%ndim ) then
  14928. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14929. write (gol,'(" size start : ",i6)') size(start ); call goErr
  14930. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14931. TRACEBACK; status=1; return
  14932. end if
  14933. end if
  14934. if ( present(count ) ) then
  14935. if ( size(count ) /= varp%ndim ) then
  14936. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14937. write (gol,'(" size count : ",i6)') size(count ); call goErr
  14938. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14939. TRACEBACK; status=1; return
  14940. end if
  14941. end if
  14942. if ( present(stride ) ) then
  14943. if ( size(stride ) /= varp%ndim ) then
  14944. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14945. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  14946. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14947. TRACEBACK; status=1; return
  14948. end if
  14949. end if
  14950. if ( present(map ) ) then
  14951. if ( size(map ) /= varp%ndim ) then
  14952. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  14953. write (gol,'(" size map : ",i6)') size(map ); call goErr
  14954. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  14955. TRACEBACK; status=1; return
  14956. end if
  14957. end if
  14958. ! loop over file types:
  14959. do iftype = 1, filep%nftype
  14960. ! current type:
  14961. ftype = filep%ftypes(iftype)
  14962. ! select appropriate routine for each type:
  14963. select case ( ftype )
  14964. #ifdef with_hdf4
  14965. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14966. case ( MDF_HDF4 )
  14967. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  14968. ! check ...
  14969. if ( present(map ) ) then
  14970. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  14971. TRACEBACK; status=1; return
  14972. end if
  14973. ! fill offset (zero based!) and stride with default values:
  14974. hdf4_offset = 0
  14975. hdf4_stride = 1
  14976. ! count is by default the shape; padd with singleton dimensions:
  14977. hdf4_count = 1; hdf4_count(1:1) = shape(values)
  14978. ! replace by optional arguments if necessary:
  14979. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  14980. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  14981. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  14982. ! test target type;
  14983. ! convert to required kind before entering sfWData,
  14984. ! otherwise segmentation faults on some machines ...
  14985. select case ( varp%xtype )
  14986. case ( MDF_BYTE )
  14987. allocate( values_int1(size(values,1)) )
  14988. values_int1 = int(values,kind=1)
  14989. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14990. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  14991. deallocate( values_int1 )
  14992. case ( MDF_SHORT )
  14993. allocate( values_int2(size(values,1)) )
  14994. values_int2 = int(values,kind=2)
  14995. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  14996. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  14997. deallocate( values_int2 )
  14998. case ( MDF_INT )
  14999. allocate( values_int4(size(values,1)) )
  15000. values_int4 = int(values,kind=4)
  15001. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15002. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  15003. deallocate( values_int4 )
  15004. case ( MDF_FLOAT )
  15005. allocate( values_real4(size(values,1)) )
  15006. values_real4 = real(values,kind=4)
  15007. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15008. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  15009. deallocate( values_real4 )
  15010. case ( MDF_DOUBLE )
  15011. allocate( values_real8(size(values,1)) )
  15012. values_real8 = real(values,kind=8)
  15013. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15014. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  15015. deallocate( values_real8 )
  15016. case default
  15017. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  15018. TRACEBACK; status=1; return
  15019. end select
  15020. if ( status == FAIL ) then
  15021. write (gol,'("writing hdf4 data set:")'); call goErr
  15022. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  15023. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  15024. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  15025. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  15026. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  15027. write (gol,'(" size : ",i12)') size(values); call goErr
  15028. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  15029. TRACEBACK; status=1; return
  15030. end if
  15031. #endif
  15032. #ifdef with_hdf5_beta
  15033. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15034. case ( MDF_HDF5 )
  15035. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15036. ! check ...
  15037. if ( present(map ) ) then
  15038. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  15039. TRACEBACK; status=1; return
  15040. end if
  15041. ! fill offset (zero based!), stride, and count :
  15042. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  15043. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  15044. hdf5_count = 1 ! default singleton dimension
  15045. if ( present(count) ) then
  15046. hdf5_count(1:varp%ndim) = count
  15047. else
  15048. hdf5_count(1:1) = shape(values)
  15049. end if
  15050. ! new dimension:
  15051. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  15052. ! target data space in file:
  15053. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  15054. IF_NOT_OK_RETURN(status=1)
  15055. ! chunked dataset ?
  15056. if ( varp%hdf5_chunked ) then
  15057. ! reset extend:
  15058. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  15059. IF_NOT_OK_RETURN(status=1)
  15060. end if
  15061. ! select hyperslab:
  15062. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  15063. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  15064. stride=hdf5_stride(1:varp%ndim) )
  15065. ! write data:
  15066. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  15067. int(shape(values),kind=HSIZE_T), status, &
  15068. file_space_id=hdf5_file_space_id )
  15069. IF_NOT_OK_RETURN(status=1)
  15070. ! release data space:
  15071. call H5SClose_f( hdf5_file_space_id, status )
  15072. IF_NOT_OK_RETURN(status=1)
  15073. #endif
  15074. #ifdef with_netcdf
  15075. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15076. case ( MDF_NETCDF, MDF_NETCDF4 )
  15077. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15078. ! test target type:
  15079. ! convert to required kind before entering NF90_Put_Var,
  15080. ! otherwise segmentation faults on some machines ...
  15081. select case ( varp%xtype )
  15082. case ( MDF_BYTE )
  15083. allocate( values_int1(size(values,1)) )
  15084. values_int1 = int(values,kind=1)
  15085. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  15086. start, count, stride, map )
  15087. IF_NF90_NOT_OK_RETURN(status=1)
  15088. deallocate( values_int1 )
  15089. case ( MDF_SHORT )
  15090. allocate( values_int2(size(values,1)) )
  15091. values_int2 = int(values,kind=2)
  15092. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  15093. start, count, stride, map )
  15094. IF_NF90_NOT_OK_RETURN(status=1)
  15095. deallocate( values_int2 )
  15096. case ( MDF_INT )
  15097. allocate( values_int4(size(values,1)) )
  15098. values_int4 = int(values,kind=4)
  15099. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  15100. start, count, stride, map )
  15101. IF_NF90_NOT_OK_RETURN(status=1)
  15102. deallocate( values_int4 )
  15103. case ( MDF_FLOAT )
  15104. allocate( values_real4(size(values,1)) )
  15105. values_real4 = real(values,kind=4)
  15106. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  15107. start, count, stride, map )
  15108. IF_NF90_NOT_OK_RETURN(status=1)
  15109. deallocate( values_real4 )
  15110. case ( MDF_DOUBLE )
  15111. allocate( values_real8(size(values,1)) )
  15112. values_real8 = real(values,kind=8)
  15113. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  15114. start, count, stride, map )
  15115. IF_NF90_NOT_OK_RETURN(status=1)
  15116. deallocate( values_real8 )
  15117. case default
  15118. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  15119. TRACEBACK; status=1; return
  15120. end select
  15121. ! just put; let netcdf library convert the right kind:
  15122. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  15123. ! start, count, stride, map )
  15124. !IF_NF90_NOT_OK_RETURN(status=1)
  15125. #endif
  15126. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15127. case default
  15128. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15129. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  15130. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  15131. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  15132. TRACEBACK; status=1; return
  15133. end select
  15134. end do ! file types
  15135. ! ok
  15136. status = 0
  15137. end subroutine MDF_Put_Var_r4_1d
  15138. ! ***
  15139. subroutine MDF_Get_Var_r4_1d( hid, varid, values, status, &
  15140. start, count, stride, map )
  15141. #ifdef with_netcdf
  15142. use NetCDF, only : NF90_Get_Var
  15143. #endif
  15144. ! --- in/out -------------------------------------
  15145. integer, intent(in) :: hid
  15146. integer, intent(in) :: varid
  15147. real(4), intent(out) :: values(:)
  15148. integer, intent(out) :: status
  15149. integer, intent(in), optional :: start (:)
  15150. integer, intent(in), optional :: count (:)
  15151. integer, intent(in), optional :: stride(:)
  15152. integer, intent(in), optional :: map (:)
  15153. ! --- const --------------------------------------
  15154. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_1d'
  15155. ! --- external -----------------------------------
  15156. #ifdef with_hdf4
  15157. integer(hdf4_wpi), external :: sfRData
  15158. #endif
  15159. ! --- local --------------------------------------
  15160. type(MDF_File), pointer :: filep
  15161. type(MDF_Var), pointer :: varp
  15162. integer :: iftype
  15163. integer :: ftype
  15164. #ifdef with_hdf4
  15165. integer :: hdf4_offset(MAX_RANK)
  15166. integer :: hdf4_stride(MAX_RANK)
  15167. integer :: hdf4_count(MAX_RANK)
  15168. integer(1), allocatable :: values_int1(:)
  15169. integer(2), allocatable :: values_int2(:)
  15170. integer(4), allocatable :: values_int4(:)
  15171. integer(8), allocatable :: values_int8(:)
  15172. real(4), allocatable :: values_real4(:)
  15173. real(8), allocatable :: values_real8(:)
  15174. #endif
  15175. ! --- begin --------------------------------------
  15176. ! pointer to file structure:
  15177. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  15178. IF_NOT_OK_RETURN(status=1)
  15179. ! pointer to variable structure:
  15180. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  15181. IF_NOT_OK_RETURN(status=1)
  15182. ! check ...
  15183. if ( size(shape(values)) > varp%ndim ) then
  15184. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  15185. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  15186. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  15187. TRACEBACK; status=1; return
  15188. end if
  15189. ! check ...
  15190. if ( present(start ) ) then
  15191. if ( size(start ) /= varp%ndim ) then
  15192. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15193. write (gol,'(" size start : ",i6)') size(start ); call goErr
  15194. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15195. TRACEBACK; status=1; return
  15196. end if
  15197. end if
  15198. if ( present(count ) ) then
  15199. if ( size(count ) /= varp%ndim ) then
  15200. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15201. write (gol,'(" size count : ",i6)') size(count ); call goErr
  15202. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15203. TRACEBACK; status=1; return
  15204. end if
  15205. end if
  15206. if ( present(stride ) ) then
  15207. if ( size(stride ) /= varp%ndim ) then
  15208. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15209. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  15210. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15211. TRACEBACK; status=1; return
  15212. end if
  15213. end if
  15214. if ( present(map ) ) then
  15215. if ( size(map ) /= varp%ndim ) then
  15216. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15217. write (gol,'(" size map : ",i6)') size(map ); call goErr
  15218. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15219. TRACEBACK; status=1; return
  15220. end if
  15221. end if
  15222. ! loop over file types:
  15223. do iftype = 1, filep%nftype
  15224. ! current type:
  15225. ftype = filep%ftypes(iftype)
  15226. ! select appropriate routine for each type:
  15227. select case ( ftype )
  15228. #ifdef with_hdf4
  15229. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15230. case ( MDF_HDF4 )
  15231. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15232. ! check ...
  15233. if ( present(map ) ) then
  15234. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  15235. TRACEBACK; status=1; return
  15236. end if
  15237. ! fill offset (zero based!), stride, and count :
  15238. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  15239. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  15240. hdf4_count = 1 ! default singleton dimension
  15241. hdf4_count(1:1) = shape(values)
  15242. ! test source type:
  15243. select case ( varp%hdf4_xtype )
  15244. case ( DFNT_INT8 )
  15245. allocate( values_int1(size(values,1)) )
  15246. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  15247. values = real(values_int1,kind=4)
  15248. deallocate( values_int1 )
  15249. case ( DFNT_INT16 )
  15250. allocate( values_int2(size(values,1)) )
  15251. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  15252. values = real(values_int2,kind=4)
  15253. deallocate( values_int2 )
  15254. case ( DFNT_INT32 )
  15255. allocate( values_int4(size(values,1)) )
  15256. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  15257. values = real(values_int4,kind=4)
  15258. deallocate( values_int4 )
  15259. case ( DFNT_INT64 )
  15260. allocate( values_int8(size(values,1)) )
  15261. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  15262. values = real(values_int8,kind=4)
  15263. deallocate( values_int8 )
  15264. case ( DFNT_FLOAT32 )
  15265. allocate( values_real4(size(values,1)) )
  15266. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  15267. values = real(values_real4,kind=4)
  15268. deallocate( values_real4 )
  15269. case ( DFNT_FLOAT64 )
  15270. allocate( values_real8(size(values,1)) )
  15271. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  15272. values = real(values_real8,kind=4)
  15273. deallocate( values_real8 )
  15274. case default
  15275. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  15276. TRACEBACK; status=1; return
  15277. end select
  15278. if ( status == FAIL ) then
  15279. write (gol,'("reading hdf4 data set:")'); call goErr
  15280. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  15281. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  15282. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  15283. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  15284. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  15285. write (gol,'(" size : ",i6)') size(values); call goErr
  15286. TRACEBACK; status=1; return
  15287. end if
  15288. #endif
  15289. #ifdef with_netcdf
  15290. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15291. case ( MDF_NETCDF, MDF_NETCDF4 )
  15292. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15293. ! read values, converted automatically:
  15294. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  15295. start, count, stride, map )
  15296. IF_NF90_NOT_OK_RETURN(status=1)
  15297. #endif
  15298. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15299. case default
  15300. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15301. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  15302. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  15303. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  15304. TRACEBACK; status=1; return
  15305. end select
  15306. end do ! file types
  15307. ! ok
  15308. status = 0
  15309. end subroutine MDF_Get_Var_r4_1d
  15310. ! ***
  15311. subroutine MDF_Put_Var_r4_2d( hid, varid, values, status, &
  15312. start, count, stride, map )
  15313. #ifdef with_hdf5_beta
  15314. use HDF5, only : HID_T, HSIZE_T
  15315. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  15316. use HDF5, only : H5T_NATIVE_CHARACTER
  15317. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  15318. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  15319. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  15320. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  15321. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  15322. #endif
  15323. #ifdef with_netcdf
  15324. use NetCDF, only : NF90_Put_Var
  15325. #endif
  15326. ! --- in/out -------------------------------------
  15327. integer, intent(in) :: hid
  15328. integer, intent(in) :: varid
  15329. real(4), intent(in) :: values(:,:)
  15330. integer, intent(out) :: status
  15331. integer, intent(in), optional :: start (:)
  15332. integer, intent(in), optional :: count (:)
  15333. integer, intent(in), optional :: stride(:)
  15334. integer, intent(in), optional :: map (:)
  15335. ! --- const --------------------------------------
  15336. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_2d'
  15337. ! --- external -----------------------------------
  15338. #ifdef with_hdf4
  15339. integer(hdf4_wpi), external :: sfWData
  15340. #endif
  15341. ! --- local --------------------------------------
  15342. type(MDF_File), pointer :: filep
  15343. type(MDF_Var), pointer :: varp
  15344. integer :: iftype
  15345. integer :: ftype
  15346. #ifdef with_hdf4
  15347. integer :: hdf4_offset(MAX_RANK)
  15348. integer :: hdf4_stride(MAX_RANK)
  15349. integer :: hdf4_count(MAX_RANK)
  15350. #endif
  15351. #ifdef with_hdf5_beta
  15352. !integer(HID_T) :: hdf5_type_id
  15353. integer(HID_T) :: hdf5_file_space_id
  15354. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  15355. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  15356. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  15357. #endif
  15358. integer(1), allocatable :: values_int1(:,:)
  15359. integer(2), allocatable :: values_int2(:,:)
  15360. integer(4), allocatable :: values_int4(:,:)
  15361. integer(8), allocatable :: values_int8(:,:)
  15362. real(4), allocatable :: values_real4(:,:)
  15363. real(8), allocatable :: values_real8(:,:)
  15364. ! --- begin --------------------------------------
  15365. ! pointer to file structure:
  15366. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  15367. IF_NOT_OK_RETURN(status=1)
  15368. ! pointer to variable structure:
  15369. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  15370. IF_NOT_OK_RETURN(status=1)
  15371. ! check ...
  15372. if ( size(shape(values)) > varp%ndim ) then
  15373. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  15374. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  15375. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  15376. TRACEBACK; status=1; return
  15377. end if
  15378. ! check ...
  15379. if ( present(start ) ) then
  15380. if ( size(start ) /= varp%ndim ) then
  15381. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15382. write (gol,'(" size start : ",i6)') size(start ); call goErr
  15383. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15384. TRACEBACK; status=1; return
  15385. end if
  15386. end if
  15387. if ( present(count ) ) then
  15388. if ( size(count ) /= varp%ndim ) then
  15389. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15390. write (gol,'(" size count : ",i6)') size(count ); call goErr
  15391. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15392. TRACEBACK; status=1; return
  15393. end if
  15394. end if
  15395. if ( present(stride ) ) then
  15396. if ( size(stride ) /= varp%ndim ) then
  15397. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15398. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  15399. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15400. TRACEBACK; status=1; return
  15401. end if
  15402. end if
  15403. if ( present(map ) ) then
  15404. if ( size(map ) /= varp%ndim ) then
  15405. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15406. write (gol,'(" size map : ",i6)') size(map ); call goErr
  15407. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15408. TRACEBACK; status=1; return
  15409. end if
  15410. end if
  15411. ! loop over file types:
  15412. do iftype = 1, filep%nftype
  15413. ! current type:
  15414. ftype = filep%ftypes(iftype)
  15415. ! select appropriate routine for each type:
  15416. select case ( ftype )
  15417. #ifdef with_hdf4
  15418. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15419. case ( MDF_HDF4 )
  15420. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15421. ! check ...
  15422. if ( present(map ) ) then
  15423. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  15424. TRACEBACK; status=1; return
  15425. end if
  15426. ! fill offset (zero based!) and stride with default values:
  15427. hdf4_offset = 0
  15428. hdf4_stride = 1
  15429. ! count is by default the shape; padd with singleton dimensions:
  15430. hdf4_count = 1; hdf4_count(1:2) = shape(values)
  15431. ! replace by optional arguments if necessary:
  15432. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  15433. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  15434. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  15435. ! test target type;
  15436. ! convert to required kind before entering sfWData,
  15437. ! otherwise segmentation faults on some machines ...
  15438. select case ( varp%xtype )
  15439. case ( MDF_BYTE )
  15440. allocate( values_int1(size(values,1),size(values,2)) )
  15441. values_int1 = int(values,kind=1)
  15442. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15443. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  15444. deallocate( values_int1 )
  15445. case ( MDF_SHORT )
  15446. allocate( values_int2(size(values,1),size(values,2)) )
  15447. values_int2 = int(values,kind=2)
  15448. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15449. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  15450. deallocate( values_int2 )
  15451. case ( MDF_INT )
  15452. allocate( values_int4(size(values,1),size(values,2)) )
  15453. values_int4 = int(values,kind=4)
  15454. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15455. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  15456. deallocate( values_int4 )
  15457. case ( MDF_FLOAT )
  15458. allocate( values_real4(size(values,1),size(values,2)) )
  15459. values_real4 = real(values,kind=4)
  15460. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15461. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  15462. deallocate( values_real4 )
  15463. case ( MDF_DOUBLE )
  15464. allocate( values_real8(size(values,1),size(values,2)) )
  15465. values_real8 = real(values,kind=8)
  15466. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15467. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  15468. deallocate( values_real8 )
  15469. case default
  15470. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  15471. TRACEBACK; status=1; return
  15472. end select
  15473. if ( status == FAIL ) then
  15474. write (gol,'("writing hdf4 data set:")'); call goErr
  15475. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  15476. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  15477. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  15478. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  15479. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  15480. write (gol,'(" size : ",i12)') size(values); call goErr
  15481. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  15482. TRACEBACK; status=1; return
  15483. end if
  15484. #endif
  15485. #ifdef with_hdf5_beta
  15486. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15487. case ( MDF_HDF5 )
  15488. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15489. ! check ...
  15490. if ( present(map ) ) then
  15491. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  15492. TRACEBACK; status=1; return
  15493. end if
  15494. ! fill offset (zero based!), stride, and count :
  15495. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  15496. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  15497. hdf5_count = 1 ! default singleton dimension
  15498. if ( present(count) ) then
  15499. hdf5_count(1:varp%ndim) = count
  15500. else
  15501. hdf5_count(1:2) = shape(values)
  15502. end if
  15503. ! new dimension:
  15504. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  15505. ! target data space in file:
  15506. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  15507. IF_NOT_OK_RETURN(status=1)
  15508. ! chunked dataset ?
  15509. if ( varp%hdf5_chunked ) then
  15510. ! reset extend:
  15511. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  15512. IF_NOT_OK_RETURN(status=1)
  15513. end if
  15514. ! select hyperslab:
  15515. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  15516. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  15517. stride=hdf5_stride(1:varp%ndim) )
  15518. ! write data:
  15519. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  15520. int(shape(values),kind=HSIZE_T), status, &
  15521. file_space_id=hdf5_file_space_id )
  15522. IF_NOT_OK_RETURN(status=1)
  15523. ! release data space:
  15524. call H5SClose_f( hdf5_file_space_id, status )
  15525. IF_NOT_OK_RETURN(status=1)
  15526. #endif
  15527. #ifdef with_netcdf
  15528. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15529. case ( MDF_NETCDF, MDF_NETCDF4 )
  15530. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15531. ! test target type:
  15532. ! convert to required kind before entering NF90_Put_Var,
  15533. ! otherwise segmentation faults on some machines ...
  15534. select case ( varp%xtype )
  15535. case ( MDF_BYTE )
  15536. allocate( values_int1(size(values,1),size(values,2)) )
  15537. values_int1 = int(values,kind=1)
  15538. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  15539. start, count, stride, map )
  15540. IF_NF90_NOT_OK_RETURN(status=1)
  15541. deallocate( values_int1 )
  15542. case ( MDF_SHORT )
  15543. allocate( values_int2(size(values,1),size(values,2)) )
  15544. values_int2 = int(values,kind=2)
  15545. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  15546. start, count, stride, map )
  15547. IF_NF90_NOT_OK_RETURN(status=1)
  15548. deallocate( values_int2 )
  15549. case ( MDF_INT )
  15550. allocate( values_int4(size(values,1),size(values,2)) )
  15551. values_int4 = int(values,kind=4)
  15552. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  15553. start, count, stride, map )
  15554. IF_NF90_NOT_OK_RETURN(status=1)
  15555. deallocate( values_int4 )
  15556. case ( MDF_FLOAT )
  15557. allocate( values_real4(size(values,1),size(values,2)) )
  15558. values_real4 = real(values,kind=4)
  15559. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  15560. start, count, stride, map )
  15561. IF_NF90_NOT_OK_RETURN(status=1)
  15562. deallocate( values_real4 )
  15563. case ( MDF_DOUBLE )
  15564. allocate( values_real8(size(values,1),size(values,2)) )
  15565. values_real8 = real(values,kind=8)
  15566. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  15567. start, count, stride, map )
  15568. IF_NF90_NOT_OK_RETURN(status=1)
  15569. deallocate( values_real8 )
  15570. case default
  15571. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  15572. TRACEBACK; status=1; return
  15573. end select
  15574. ! just put; let netcdf library convert the right kind:
  15575. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  15576. ! start, count, stride, map )
  15577. !IF_NF90_NOT_OK_RETURN(status=1)
  15578. #endif
  15579. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15580. case default
  15581. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15582. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  15583. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  15584. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  15585. TRACEBACK; status=1; return
  15586. end select
  15587. end do ! file types
  15588. ! ok
  15589. status = 0
  15590. end subroutine MDF_Put_Var_r4_2d
  15591. ! ***
  15592. subroutine MDF_Get_Var_r4_2d( hid, varid, values, status, &
  15593. start, count, stride, map )
  15594. #ifdef with_netcdf
  15595. use NetCDF, only : NF90_Get_Var
  15596. #endif
  15597. ! --- in/out -------------------------------------
  15598. integer, intent(in) :: hid
  15599. integer, intent(in) :: varid
  15600. real(4), intent(out) :: values(:,:)
  15601. integer, intent(out) :: status
  15602. integer, intent(in), optional :: start (:)
  15603. integer, intent(in), optional :: count (:)
  15604. integer, intent(in), optional :: stride(:)
  15605. integer, intent(in), optional :: map (:)
  15606. ! --- const --------------------------------------
  15607. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_2d'
  15608. ! --- external -----------------------------------
  15609. #ifdef with_hdf4
  15610. integer(hdf4_wpi), external :: sfRData
  15611. #endif
  15612. ! --- local --------------------------------------
  15613. type(MDF_File), pointer :: filep
  15614. type(MDF_Var), pointer :: varp
  15615. integer :: iftype
  15616. integer :: ftype
  15617. #ifdef with_hdf4
  15618. integer :: hdf4_offset(MAX_RANK)
  15619. integer :: hdf4_stride(MAX_RANK)
  15620. integer :: hdf4_count(MAX_RANK)
  15621. integer(1), allocatable :: values_int1(:,:)
  15622. integer(2), allocatable :: values_int2(:,:)
  15623. integer(4), allocatable :: values_int4(:,:)
  15624. integer(8), allocatable :: values_int8(:,:)
  15625. real(4), allocatable :: values_real4(:,:)
  15626. real(8), allocatable :: values_real8(:,:)
  15627. #endif
  15628. ! --- begin --------------------------------------
  15629. ! pointer to file structure:
  15630. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  15631. IF_NOT_OK_RETURN(status=1)
  15632. ! pointer to variable structure:
  15633. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  15634. IF_NOT_OK_RETURN(status=1)
  15635. ! check ...
  15636. if ( size(shape(values)) > varp%ndim ) then
  15637. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  15638. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  15639. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  15640. TRACEBACK; status=1; return
  15641. end if
  15642. ! check ...
  15643. if ( present(start ) ) then
  15644. if ( size(start ) /= varp%ndim ) then
  15645. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15646. write (gol,'(" size start : ",i6)') size(start ); call goErr
  15647. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15648. TRACEBACK; status=1; return
  15649. end if
  15650. end if
  15651. if ( present(count ) ) then
  15652. if ( size(count ) /= varp%ndim ) then
  15653. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15654. write (gol,'(" size count : ",i6)') size(count ); call goErr
  15655. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15656. TRACEBACK; status=1; return
  15657. end if
  15658. end if
  15659. if ( present(stride ) ) then
  15660. if ( size(stride ) /= varp%ndim ) then
  15661. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15662. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  15663. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15664. TRACEBACK; status=1; return
  15665. end if
  15666. end if
  15667. if ( present(map ) ) then
  15668. if ( size(map ) /= varp%ndim ) then
  15669. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15670. write (gol,'(" size map : ",i6)') size(map ); call goErr
  15671. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15672. TRACEBACK; status=1; return
  15673. end if
  15674. end if
  15675. ! loop over file types:
  15676. do iftype = 1, filep%nftype
  15677. ! current type:
  15678. ftype = filep%ftypes(iftype)
  15679. ! select appropriate routine for each type:
  15680. select case ( ftype )
  15681. #ifdef with_hdf4
  15682. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15683. case ( MDF_HDF4 )
  15684. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15685. ! check ...
  15686. if ( present(map ) ) then
  15687. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  15688. TRACEBACK; status=1; return
  15689. end if
  15690. ! fill offset (zero based!), stride, and count :
  15691. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  15692. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  15693. hdf4_count = 1 ! default singleton dimension
  15694. hdf4_count(1:2) = shape(values)
  15695. ! test source type:
  15696. select case ( varp%hdf4_xtype )
  15697. case ( DFNT_INT8 )
  15698. allocate( values_int1(size(values,1),size(values,2)) )
  15699. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  15700. values = real(values_int1,kind=4)
  15701. deallocate( values_int1 )
  15702. case ( DFNT_INT16 )
  15703. allocate( values_int2(size(values,1),size(values,2)) )
  15704. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  15705. values = real(values_int2,kind=4)
  15706. deallocate( values_int2 )
  15707. case ( DFNT_INT32 )
  15708. allocate( values_int4(size(values,1),size(values,2)) )
  15709. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  15710. values = real(values_int4,kind=4)
  15711. deallocate( values_int4 )
  15712. case ( DFNT_INT64 )
  15713. allocate( values_int8(size(values,1),size(values,2)) )
  15714. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  15715. values = real(values_int8,kind=4)
  15716. deallocate( values_int8 )
  15717. case ( DFNT_FLOAT32 )
  15718. allocate( values_real4(size(values,1),size(values,2)) )
  15719. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  15720. values = real(values_real4,kind=4)
  15721. deallocate( values_real4 )
  15722. case ( DFNT_FLOAT64 )
  15723. allocate( values_real8(size(values,1),size(values,2)) )
  15724. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  15725. values = real(values_real8,kind=4)
  15726. deallocate( values_real8 )
  15727. case default
  15728. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  15729. TRACEBACK; status=1; return
  15730. end select
  15731. if ( status == FAIL ) then
  15732. write (gol,'("reading hdf4 data set:")'); call goErr
  15733. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  15734. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  15735. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  15736. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  15737. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  15738. write (gol,'(" size : ",i6)') size(values); call goErr
  15739. TRACEBACK; status=1; return
  15740. end if
  15741. #endif
  15742. #ifdef with_netcdf
  15743. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15744. case ( MDF_NETCDF, MDF_NETCDF4 )
  15745. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15746. ! read values, converted automatically:
  15747. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  15748. start, count, stride, map )
  15749. IF_NF90_NOT_OK_RETURN(status=1)
  15750. #endif
  15751. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15752. case default
  15753. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15754. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  15755. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  15756. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  15757. TRACEBACK; status=1; return
  15758. end select
  15759. end do ! file types
  15760. ! ok
  15761. status = 0
  15762. end subroutine MDF_Get_Var_r4_2d
  15763. ! ***
  15764. subroutine MDF_Put_Var_r4_3d( hid, varid, values, status, &
  15765. start, count, stride, map )
  15766. #ifdef with_hdf5_beta
  15767. use HDF5, only : HID_T, HSIZE_T
  15768. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  15769. use HDF5, only : H5T_NATIVE_CHARACTER
  15770. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  15771. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  15772. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  15773. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  15774. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  15775. #endif
  15776. #ifdef with_netcdf
  15777. use NetCDF, only : NF90_Put_Var
  15778. #endif
  15779. ! --- in/out -------------------------------------
  15780. integer, intent(in) :: hid
  15781. integer, intent(in) :: varid
  15782. real(4), intent(in) :: values(:,:,:)
  15783. integer, intent(out) :: status
  15784. integer, intent(in), optional :: start (:)
  15785. integer, intent(in), optional :: count (:)
  15786. integer, intent(in), optional :: stride(:)
  15787. integer, intent(in), optional :: map (:)
  15788. ! --- const --------------------------------------
  15789. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_3d'
  15790. ! --- external -----------------------------------
  15791. #ifdef with_hdf4
  15792. integer(hdf4_wpi), external :: sfWData
  15793. #endif
  15794. ! --- local --------------------------------------
  15795. type(MDF_File), pointer :: filep
  15796. type(MDF_Var), pointer :: varp
  15797. integer :: iftype
  15798. integer :: ftype
  15799. #ifdef with_hdf4
  15800. integer :: hdf4_offset(MAX_RANK)
  15801. integer :: hdf4_stride(MAX_RANK)
  15802. integer :: hdf4_count(MAX_RANK)
  15803. #endif
  15804. #ifdef with_hdf5_beta
  15805. !integer(HID_T) :: hdf5_type_id
  15806. integer(HID_T) :: hdf5_file_space_id
  15807. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  15808. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  15809. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  15810. #endif
  15811. integer(1), allocatable :: values_int1(:,:,:)
  15812. integer(2), allocatable :: values_int2(:,:,:)
  15813. integer(4), allocatable :: values_int4(:,:,:)
  15814. integer(8), allocatable :: values_int8(:,:,:)
  15815. real(4), allocatable :: values_real4(:,:,:)
  15816. real(8), allocatable :: values_real8(:,:,:)
  15817. ! --- begin --------------------------------------
  15818. ! pointer to file structure:
  15819. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  15820. IF_NOT_OK_RETURN(status=1)
  15821. ! pointer to variable structure:
  15822. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  15823. IF_NOT_OK_RETURN(status=1)
  15824. ! check ...
  15825. if ( size(shape(values)) > varp%ndim ) then
  15826. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  15827. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  15828. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  15829. TRACEBACK; status=1; return
  15830. end if
  15831. ! check ...
  15832. if ( present(start ) ) then
  15833. if ( size(start ) /= varp%ndim ) then
  15834. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15835. write (gol,'(" size start : ",i6)') size(start ); call goErr
  15836. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15837. TRACEBACK; status=1; return
  15838. end if
  15839. end if
  15840. if ( present(count ) ) then
  15841. if ( size(count ) /= varp%ndim ) then
  15842. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15843. write (gol,'(" size count : ",i6)') size(count ); call goErr
  15844. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15845. TRACEBACK; status=1; return
  15846. end if
  15847. end if
  15848. if ( present(stride ) ) then
  15849. if ( size(stride ) /= varp%ndim ) then
  15850. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15851. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  15852. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15853. TRACEBACK; status=1; return
  15854. end if
  15855. end if
  15856. if ( present(map ) ) then
  15857. if ( size(map ) /= varp%ndim ) then
  15858. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  15859. write (gol,'(" size map : ",i6)') size(map ); call goErr
  15860. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  15861. TRACEBACK; status=1; return
  15862. end if
  15863. end if
  15864. ! loop over file types:
  15865. do iftype = 1, filep%nftype
  15866. ! current type:
  15867. ftype = filep%ftypes(iftype)
  15868. ! select appropriate routine for each type:
  15869. select case ( ftype )
  15870. #ifdef with_hdf4
  15871. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15872. case ( MDF_HDF4 )
  15873. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15874. ! check ...
  15875. if ( present(map ) ) then
  15876. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  15877. TRACEBACK; status=1; return
  15878. end if
  15879. ! fill offset (zero based!) and stride with default values:
  15880. hdf4_offset = 0
  15881. hdf4_stride = 1
  15882. ! count is by default the shape; padd with singleton dimensions:
  15883. hdf4_count = 1; hdf4_count(1:3) = shape(values)
  15884. ! replace by optional arguments if necessary:
  15885. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  15886. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  15887. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  15888. ! test target type;
  15889. ! convert to required kind before entering sfWData,
  15890. ! otherwise segmentation faults on some machines ...
  15891. select case ( varp%xtype )
  15892. case ( MDF_BYTE )
  15893. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  15894. values_int1 = int(values,kind=1)
  15895. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15896. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  15897. deallocate( values_int1 )
  15898. case ( MDF_SHORT )
  15899. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  15900. values_int2 = int(values,kind=2)
  15901. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15902. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  15903. deallocate( values_int2 )
  15904. case ( MDF_INT )
  15905. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  15906. values_int4 = int(values,kind=4)
  15907. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15908. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  15909. deallocate( values_int4 )
  15910. case ( MDF_FLOAT )
  15911. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  15912. values_real4 = real(values,kind=4)
  15913. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15914. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  15915. deallocate( values_real4 )
  15916. case ( MDF_DOUBLE )
  15917. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  15918. values_real8 = real(values,kind=8)
  15919. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  15920. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  15921. deallocate( values_real8 )
  15922. case default
  15923. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  15924. TRACEBACK; status=1; return
  15925. end select
  15926. if ( status == FAIL ) then
  15927. write (gol,'("writing hdf4 data set:")'); call goErr
  15928. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  15929. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  15930. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  15931. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  15932. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  15933. write (gol,'(" size : ",i12)') size(values); call goErr
  15934. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  15935. TRACEBACK; status=1; return
  15936. end if
  15937. #endif
  15938. #ifdef with_hdf5_beta
  15939. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15940. case ( MDF_HDF5 )
  15941. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15942. ! check ...
  15943. if ( present(map ) ) then
  15944. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  15945. TRACEBACK; status=1; return
  15946. end if
  15947. ! fill offset (zero based!), stride, and count :
  15948. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  15949. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  15950. hdf5_count = 1 ! default singleton dimension
  15951. if ( present(count) ) then
  15952. hdf5_count(1:varp%ndim) = count
  15953. else
  15954. hdf5_count(1:3) = shape(values)
  15955. end if
  15956. ! new dimension:
  15957. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  15958. ! target data space in file:
  15959. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  15960. IF_NOT_OK_RETURN(status=1)
  15961. ! chunked dataset ?
  15962. if ( varp%hdf5_chunked ) then
  15963. ! reset extend:
  15964. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  15965. IF_NOT_OK_RETURN(status=1)
  15966. end if
  15967. ! select hyperslab:
  15968. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  15969. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  15970. stride=hdf5_stride(1:varp%ndim) )
  15971. ! write data:
  15972. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  15973. int(shape(values),kind=HSIZE_T), status, &
  15974. file_space_id=hdf5_file_space_id )
  15975. IF_NOT_OK_RETURN(status=1)
  15976. ! release data space:
  15977. call H5SClose_f( hdf5_file_space_id, status )
  15978. IF_NOT_OK_RETURN(status=1)
  15979. #endif
  15980. #ifdef with_netcdf
  15981. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15982. case ( MDF_NETCDF, MDF_NETCDF4 )
  15983. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  15984. ! test target type:
  15985. ! convert to required kind before entering NF90_Put_Var,
  15986. ! otherwise segmentation faults on some machines ...
  15987. select case ( varp%xtype )
  15988. case ( MDF_BYTE )
  15989. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  15990. values_int1 = int(values,kind=1)
  15991. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  15992. start, count, stride, map )
  15993. IF_NF90_NOT_OK_RETURN(status=1)
  15994. deallocate( values_int1 )
  15995. case ( MDF_SHORT )
  15996. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  15997. values_int2 = int(values,kind=2)
  15998. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  15999. start, count, stride, map )
  16000. IF_NF90_NOT_OK_RETURN(status=1)
  16001. deallocate( values_int2 )
  16002. case ( MDF_INT )
  16003. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  16004. values_int4 = int(values,kind=4)
  16005. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  16006. start, count, stride, map )
  16007. IF_NF90_NOT_OK_RETURN(status=1)
  16008. deallocate( values_int4 )
  16009. case ( MDF_FLOAT )
  16010. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  16011. values_real4 = real(values,kind=4)
  16012. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  16013. start, count, stride, map )
  16014. IF_NF90_NOT_OK_RETURN(status=1)
  16015. deallocate( values_real4 )
  16016. case ( MDF_DOUBLE )
  16017. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  16018. values_real8 = real(values,kind=8)
  16019. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  16020. start, count, stride, map )
  16021. IF_NF90_NOT_OK_RETURN(status=1)
  16022. deallocate( values_real8 )
  16023. case default
  16024. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  16025. TRACEBACK; status=1; return
  16026. end select
  16027. ! just put; let netcdf library convert the right kind:
  16028. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  16029. ! start, count, stride, map )
  16030. !IF_NF90_NOT_OK_RETURN(status=1)
  16031. #endif
  16032. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16033. case default
  16034. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16035. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  16036. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  16037. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  16038. TRACEBACK; status=1; return
  16039. end select
  16040. end do ! file types
  16041. ! ok
  16042. status = 0
  16043. end subroutine MDF_Put_Var_r4_3d
  16044. ! ***
  16045. subroutine MDF_Get_Var_r4_3d( hid, varid, values, status, &
  16046. start, count, stride, map )
  16047. #ifdef with_netcdf
  16048. use NetCDF, only : NF90_Get_Var
  16049. #endif
  16050. ! --- in/out -------------------------------------
  16051. integer, intent(in) :: hid
  16052. integer, intent(in) :: varid
  16053. real(4), intent(out) :: values(:,:,:)
  16054. integer, intent(out) :: status
  16055. integer, intent(in), optional :: start (:)
  16056. integer, intent(in), optional :: count (:)
  16057. integer, intent(in), optional :: stride(:)
  16058. integer, intent(in), optional :: map (:)
  16059. ! --- const --------------------------------------
  16060. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_3d'
  16061. ! --- external -----------------------------------
  16062. #ifdef with_hdf4
  16063. integer(hdf4_wpi), external :: sfRData
  16064. #endif
  16065. ! --- local --------------------------------------
  16066. type(MDF_File), pointer :: filep
  16067. type(MDF_Var), pointer :: varp
  16068. integer :: iftype
  16069. integer :: ftype
  16070. #ifdef with_hdf4
  16071. integer :: hdf4_offset(MAX_RANK)
  16072. integer :: hdf4_stride(MAX_RANK)
  16073. integer :: hdf4_count(MAX_RANK)
  16074. integer(1), allocatable :: values_int1(:,:,:)
  16075. integer(2), allocatable :: values_int2(:,:,:)
  16076. integer(4), allocatable :: values_int4(:,:,:)
  16077. integer(8), allocatable :: values_int8(:,:,:)
  16078. real(4), allocatable :: values_real4(:,:,:)
  16079. real(8), allocatable :: values_real8(:,:,:)
  16080. #endif
  16081. ! --- begin --------------------------------------
  16082. ! pointer to file structure:
  16083. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  16084. IF_NOT_OK_RETURN(status=1)
  16085. ! pointer to variable structure:
  16086. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  16087. IF_NOT_OK_RETURN(status=1)
  16088. ! check ...
  16089. if ( size(shape(values)) > varp%ndim ) then
  16090. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  16091. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  16092. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  16093. TRACEBACK; status=1; return
  16094. end if
  16095. ! check ...
  16096. if ( present(start ) ) then
  16097. if ( size(start ) /= varp%ndim ) then
  16098. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16099. write (gol,'(" size start : ",i6)') size(start ); call goErr
  16100. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16101. TRACEBACK; status=1; return
  16102. end if
  16103. end if
  16104. if ( present(count ) ) then
  16105. if ( size(count ) /= varp%ndim ) then
  16106. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16107. write (gol,'(" size count : ",i6)') size(count ); call goErr
  16108. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16109. TRACEBACK; status=1; return
  16110. end if
  16111. end if
  16112. if ( present(stride ) ) then
  16113. if ( size(stride ) /= varp%ndim ) then
  16114. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16115. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  16116. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16117. TRACEBACK; status=1; return
  16118. end if
  16119. end if
  16120. if ( present(map ) ) then
  16121. if ( size(map ) /= varp%ndim ) then
  16122. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16123. write (gol,'(" size map : ",i6)') size(map ); call goErr
  16124. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16125. TRACEBACK; status=1; return
  16126. end if
  16127. end if
  16128. ! loop over file types:
  16129. do iftype = 1, filep%nftype
  16130. ! current type:
  16131. ftype = filep%ftypes(iftype)
  16132. ! select appropriate routine for each type:
  16133. select case ( ftype )
  16134. #ifdef with_hdf4
  16135. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16136. case ( MDF_HDF4 )
  16137. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16138. ! check ...
  16139. if ( present(map ) ) then
  16140. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  16141. TRACEBACK; status=1; return
  16142. end if
  16143. ! fill offset (zero based!), stride, and count :
  16144. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  16145. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  16146. hdf4_count = 1 ! default singleton dimension
  16147. hdf4_count(1:3) = shape(values)
  16148. ! test source type:
  16149. select case ( varp%hdf4_xtype )
  16150. case ( DFNT_INT8 )
  16151. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  16152. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  16153. values = real(values_int1,kind=4)
  16154. deallocate( values_int1 )
  16155. case ( DFNT_INT16 )
  16156. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  16157. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  16158. values = real(values_int2,kind=4)
  16159. deallocate( values_int2 )
  16160. case ( DFNT_INT32 )
  16161. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  16162. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  16163. values = real(values_int4,kind=4)
  16164. deallocate( values_int4 )
  16165. case ( DFNT_INT64 )
  16166. allocate( values_int8(size(values,1),size(values,2),size(values,3)) )
  16167. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  16168. values = real(values_int8,kind=4)
  16169. deallocate( values_int8 )
  16170. case ( DFNT_FLOAT32 )
  16171. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  16172. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  16173. values = real(values_real4,kind=4)
  16174. deallocate( values_real4 )
  16175. case ( DFNT_FLOAT64 )
  16176. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  16177. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  16178. values = real(values_real8,kind=4)
  16179. deallocate( values_real8 )
  16180. case default
  16181. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  16182. TRACEBACK; status=1; return
  16183. end select
  16184. if ( status == FAIL ) then
  16185. write (gol,'("reading hdf4 data set:")'); call goErr
  16186. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  16187. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  16188. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  16189. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  16190. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  16191. write (gol,'(" size : ",i6)') size(values); call goErr
  16192. TRACEBACK; status=1; return
  16193. end if
  16194. #endif
  16195. #ifdef with_netcdf
  16196. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16197. case ( MDF_NETCDF, MDF_NETCDF4 )
  16198. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16199. ! read values, converted automatically:
  16200. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  16201. start, count, stride, map )
  16202. IF_NF90_NOT_OK_RETURN(status=1)
  16203. #endif
  16204. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16205. case default
  16206. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16207. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  16208. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  16209. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  16210. TRACEBACK; status=1; return
  16211. end select
  16212. end do ! file types
  16213. ! ok
  16214. status = 0
  16215. end subroutine MDF_Get_Var_r4_3d
  16216. ! ***
  16217. subroutine MDF_Put_Var_r4_4d( hid, varid, values, status, &
  16218. start, count, stride, map )
  16219. #ifdef with_hdf5_beta
  16220. use HDF5, only : HID_T, HSIZE_T
  16221. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  16222. use HDF5, only : H5T_NATIVE_CHARACTER
  16223. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  16224. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  16225. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  16226. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  16227. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  16228. #endif
  16229. #ifdef with_netcdf
  16230. use NetCDF, only : NF90_Put_Var
  16231. #endif
  16232. ! --- in/out -------------------------------------
  16233. integer, intent(in) :: hid
  16234. integer, intent(in) :: varid
  16235. real(4), intent(in) :: values(:,:,:,:)
  16236. integer, intent(out) :: status
  16237. integer, intent(in), optional :: start (:)
  16238. integer, intent(in), optional :: count (:)
  16239. integer, intent(in), optional :: stride(:)
  16240. integer, intent(in), optional :: map (:)
  16241. ! --- const --------------------------------------
  16242. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_4d'
  16243. ! --- external -----------------------------------
  16244. #ifdef with_hdf4
  16245. integer(hdf4_wpi), external :: sfWData
  16246. #endif
  16247. ! --- local --------------------------------------
  16248. type(MDF_File), pointer :: filep
  16249. type(MDF_Var), pointer :: varp
  16250. integer :: iftype
  16251. integer :: ftype
  16252. #ifdef with_hdf4
  16253. integer :: hdf4_offset(MAX_RANK)
  16254. integer :: hdf4_stride(MAX_RANK)
  16255. integer :: hdf4_count(MAX_RANK)
  16256. #endif
  16257. #ifdef with_hdf5_beta
  16258. !integer(HID_T) :: hdf5_type_id
  16259. integer(HID_T) :: hdf5_file_space_id
  16260. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  16261. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  16262. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  16263. #endif
  16264. integer(1), allocatable :: values_int1(:,:,:,:)
  16265. integer(2), allocatable :: values_int2(:,:,:,:)
  16266. integer(4), allocatable :: values_int4(:,:,:,:)
  16267. integer(8), allocatable :: values_int8(:,:,:,:)
  16268. real(4), allocatable :: values_real4(:,:,:,:)
  16269. real(8), allocatable :: values_real8(:,:,:,:)
  16270. ! --- begin --------------------------------------
  16271. ! pointer to file structure:
  16272. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  16273. IF_NOT_OK_RETURN(status=1)
  16274. ! pointer to variable structure:
  16275. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  16276. IF_NOT_OK_RETURN(status=1)
  16277. ! check ...
  16278. if ( size(shape(values)) > varp%ndim ) then
  16279. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  16280. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  16281. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  16282. TRACEBACK; status=1; return
  16283. end if
  16284. ! check ...
  16285. if ( present(start ) ) then
  16286. if ( size(start ) /= varp%ndim ) then
  16287. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16288. write (gol,'(" size start : ",i6)') size(start ); call goErr
  16289. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16290. TRACEBACK; status=1; return
  16291. end if
  16292. end if
  16293. if ( present(count ) ) then
  16294. if ( size(count ) /= varp%ndim ) then
  16295. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16296. write (gol,'(" size count : ",i6)') size(count ); call goErr
  16297. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16298. TRACEBACK; status=1; return
  16299. end if
  16300. end if
  16301. if ( present(stride ) ) then
  16302. if ( size(stride ) /= varp%ndim ) then
  16303. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16304. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  16305. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16306. TRACEBACK; status=1; return
  16307. end if
  16308. end if
  16309. if ( present(map ) ) then
  16310. if ( size(map ) /= varp%ndim ) then
  16311. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16312. write (gol,'(" size map : ",i6)') size(map ); call goErr
  16313. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16314. TRACEBACK; status=1; return
  16315. end if
  16316. end if
  16317. ! loop over file types:
  16318. do iftype = 1, filep%nftype
  16319. ! current type:
  16320. ftype = filep%ftypes(iftype)
  16321. ! select appropriate routine for each type:
  16322. select case ( ftype )
  16323. #ifdef with_hdf4
  16324. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16325. case ( MDF_HDF4 )
  16326. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16327. ! check ...
  16328. if ( present(map ) ) then
  16329. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  16330. TRACEBACK; status=1; return
  16331. end if
  16332. ! fill offset (zero based!) and stride with default values:
  16333. hdf4_offset = 0
  16334. hdf4_stride = 1
  16335. ! count is by default the shape; padd with singleton dimensions:
  16336. hdf4_count = 1; hdf4_count(1:4) = shape(values)
  16337. ! replace by optional arguments if necessary:
  16338. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  16339. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  16340. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  16341. ! test target type;
  16342. ! convert to required kind before entering sfWData,
  16343. ! otherwise segmentation faults on some machines ...
  16344. select case ( varp%xtype )
  16345. case ( MDF_BYTE )
  16346. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16347. values_int1 = int(values,kind=1)
  16348. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16349. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  16350. deallocate( values_int1 )
  16351. case ( MDF_SHORT )
  16352. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16353. values_int2 = int(values,kind=2)
  16354. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16355. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  16356. deallocate( values_int2 )
  16357. case ( MDF_INT )
  16358. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16359. values_int4 = int(values,kind=4)
  16360. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16361. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  16362. deallocate( values_int4 )
  16363. case ( MDF_FLOAT )
  16364. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16365. values_real4 = real(values,kind=4)
  16366. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16367. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  16368. deallocate( values_real4 )
  16369. case ( MDF_DOUBLE )
  16370. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16371. values_real8 = real(values,kind=8)
  16372. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16373. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  16374. deallocate( values_real8 )
  16375. case default
  16376. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  16377. TRACEBACK; status=1; return
  16378. end select
  16379. if ( status == FAIL ) then
  16380. write (gol,'("writing hdf4 data set:")'); call goErr
  16381. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  16382. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  16383. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  16384. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  16385. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  16386. write (gol,'(" size : ",i12)') size(values); call goErr
  16387. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  16388. TRACEBACK; status=1; return
  16389. end if
  16390. #endif
  16391. #ifdef with_hdf5_beta
  16392. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16393. case ( MDF_HDF5 )
  16394. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16395. ! check ...
  16396. if ( present(map ) ) then
  16397. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  16398. TRACEBACK; status=1; return
  16399. end if
  16400. ! fill offset (zero based!), stride, and count :
  16401. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  16402. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  16403. hdf5_count = 1 ! default singleton dimension
  16404. if ( present(count) ) then
  16405. hdf5_count(1:varp%ndim) = count
  16406. else
  16407. hdf5_count(1:4) = shape(values)
  16408. end if
  16409. ! new dimension:
  16410. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  16411. ! target data space in file:
  16412. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  16413. IF_NOT_OK_RETURN(status=1)
  16414. ! chunked dataset ?
  16415. if ( varp%hdf5_chunked ) then
  16416. ! reset extend:
  16417. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  16418. IF_NOT_OK_RETURN(status=1)
  16419. end if
  16420. ! select hyperslab:
  16421. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  16422. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  16423. stride=hdf5_stride(1:varp%ndim) )
  16424. ! write data:
  16425. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  16426. int(shape(values),kind=HSIZE_T), status, &
  16427. file_space_id=hdf5_file_space_id )
  16428. IF_NOT_OK_RETURN(status=1)
  16429. ! release data space:
  16430. call H5SClose_f( hdf5_file_space_id, status )
  16431. IF_NOT_OK_RETURN(status=1)
  16432. #endif
  16433. #ifdef with_netcdf
  16434. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16435. case ( MDF_NETCDF, MDF_NETCDF4 )
  16436. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16437. ! test target type:
  16438. ! convert to required kind before entering NF90_Put_Var,
  16439. ! otherwise segmentation faults on some machines ...
  16440. select case ( varp%xtype )
  16441. case ( MDF_BYTE )
  16442. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16443. values_int1 = int(values,kind=1)
  16444. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  16445. start, count, stride, map )
  16446. IF_NF90_NOT_OK_RETURN(status=1)
  16447. deallocate( values_int1 )
  16448. case ( MDF_SHORT )
  16449. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16450. values_int2 = int(values,kind=2)
  16451. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  16452. start, count, stride, map )
  16453. IF_NF90_NOT_OK_RETURN(status=1)
  16454. deallocate( values_int2 )
  16455. case ( MDF_INT )
  16456. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16457. values_int4 = int(values,kind=4)
  16458. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  16459. start, count, stride, map )
  16460. IF_NF90_NOT_OK_RETURN(status=1)
  16461. deallocate( values_int4 )
  16462. case ( MDF_FLOAT )
  16463. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16464. values_real4 = real(values,kind=4)
  16465. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  16466. start, count, stride, map )
  16467. IF_NF90_NOT_OK_RETURN(status=1)
  16468. deallocate( values_real4 )
  16469. case ( MDF_DOUBLE )
  16470. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16471. values_real8 = real(values,kind=8)
  16472. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  16473. start, count, stride, map )
  16474. IF_NF90_NOT_OK_RETURN(status=1)
  16475. deallocate( values_real8 )
  16476. case default
  16477. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  16478. TRACEBACK; status=1; return
  16479. end select
  16480. ! just put; let netcdf library convert the right kind:
  16481. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  16482. ! start, count, stride, map )
  16483. !IF_NF90_NOT_OK_RETURN(status=1)
  16484. #endif
  16485. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16486. case default
  16487. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16488. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  16489. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  16490. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  16491. TRACEBACK; status=1; return
  16492. end select
  16493. end do ! file types
  16494. ! ok
  16495. status = 0
  16496. end subroutine MDF_Put_Var_r4_4d
  16497. ! ***
  16498. subroutine MDF_Get_Var_r4_4d( hid, varid, values, status, &
  16499. start, count, stride, map )
  16500. #ifdef with_netcdf
  16501. use NetCDF, only : NF90_Get_Var
  16502. #endif
  16503. ! --- in/out -------------------------------------
  16504. integer, intent(in) :: hid
  16505. integer, intent(in) :: varid
  16506. real(4), intent(out) :: values(:,:,:,:)
  16507. integer, intent(out) :: status
  16508. integer, intent(in), optional :: start (:)
  16509. integer, intent(in), optional :: count (:)
  16510. integer, intent(in), optional :: stride(:)
  16511. integer, intent(in), optional :: map (:)
  16512. ! --- const --------------------------------------
  16513. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_4d'
  16514. ! --- external -----------------------------------
  16515. #ifdef with_hdf4
  16516. integer(hdf4_wpi), external :: sfRData
  16517. #endif
  16518. ! --- local --------------------------------------
  16519. type(MDF_File), pointer :: filep
  16520. type(MDF_Var), pointer :: varp
  16521. integer :: iftype
  16522. integer :: ftype
  16523. #ifdef with_hdf4
  16524. integer :: hdf4_offset(MAX_RANK)
  16525. integer :: hdf4_stride(MAX_RANK)
  16526. integer :: hdf4_count(MAX_RANK)
  16527. integer(1), allocatable :: values_int1(:,:,:,:)
  16528. integer(2), allocatable :: values_int2(:,:,:,:)
  16529. integer(4), allocatable :: values_int4(:,:,:,:)
  16530. integer(8), allocatable :: values_int8(:,:,:,:)
  16531. real(4), allocatable :: values_real4(:,:,:,:)
  16532. real(8), allocatable :: values_real8(:,:,:,:)
  16533. #endif
  16534. ! --- begin --------------------------------------
  16535. ! pointer to file structure:
  16536. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  16537. IF_NOT_OK_RETURN(status=1)
  16538. ! pointer to variable structure:
  16539. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  16540. IF_NOT_OK_RETURN(status=1)
  16541. ! check ...
  16542. if ( size(shape(values)) > varp%ndim ) then
  16543. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  16544. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  16545. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  16546. TRACEBACK; status=1; return
  16547. end if
  16548. ! check ...
  16549. if ( present(start ) ) then
  16550. if ( size(start ) /= varp%ndim ) then
  16551. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16552. write (gol,'(" size start : ",i6)') size(start ); call goErr
  16553. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16554. TRACEBACK; status=1; return
  16555. end if
  16556. end if
  16557. if ( present(count ) ) then
  16558. if ( size(count ) /= varp%ndim ) then
  16559. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16560. write (gol,'(" size count : ",i6)') size(count ); call goErr
  16561. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16562. TRACEBACK; status=1; return
  16563. end if
  16564. end if
  16565. if ( present(stride ) ) then
  16566. if ( size(stride ) /= varp%ndim ) then
  16567. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16568. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  16569. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16570. TRACEBACK; status=1; return
  16571. end if
  16572. end if
  16573. if ( present(map ) ) then
  16574. if ( size(map ) /= varp%ndim ) then
  16575. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16576. write (gol,'(" size map : ",i6)') size(map ); call goErr
  16577. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16578. TRACEBACK; status=1; return
  16579. end if
  16580. end if
  16581. ! loop over file types:
  16582. do iftype = 1, filep%nftype
  16583. ! current type:
  16584. ftype = filep%ftypes(iftype)
  16585. ! select appropriate routine for each type:
  16586. select case ( ftype )
  16587. #ifdef with_hdf4
  16588. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16589. case ( MDF_HDF4 )
  16590. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16591. ! check ...
  16592. if ( present(map ) ) then
  16593. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  16594. TRACEBACK; status=1; return
  16595. end if
  16596. ! fill offset (zero based!), stride, and count :
  16597. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  16598. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  16599. hdf4_count = 1 ! default singleton dimension
  16600. hdf4_count(1:4) = shape(values)
  16601. ! test source type:
  16602. select case ( varp%hdf4_xtype )
  16603. case ( DFNT_INT8 )
  16604. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16605. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  16606. values = real(values_int1,kind=4)
  16607. deallocate( values_int1 )
  16608. case ( DFNT_INT16 )
  16609. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16610. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  16611. values = real(values_int2,kind=4)
  16612. deallocate( values_int2 )
  16613. case ( DFNT_INT32 )
  16614. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16615. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  16616. values = real(values_int4,kind=4)
  16617. deallocate( values_int4 )
  16618. case ( DFNT_INT64 )
  16619. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16620. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  16621. values = real(values_int8,kind=4)
  16622. deallocate( values_int8 )
  16623. case ( DFNT_FLOAT32 )
  16624. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16625. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  16626. values = real(values_real4,kind=4)
  16627. deallocate( values_real4 )
  16628. case ( DFNT_FLOAT64 )
  16629. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  16630. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  16631. values = real(values_real8,kind=4)
  16632. deallocate( values_real8 )
  16633. case default
  16634. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  16635. TRACEBACK; status=1; return
  16636. end select
  16637. if ( status == FAIL ) then
  16638. write (gol,'("reading hdf4 data set:")'); call goErr
  16639. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  16640. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  16641. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  16642. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  16643. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  16644. write (gol,'(" size : ",i6)') size(values); call goErr
  16645. TRACEBACK; status=1; return
  16646. end if
  16647. #endif
  16648. #ifdef with_netcdf
  16649. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16650. case ( MDF_NETCDF, MDF_NETCDF4 )
  16651. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16652. ! read values, converted automatically:
  16653. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  16654. start, count, stride, map )
  16655. IF_NF90_NOT_OK_RETURN(status=1)
  16656. #endif
  16657. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16658. case default
  16659. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16660. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  16661. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  16662. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  16663. TRACEBACK; status=1; return
  16664. end select
  16665. end do ! file types
  16666. ! ok
  16667. status = 0
  16668. end subroutine MDF_Get_Var_r4_4d
  16669. ! ***
  16670. subroutine MDF_Put_Var_r4_5d( hid, varid, values, status, &
  16671. start, count, stride, map )
  16672. #ifdef with_hdf5_beta
  16673. use HDF5, only : HID_T, HSIZE_T
  16674. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  16675. use HDF5, only : H5T_NATIVE_CHARACTER
  16676. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  16677. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  16678. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  16679. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  16680. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  16681. #endif
  16682. #ifdef with_netcdf
  16683. use NetCDF, only : NF90_Put_Var
  16684. #endif
  16685. ! --- in/out -------------------------------------
  16686. integer, intent(in) :: hid
  16687. integer, intent(in) :: varid
  16688. real(4), intent(in) :: values(:,:,:,:,:)
  16689. integer, intent(out) :: status
  16690. integer, intent(in), optional :: start (:)
  16691. integer, intent(in), optional :: count (:)
  16692. integer, intent(in), optional :: stride(:)
  16693. integer, intent(in), optional :: map (:)
  16694. ! --- const --------------------------------------
  16695. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_5d'
  16696. ! --- external -----------------------------------
  16697. #ifdef with_hdf4
  16698. integer(hdf4_wpi), external :: sfWData
  16699. #endif
  16700. ! --- local --------------------------------------
  16701. type(MDF_File), pointer :: filep
  16702. type(MDF_Var), pointer :: varp
  16703. integer :: iftype
  16704. integer :: ftype
  16705. #ifdef with_hdf4
  16706. integer :: hdf4_offset(MAX_RANK)
  16707. integer :: hdf4_stride(MAX_RANK)
  16708. integer :: hdf4_count(MAX_RANK)
  16709. #endif
  16710. #ifdef with_hdf5_beta
  16711. !integer(HID_T) :: hdf5_type_id
  16712. integer(HID_T) :: hdf5_file_space_id
  16713. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  16714. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  16715. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  16716. #endif
  16717. integer(1), allocatable :: values_int1(:,:,:,:,:)
  16718. integer(2), allocatable :: values_int2(:,:,:,:,:)
  16719. integer(4), allocatable :: values_int4(:,:,:,:,:)
  16720. integer(8), allocatable :: values_int8(:,:,:,:,:)
  16721. real(4), allocatable :: values_real4(:,:,:,:,:)
  16722. real(8), allocatable :: values_real8(:,:,:,:,:)
  16723. ! --- begin --------------------------------------
  16724. ! pointer to file structure:
  16725. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  16726. IF_NOT_OK_RETURN(status=1)
  16727. ! pointer to variable structure:
  16728. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  16729. IF_NOT_OK_RETURN(status=1)
  16730. ! check ...
  16731. if ( size(shape(values)) > varp%ndim ) then
  16732. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  16733. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  16734. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  16735. TRACEBACK; status=1; return
  16736. end if
  16737. ! check ...
  16738. if ( present(start ) ) then
  16739. if ( size(start ) /= varp%ndim ) then
  16740. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16741. write (gol,'(" size start : ",i6)') size(start ); call goErr
  16742. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16743. TRACEBACK; status=1; return
  16744. end if
  16745. end if
  16746. if ( present(count ) ) then
  16747. if ( size(count ) /= varp%ndim ) then
  16748. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16749. write (gol,'(" size count : ",i6)') size(count ); call goErr
  16750. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16751. TRACEBACK; status=1; return
  16752. end if
  16753. end if
  16754. if ( present(stride ) ) then
  16755. if ( size(stride ) /= varp%ndim ) then
  16756. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16757. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  16758. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16759. TRACEBACK; status=1; return
  16760. end if
  16761. end if
  16762. if ( present(map ) ) then
  16763. if ( size(map ) /= varp%ndim ) then
  16764. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  16765. write (gol,'(" size map : ",i6)') size(map ); call goErr
  16766. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  16767. TRACEBACK; status=1; return
  16768. end if
  16769. end if
  16770. ! loop over file types:
  16771. do iftype = 1, filep%nftype
  16772. ! current type:
  16773. ftype = filep%ftypes(iftype)
  16774. ! select appropriate routine for each type:
  16775. select case ( ftype )
  16776. #ifdef with_hdf4
  16777. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16778. case ( MDF_HDF4 )
  16779. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16780. ! check ...
  16781. if ( present(map ) ) then
  16782. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  16783. TRACEBACK; status=1; return
  16784. end if
  16785. ! fill offset (zero based!) and stride with default values:
  16786. hdf4_offset = 0
  16787. hdf4_stride = 1
  16788. ! count is by default the shape; padd with singleton dimensions:
  16789. hdf4_count = 1; hdf4_count(1:5) = shape(values)
  16790. ! replace by optional arguments if necessary:
  16791. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  16792. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  16793. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  16794. ! test target type;
  16795. ! convert to required kind before entering sfWData,
  16796. ! otherwise segmentation faults on some machines ...
  16797. select case ( varp%xtype )
  16798. case ( MDF_BYTE )
  16799. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16800. values_int1 = int(values,kind=1)
  16801. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16802. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  16803. deallocate( values_int1 )
  16804. case ( MDF_SHORT )
  16805. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16806. values_int2 = int(values,kind=2)
  16807. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16808. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  16809. deallocate( values_int2 )
  16810. case ( MDF_INT )
  16811. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16812. values_int4 = int(values,kind=4)
  16813. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16814. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  16815. deallocate( values_int4 )
  16816. case ( MDF_FLOAT )
  16817. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16818. values_real4 = real(values,kind=4)
  16819. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16820. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  16821. deallocate( values_real4 )
  16822. case ( MDF_DOUBLE )
  16823. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16824. values_real8 = real(values,kind=8)
  16825. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  16826. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  16827. deallocate( values_real8 )
  16828. case default
  16829. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  16830. TRACEBACK; status=1; return
  16831. end select
  16832. if ( status == FAIL ) then
  16833. write (gol,'("writing hdf4 data set:")'); call goErr
  16834. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  16835. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  16836. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  16837. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  16838. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  16839. write (gol,'(" size : ",i12)') size(values); call goErr
  16840. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  16841. TRACEBACK; status=1; return
  16842. end if
  16843. #endif
  16844. #ifdef with_hdf5_beta
  16845. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16846. case ( MDF_HDF5 )
  16847. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16848. ! check ...
  16849. if ( present(map ) ) then
  16850. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  16851. TRACEBACK; status=1; return
  16852. end if
  16853. ! fill offset (zero based!), stride, and count :
  16854. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  16855. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  16856. hdf5_count = 1 ! default singleton dimension
  16857. if ( present(count) ) then
  16858. hdf5_count(1:varp%ndim) = count
  16859. else
  16860. hdf5_count(1:5) = shape(values)
  16861. end if
  16862. ! new dimension:
  16863. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  16864. ! target data space in file:
  16865. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  16866. IF_NOT_OK_RETURN(status=1)
  16867. ! chunked dataset ?
  16868. if ( varp%hdf5_chunked ) then
  16869. ! reset extend:
  16870. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  16871. IF_NOT_OK_RETURN(status=1)
  16872. end if
  16873. ! select hyperslab:
  16874. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  16875. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  16876. stride=hdf5_stride(1:varp%ndim) )
  16877. ! write data:
  16878. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  16879. int(shape(values),kind=HSIZE_T), status, &
  16880. file_space_id=hdf5_file_space_id )
  16881. IF_NOT_OK_RETURN(status=1)
  16882. ! release data space:
  16883. call H5SClose_f( hdf5_file_space_id, status )
  16884. IF_NOT_OK_RETURN(status=1)
  16885. #endif
  16886. #ifdef with_netcdf
  16887. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16888. case ( MDF_NETCDF, MDF_NETCDF4 )
  16889. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16890. ! test target type:
  16891. ! convert to required kind before entering NF90_Put_Var,
  16892. ! otherwise segmentation faults on some machines ...
  16893. select case ( varp%xtype )
  16894. case ( MDF_BYTE )
  16895. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16896. values_int1 = int(values,kind=1)
  16897. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  16898. start, count, stride, map )
  16899. IF_NF90_NOT_OK_RETURN(status=1)
  16900. deallocate( values_int1 )
  16901. case ( MDF_SHORT )
  16902. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16903. values_int2 = int(values,kind=2)
  16904. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  16905. start, count, stride, map )
  16906. IF_NF90_NOT_OK_RETURN(status=1)
  16907. deallocate( values_int2 )
  16908. case ( MDF_INT )
  16909. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16910. values_int4 = int(values,kind=4)
  16911. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  16912. start, count, stride, map )
  16913. IF_NF90_NOT_OK_RETURN(status=1)
  16914. deallocate( values_int4 )
  16915. case ( MDF_FLOAT )
  16916. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16917. values_real4 = real(values,kind=4)
  16918. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  16919. start, count, stride, map )
  16920. IF_NF90_NOT_OK_RETURN(status=1)
  16921. deallocate( values_real4 )
  16922. case ( MDF_DOUBLE )
  16923. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  16924. values_real8 = real(values,kind=8)
  16925. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  16926. start, count, stride, map )
  16927. IF_NF90_NOT_OK_RETURN(status=1)
  16928. deallocate( values_real8 )
  16929. case default
  16930. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  16931. TRACEBACK; status=1; return
  16932. end select
  16933. ! just put; let netcdf library convert the right kind:
  16934. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  16935. ! start, count, stride, map )
  16936. !IF_NF90_NOT_OK_RETURN(status=1)
  16937. #endif
  16938. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16939. case default
  16940. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  16941. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  16942. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  16943. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  16944. TRACEBACK; status=1; return
  16945. end select
  16946. end do ! file types
  16947. ! ok
  16948. status = 0
  16949. end subroutine MDF_Put_Var_r4_5d
  16950. ! ***
  16951. subroutine MDF_Get_Var_r4_5d( hid, varid, values, status, &
  16952. start, count, stride, map )
  16953. #ifdef with_netcdf
  16954. use NetCDF, only : NF90_Get_Var
  16955. #endif
  16956. ! --- in/out -------------------------------------
  16957. integer, intent(in) :: hid
  16958. integer, intent(in) :: varid
  16959. real(4), intent(out) :: values(:,:,:,:,:)
  16960. integer, intent(out) :: status
  16961. integer, intent(in), optional :: start (:)
  16962. integer, intent(in), optional :: count (:)
  16963. integer, intent(in), optional :: stride(:)
  16964. integer, intent(in), optional :: map (:)
  16965. ! --- const --------------------------------------
  16966. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_5d'
  16967. ! --- external -----------------------------------
  16968. #ifdef with_hdf4
  16969. integer(hdf4_wpi), external :: sfRData
  16970. #endif
  16971. ! --- local --------------------------------------
  16972. type(MDF_File), pointer :: filep
  16973. type(MDF_Var), pointer :: varp
  16974. integer :: iftype
  16975. integer :: ftype
  16976. #ifdef with_hdf4
  16977. integer :: hdf4_offset(MAX_RANK)
  16978. integer :: hdf4_stride(MAX_RANK)
  16979. integer :: hdf4_count(MAX_RANK)
  16980. integer(1), allocatable :: values_int1(:,:,:,:,:)
  16981. integer(2), allocatable :: values_int2(:,:,:,:,:)
  16982. integer(4), allocatable :: values_int4(:,:,:,:,:)
  16983. integer(8), allocatable :: values_int8(:,:,:,:,:)
  16984. real(4), allocatable :: values_real4(:,:,:,:,:)
  16985. real(8), allocatable :: values_real8(:,:,:,:,:)
  16986. #endif
  16987. ! --- begin --------------------------------------
  16988. ! pointer to file structure:
  16989. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  16990. IF_NOT_OK_RETURN(status=1)
  16991. ! pointer to variable structure:
  16992. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  16993. IF_NOT_OK_RETURN(status=1)
  16994. ! check ...
  16995. if ( size(shape(values)) > varp%ndim ) then
  16996. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  16997. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  16998. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  16999. TRACEBACK; status=1; return
  17000. end if
  17001. ! check ...
  17002. if ( present(start ) ) then
  17003. if ( size(start ) /= varp%ndim ) then
  17004. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17005. write (gol,'(" size start : ",i6)') size(start ); call goErr
  17006. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17007. TRACEBACK; status=1; return
  17008. end if
  17009. end if
  17010. if ( present(count ) ) then
  17011. if ( size(count ) /= varp%ndim ) then
  17012. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17013. write (gol,'(" size count : ",i6)') size(count ); call goErr
  17014. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17015. TRACEBACK; status=1; return
  17016. end if
  17017. end if
  17018. if ( present(stride ) ) then
  17019. if ( size(stride ) /= varp%ndim ) then
  17020. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17021. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  17022. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17023. TRACEBACK; status=1; return
  17024. end if
  17025. end if
  17026. if ( present(map ) ) then
  17027. if ( size(map ) /= varp%ndim ) then
  17028. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17029. write (gol,'(" size map : ",i6)') size(map ); call goErr
  17030. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17031. TRACEBACK; status=1; return
  17032. end if
  17033. end if
  17034. ! loop over file types:
  17035. do iftype = 1, filep%nftype
  17036. ! current type:
  17037. ftype = filep%ftypes(iftype)
  17038. ! select appropriate routine for each type:
  17039. select case ( ftype )
  17040. #ifdef with_hdf4
  17041. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17042. case ( MDF_HDF4 )
  17043. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17044. ! check ...
  17045. if ( present(map ) ) then
  17046. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  17047. TRACEBACK; status=1; return
  17048. end if
  17049. ! fill offset (zero based!), stride, and count :
  17050. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  17051. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  17052. hdf4_count = 1 ! default singleton dimension
  17053. hdf4_count(1:5) = shape(values)
  17054. ! test source type:
  17055. select case ( varp%hdf4_xtype )
  17056. case ( DFNT_INT8 )
  17057. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17058. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  17059. values = real(values_int1,kind=4)
  17060. deallocate( values_int1 )
  17061. case ( DFNT_INT16 )
  17062. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17063. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  17064. values = real(values_int2,kind=4)
  17065. deallocate( values_int2 )
  17066. case ( DFNT_INT32 )
  17067. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17068. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  17069. values = real(values_int4,kind=4)
  17070. deallocate( values_int4 )
  17071. case ( DFNT_INT64 )
  17072. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17073. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  17074. values = real(values_int8,kind=4)
  17075. deallocate( values_int8 )
  17076. case ( DFNT_FLOAT32 )
  17077. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17078. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  17079. values = real(values_real4,kind=4)
  17080. deallocate( values_real4 )
  17081. case ( DFNT_FLOAT64 )
  17082. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  17083. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  17084. values = real(values_real8,kind=4)
  17085. deallocate( values_real8 )
  17086. case default
  17087. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  17088. TRACEBACK; status=1; return
  17089. end select
  17090. if ( status == FAIL ) then
  17091. write (gol,'("reading hdf4 data set:")'); call goErr
  17092. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  17093. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  17094. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  17095. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  17096. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  17097. write (gol,'(" size : ",i6)') size(values); call goErr
  17098. TRACEBACK; status=1; return
  17099. end if
  17100. #endif
  17101. #ifdef with_netcdf
  17102. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17103. case ( MDF_NETCDF, MDF_NETCDF4 )
  17104. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17105. ! read values, converted automatically:
  17106. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  17107. start, count, stride, map )
  17108. IF_NF90_NOT_OK_RETURN(status=1)
  17109. #endif
  17110. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17111. case default
  17112. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17113. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  17114. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  17115. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  17116. TRACEBACK; status=1; return
  17117. end select
  17118. end do ! file types
  17119. ! ok
  17120. status = 0
  17121. end subroutine MDF_Get_Var_r4_5d
  17122. ! ***
  17123. subroutine MDF_Put_Var_r4_6d( hid, varid, values, status, &
  17124. start, count, stride, map )
  17125. #ifdef with_hdf5_beta
  17126. use HDF5, only : HID_T, HSIZE_T
  17127. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  17128. use HDF5, only : H5T_NATIVE_CHARACTER
  17129. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  17130. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  17131. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  17132. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  17133. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  17134. #endif
  17135. #ifdef with_netcdf
  17136. use NetCDF, only : NF90_Put_Var
  17137. #endif
  17138. ! --- in/out -------------------------------------
  17139. integer, intent(in) :: hid
  17140. integer, intent(in) :: varid
  17141. real(4), intent(in) :: values(:,:,:,:,:,:)
  17142. integer, intent(out) :: status
  17143. integer, intent(in), optional :: start (:)
  17144. integer, intent(in), optional :: count (:)
  17145. integer, intent(in), optional :: stride(:)
  17146. integer, intent(in), optional :: map (:)
  17147. ! --- const --------------------------------------
  17148. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_6d'
  17149. ! --- external -----------------------------------
  17150. #ifdef with_hdf4
  17151. integer(hdf4_wpi), external :: sfWData
  17152. #endif
  17153. ! --- local --------------------------------------
  17154. type(MDF_File), pointer :: filep
  17155. type(MDF_Var), pointer :: varp
  17156. integer :: iftype
  17157. integer :: ftype
  17158. #ifdef with_hdf4
  17159. integer :: hdf4_offset(MAX_RANK)
  17160. integer :: hdf4_stride(MAX_RANK)
  17161. integer :: hdf4_count(MAX_RANK)
  17162. #endif
  17163. #ifdef with_hdf5_beta
  17164. !integer(HID_T) :: hdf5_type_id
  17165. integer(HID_T) :: hdf5_file_space_id
  17166. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  17167. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  17168. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  17169. #endif
  17170. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  17171. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  17172. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  17173. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  17174. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  17175. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  17176. ! --- begin --------------------------------------
  17177. ! pointer to file structure:
  17178. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  17179. IF_NOT_OK_RETURN(status=1)
  17180. ! pointer to variable structure:
  17181. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  17182. IF_NOT_OK_RETURN(status=1)
  17183. ! check ...
  17184. if ( size(shape(values)) > varp%ndim ) then
  17185. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  17186. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  17187. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  17188. TRACEBACK; status=1; return
  17189. end if
  17190. ! check ...
  17191. if ( present(start ) ) then
  17192. if ( size(start ) /= varp%ndim ) then
  17193. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17194. write (gol,'(" size start : ",i6)') size(start ); call goErr
  17195. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17196. TRACEBACK; status=1; return
  17197. end if
  17198. end if
  17199. if ( present(count ) ) then
  17200. if ( size(count ) /= varp%ndim ) then
  17201. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17202. write (gol,'(" size count : ",i6)') size(count ); call goErr
  17203. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17204. TRACEBACK; status=1; return
  17205. end if
  17206. end if
  17207. if ( present(stride ) ) then
  17208. if ( size(stride ) /= varp%ndim ) then
  17209. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17210. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  17211. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17212. TRACEBACK; status=1; return
  17213. end if
  17214. end if
  17215. if ( present(map ) ) then
  17216. if ( size(map ) /= varp%ndim ) then
  17217. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17218. write (gol,'(" size map : ",i6)') size(map ); call goErr
  17219. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17220. TRACEBACK; status=1; return
  17221. end if
  17222. end if
  17223. ! loop over file types:
  17224. do iftype = 1, filep%nftype
  17225. ! current type:
  17226. ftype = filep%ftypes(iftype)
  17227. ! select appropriate routine for each type:
  17228. select case ( ftype )
  17229. #ifdef with_hdf4
  17230. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17231. case ( MDF_HDF4 )
  17232. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17233. ! check ...
  17234. if ( present(map ) ) then
  17235. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  17236. TRACEBACK; status=1; return
  17237. end if
  17238. ! fill offset (zero based!) and stride with default values:
  17239. hdf4_offset = 0
  17240. hdf4_stride = 1
  17241. ! count is by default the shape; padd with singleton dimensions:
  17242. hdf4_count = 1; hdf4_count(1:6) = shape(values)
  17243. ! replace by optional arguments if necessary:
  17244. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  17245. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  17246. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  17247. ! test target type;
  17248. ! convert to required kind before entering sfWData,
  17249. ! otherwise segmentation faults on some machines ...
  17250. select case ( varp%xtype )
  17251. case ( MDF_BYTE )
  17252. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17253. values_int1 = int(values,kind=1)
  17254. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17255. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  17256. deallocate( values_int1 )
  17257. case ( MDF_SHORT )
  17258. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17259. values_int2 = int(values,kind=2)
  17260. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17261. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  17262. deallocate( values_int2 )
  17263. case ( MDF_INT )
  17264. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17265. values_int4 = int(values,kind=4)
  17266. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17267. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  17268. deallocate( values_int4 )
  17269. case ( MDF_FLOAT )
  17270. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17271. values_real4 = real(values,kind=4)
  17272. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17273. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  17274. deallocate( values_real4 )
  17275. case ( MDF_DOUBLE )
  17276. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17277. values_real8 = real(values,kind=8)
  17278. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17279. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  17280. deallocate( values_real8 )
  17281. case default
  17282. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  17283. TRACEBACK; status=1; return
  17284. end select
  17285. if ( status == FAIL ) then
  17286. write (gol,'("writing hdf4 data set:")'); call goErr
  17287. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  17288. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  17289. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  17290. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  17291. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  17292. write (gol,'(" size : ",i12)') size(values); call goErr
  17293. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  17294. TRACEBACK; status=1; return
  17295. end if
  17296. #endif
  17297. #ifdef with_hdf5_beta
  17298. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17299. case ( MDF_HDF5 )
  17300. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17301. ! check ...
  17302. if ( present(map ) ) then
  17303. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  17304. TRACEBACK; status=1; return
  17305. end if
  17306. ! fill offset (zero based!), stride, and count :
  17307. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  17308. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  17309. hdf5_count = 1 ! default singleton dimension
  17310. if ( present(count) ) then
  17311. hdf5_count(1:varp%ndim) = count
  17312. else
  17313. hdf5_count(1:6) = shape(values)
  17314. end if
  17315. ! new dimension:
  17316. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  17317. ! target data space in file:
  17318. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  17319. IF_NOT_OK_RETURN(status=1)
  17320. ! chunked dataset ?
  17321. if ( varp%hdf5_chunked ) then
  17322. ! reset extend:
  17323. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  17324. IF_NOT_OK_RETURN(status=1)
  17325. end if
  17326. ! select hyperslab:
  17327. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  17328. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  17329. stride=hdf5_stride(1:varp%ndim) )
  17330. ! write data:
  17331. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  17332. int(shape(values),kind=HSIZE_T), status, &
  17333. file_space_id=hdf5_file_space_id )
  17334. IF_NOT_OK_RETURN(status=1)
  17335. ! release data space:
  17336. call H5SClose_f( hdf5_file_space_id, status )
  17337. IF_NOT_OK_RETURN(status=1)
  17338. #endif
  17339. #ifdef with_netcdf
  17340. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17341. case ( MDF_NETCDF, MDF_NETCDF4 )
  17342. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17343. ! test target type:
  17344. ! convert to required kind before entering NF90_Put_Var,
  17345. ! otherwise segmentation faults on some machines ...
  17346. select case ( varp%xtype )
  17347. case ( MDF_BYTE )
  17348. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17349. values_int1 = int(values,kind=1)
  17350. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  17351. start, count, stride, map )
  17352. IF_NF90_NOT_OK_RETURN(status=1)
  17353. deallocate( values_int1 )
  17354. case ( MDF_SHORT )
  17355. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17356. values_int2 = int(values,kind=2)
  17357. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  17358. start, count, stride, map )
  17359. IF_NF90_NOT_OK_RETURN(status=1)
  17360. deallocate( values_int2 )
  17361. case ( MDF_INT )
  17362. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17363. values_int4 = int(values,kind=4)
  17364. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  17365. start, count, stride, map )
  17366. IF_NF90_NOT_OK_RETURN(status=1)
  17367. deallocate( values_int4 )
  17368. case ( MDF_FLOAT )
  17369. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17370. values_real4 = real(values,kind=4)
  17371. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  17372. start, count, stride, map )
  17373. IF_NF90_NOT_OK_RETURN(status=1)
  17374. deallocate( values_real4 )
  17375. case ( MDF_DOUBLE )
  17376. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17377. values_real8 = real(values,kind=8)
  17378. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  17379. start, count, stride, map )
  17380. IF_NF90_NOT_OK_RETURN(status=1)
  17381. deallocate( values_real8 )
  17382. case default
  17383. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  17384. TRACEBACK; status=1; return
  17385. end select
  17386. ! just put; let netcdf library convert the right kind:
  17387. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  17388. ! start, count, stride, map )
  17389. !IF_NF90_NOT_OK_RETURN(status=1)
  17390. #endif
  17391. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17392. case default
  17393. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17394. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  17395. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  17396. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  17397. TRACEBACK; status=1; return
  17398. end select
  17399. end do ! file types
  17400. ! ok
  17401. status = 0
  17402. end subroutine MDF_Put_Var_r4_6d
  17403. ! ***
  17404. subroutine MDF_Get_Var_r4_6d( hid, varid, values, status, &
  17405. start, count, stride, map )
  17406. #ifdef with_netcdf
  17407. use NetCDF, only : NF90_Get_Var
  17408. #endif
  17409. ! --- in/out -------------------------------------
  17410. integer, intent(in) :: hid
  17411. integer, intent(in) :: varid
  17412. real(4), intent(out) :: values(:,:,:,:,:,:)
  17413. integer, intent(out) :: status
  17414. integer, intent(in), optional :: start (:)
  17415. integer, intent(in), optional :: count (:)
  17416. integer, intent(in), optional :: stride(:)
  17417. integer, intent(in), optional :: map (:)
  17418. ! --- const --------------------------------------
  17419. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_6d'
  17420. ! --- external -----------------------------------
  17421. #ifdef with_hdf4
  17422. integer(hdf4_wpi), external :: sfRData
  17423. #endif
  17424. ! --- local --------------------------------------
  17425. type(MDF_File), pointer :: filep
  17426. type(MDF_Var), pointer :: varp
  17427. integer :: iftype
  17428. integer :: ftype
  17429. #ifdef with_hdf4
  17430. integer :: hdf4_offset(MAX_RANK)
  17431. integer :: hdf4_stride(MAX_RANK)
  17432. integer :: hdf4_count(MAX_RANK)
  17433. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  17434. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  17435. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  17436. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  17437. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  17438. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  17439. #endif
  17440. ! --- begin --------------------------------------
  17441. ! pointer to file structure:
  17442. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  17443. IF_NOT_OK_RETURN(status=1)
  17444. ! pointer to variable structure:
  17445. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  17446. IF_NOT_OK_RETURN(status=1)
  17447. ! check ...
  17448. if ( size(shape(values)) > varp%ndim ) then
  17449. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  17450. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  17451. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  17452. TRACEBACK; status=1; return
  17453. end if
  17454. ! check ...
  17455. if ( present(start ) ) then
  17456. if ( size(start ) /= varp%ndim ) then
  17457. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17458. write (gol,'(" size start : ",i6)') size(start ); call goErr
  17459. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17460. TRACEBACK; status=1; return
  17461. end if
  17462. end if
  17463. if ( present(count ) ) then
  17464. if ( size(count ) /= varp%ndim ) then
  17465. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17466. write (gol,'(" size count : ",i6)') size(count ); call goErr
  17467. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17468. TRACEBACK; status=1; return
  17469. end if
  17470. end if
  17471. if ( present(stride ) ) then
  17472. if ( size(stride ) /= varp%ndim ) then
  17473. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17474. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  17475. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17476. TRACEBACK; status=1; return
  17477. end if
  17478. end if
  17479. if ( present(map ) ) then
  17480. if ( size(map ) /= varp%ndim ) then
  17481. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17482. write (gol,'(" size map : ",i6)') size(map ); call goErr
  17483. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17484. TRACEBACK; status=1; return
  17485. end if
  17486. end if
  17487. ! loop over file types:
  17488. do iftype = 1, filep%nftype
  17489. ! current type:
  17490. ftype = filep%ftypes(iftype)
  17491. ! select appropriate routine for each type:
  17492. select case ( ftype )
  17493. #ifdef with_hdf4
  17494. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17495. case ( MDF_HDF4 )
  17496. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17497. ! check ...
  17498. if ( present(map ) ) then
  17499. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  17500. TRACEBACK; status=1; return
  17501. end if
  17502. ! fill offset (zero based!), stride, and count :
  17503. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  17504. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  17505. hdf4_count = 1 ! default singleton dimension
  17506. hdf4_count(1:6) = shape(values)
  17507. ! test source type:
  17508. select case ( varp%hdf4_xtype )
  17509. case ( DFNT_INT8 )
  17510. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17511. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  17512. values = real(values_int1,kind=4)
  17513. deallocate( values_int1 )
  17514. case ( DFNT_INT16 )
  17515. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17516. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  17517. values = real(values_int2,kind=4)
  17518. deallocate( values_int2 )
  17519. case ( DFNT_INT32 )
  17520. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17521. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  17522. values = real(values_int4,kind=4)
  17523. deallocate( values_int4 )
  17524. case ( DFNT_INT64 )
  17525. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17526. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  17527. values = real(values_int8,kind=4)
  17528. deallocate( values_int8 )
  17529. case ( DFNT_FLOAT32 )
  17530. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17531. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  17532. values = real(values_real4,kind=4)
  17533. deallocate( values_real4 )
  17534. case ( DFNT_FLOAT64 )
  17535. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  17536. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  17537. values = real(values_real8,kind=4)
  17538. deallocate( values_real8 )
  17539. case default
  17540. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  17541. TRACEBACK; status=1; return
  17542. end select
  17543. if ( status == FAIL ) then
  17544. write (gol,'("reading hdf4 data set:")'); call goErr
  17545. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  17546. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  17547. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  17548. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  17549. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  17550. write (gol,'(" size : ",i6)') size(values); call goErr
  17551. TRACEBACK; status=1; return
  17552. end if
  17553. #endif
  17554. #ifdef with_netcdf
  17555. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17556. case ( MDF_NETCDF, MDF_NETCDF4 )
  17557. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17558. ! read values, converted automatically:
  17559. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  17560. start, count, stride, map )
  17561. IF_NF90_NOT_OK_RETURN(status=1)
  17562. #endif
  17563. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17564. case default
  17565. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17566. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  17567. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  17568. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  17569. TRACEBACK; status=1; return
  17570. end select
  17571. end do ! file types
  17572. ! ok
  17573. status = 0
  17574. end subroutine MDF_Get_Var_r4_6d
  17575. ! ***
  17576. subroutine MDF_Put_Var_r4_7d( hid, varid, values, status, &
  17577. start, count, stride, map )
  17578. #ifdef with_hdf5_beta
  17579. use HDF5, only : HID_T, HSIZE_T
  17580. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  17581. use HDF5, only : H5T_NATIVE_CHARACTER
  17582. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  17583. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  17584. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  17585. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  17586. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  17587. #endif
  17588. #ifdef with_netcdf
  17589. use NetCDF, only : NF90_Put_Var
  17590. #endif
  17591. ! --- in/out -------------------------------------
  17592. integer, intent(in) :: hid
  17593. integer, intent(in) :: varid
  17594. real(4), intent(in) :: values(:,:,:,:,:,:,:)
  17595. integer, intent(out) :: status
  17596. integer, intent(in), optional :: start (:)
  17597. integer, intent(in), optional :: count (:)
  17598. integer, intent(in), optional :: stride(:)
  17599. integer, intent(in), optional :: map (:)
  17600. ! --- const --------------------------------------
  17601. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r4_7d'
  17602. ! --- external -----------------------------------
  17603. #ifdef with_hdf4
  17604. integer(hdf4_wpi), external :: sfWData
  17605. #endif
  17606. ! --- local --------------------------------------
  17607. type(MDF_File), pointer :: filep
  17608. type(MDF_Var), pointer :: varp
  17609. integer :: iftype
  17610. integer :: ftype
  17611. #ifdef with_hdf4
  17612. integer :: hdf4_offset(MAX_RANK)
  17613. integer :: hdf4_stride(MAX_RANK)
  17614. integer :: hdf4_count(MAX_RANK)
  17615. #endif
  17616. #ifdef with_hdf5_beta
  17617. !integer(HID_T) :: hdf5_type_id
  17618. integer(HID_T) :: hdf5_file_space_id
  17619. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  17620. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  17621. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  17622. #endif
  17623. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  17624. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  17625. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  17626. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  17627. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  17628. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  17629. ! --- begin --------------------------------------
  17630. ! pointer to file structure:
  17631. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  17632. IF_NOT_OK_RETURN(status=1)
  17633. ! pointer to variable structure:
  17634. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  17635. IF_NOT_OK_RETURN(status=1)
  17636. ! check ...
  17637. if ( size(shape(values)) > varp%ndim ) then
  17638. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  17639. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  17640. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  17641. TRACEBACK; status=1; return
  17642. end if
  17643. ! check ...
  17644. if ( present(start ) ) then
  17645. if ( size(start ) /= varp%ndim ) then
  17646. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17647. write (gol,'(" size start : ",i6)') size(start ); call goErr
  17648. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17649. TRACEBACK; status=1; return
  17650. end if
  17651. end if
  17652. if ( present(count ) ) then
  17653. if ( size(count ) /= varp%ndim ) then
  17654. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17655. write (gol,'(" size count : ",i6)') size(count ); call goErr
  17656. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17657. TRACEBACK; status=1; return
  17658. end if
  17659. end if
  17660. if ( present(stride ) ) then
  17661. if ( size(stride ) /= varp%ndim ) then
  17662. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17663. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  17664. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17665. TRACEBACK; status=1; return
  17666. end if
  17667. end if
  17668. if ( present(map ) ) then
  17669. if ( size(map ) /= varp%ndim ) then
  17670. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17671. write (gol,'(" size map : ",i6)') size(map ); call goErr
  17672. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17673. TRACEBACK; status=1; return
  17674. end if
  17675. end if
  17676. ! loop over file types:
  17677. do iftype = 1, filep%nftype
  17678. ! current type:
  17679. ftype = filep%ftypes(iftype)
  17680. ! select appropriate routine for each type:
  17681. select case ( ftype )
  17682. #ifdef with_hdf4
  17683. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17684. case ( MDF_HDF4 )
  17685. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17686. ! check ...
  17687. if ( present(map ) ) then
  17688. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  17689. TRACEBACK; status=1; return
  17690. end if
  17691. ! fill offset (zero based!) and stride with default values:
  17692. hdf4_offset = 0
  17693. hdf4_stride = 1
  17694. ! count is by default the shape; padd with singleton dimensions:
  17695. hdf4_count = 1; hdf4_count(1:7) = shape(values)
  17696. ! replace by optional arguments if necessary:
  17697. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  17698. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  17699. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  17700. ! test target type;
  17701. ! convert to required kind before entering sfWData,
  17702. ! otherwise segmentation faults on some machines ...
  17703. select case ( varp%xtype )
  17704. case ( MDF_BYTE )
  17705. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17706. values_int1 = int(values,kind=1)
  17707. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17708. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  17709. deallocate( values_int1 )
  17710. case ( MDF_SHORT )
  17711. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17712. values_int2 = int(values,kind=2)
  17713. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17714. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  17715. deallocate( values_int2 )
  17716. case ( MDF_INT )
  17717. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17718. values_int4 = int(values,kind=4)
  17719. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17720. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  17721. deallocate( values_int4 )
  17722. case ( MDF_FLOAT )
  17723. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17724. values_real4 = real(values,kind=4)
  17725. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17726. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  17727. deallocate( values_real4 )
  17728. case ( MDF_DOUBLE )
  17729. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17730. values_real8 = real(values,kind=8)
  17731. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  17732. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  17733. deallocate( values_real8 )
  17734. case default
  17735. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  17736. TRACEBACK; status=1; return
  17737. end select
  17738. if ( status == FAIL ) then
  17739. write (gol,'("writing hdf4 data set:")'); call goErr
  17740. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  17741. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  17742. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  17743. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  17744. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  17745. write (gol,'(" size : ",i12)') size(values); call goErr
  17746. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  17747. TRACEBACK; status=1; return
  17748. end if
  17749. #endif
  17750. #ifdef with_hdf5_beta
  17751. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17752. case ( MDF_HDF5 )
  17753. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17754. ! check ...
  17755. if ( present(map ) ) then
  17756. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  17757. TRACEBACK; status=1; return
  17758. end if
  17759. ! fill offset (zero based!), stride, and count :
  17760. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  17761. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  17762. hdf5_count = 1 ! default singleton dimension
  17763. if ( present(count) ) then
  17764. hdf5_count(1:varp%ndim) = count
  17765. else
  17766. hdf5_count(1:7) = shape(values)
  17767. end if
  17768. ! new dimension:
  17769. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  17770. ! target data space in file:
  17771. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  17772. IF_NOT_OK_RETURN(status=1)
  17773. ! chunked dataset ?
  17774. if ( varp%hdf5_chunked ) then
  17775. ! reset extend:
  17776. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  17777. IF_NOT_OK_RETURN(status=1)
  17778. end if
  17779. ! select hyperslab:
  17780. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  17781. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  17782. stride=hdf5_stride(1:varp%ndim) )
  17783. ! write data:
  17784. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_REAL, values, &
  17785. int(shape(values),kind=HSIZE_T), status, &
  17786. file_space_id=hdf5_file_space_id )
  17787. IF_NOT_OK_RETURN(status=1)
  17788. ! release data space:
  17789. call H5SClose_f( hdf5_file_space_id, status )
  17790. IF_NOT_OK_RETURN(status=1)
  17791. #endif
  17792. #ifdef with_netcdf
  17793. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17794. case ( MDF_NETCDF, MDF_NETCDF4 )
  17795. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17796. ! test target type:
  17797. ! convert to required kind before entering NF90_Put_Var,
  17798. ! otherwise segmentation faults on some machines ...
  17799. select case ( varp%xtype )
  17800. case ( MDF_BYTE )
  17801. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17802. values_int1 = int(values,kind=1)
  17803. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  17804. start, count, stride, map )
  17805. IF_NF90_NOT_OK_RETURN(status=1)
  17806. deallocate( values_int1 )
  17807. case ( MDF_SHORT )
  17808. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17809. values_int2 = int(values,kind=2)
  17810. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  17811. start, count, stride, map )
  17812. IF_NF90_NOT_OK_RETURN(status=1)
  17813. deallocate( values_int2 )
  17814. case ( MDF_INT )
  17815. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17816. values_int4 = int(values,kind=4)
  17817. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  17818. start, count, stride, map )
  17819. IF_NF90_NOT_OK_RETURN(status=1)
  17820. deallocate( values_int4 )
  17821. case ( MDF_FLOAT )
  17822. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17823. values_real4 = real(values,kind=4)
  17824. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  17825. start, count, stride, map )
  17826. IF_NF90_NOT_OK_RETURN(status=1)
  17827. deallocate( values_real4 )
  17828. case ( MDF_DOUBLE )
  17829. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17830. values_real8 = real(values,kind=8)
  17831. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  17832. start, count, stride, map )
  17833. IF_NF90_NOT_OK_RETURN(status=1)
  17834. deallocate( values_real8 )
  17835. case default
  17836. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  17837. TRACEBACK; status=1; return
  17838. end select
  17839. ! just put; let netcdf library convert the right kind:
  17840. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  17841. ! start, count, stride, map )
  17842. !IF_NF90_NOT_OK_RETURN(status=1)
  17843. #endif
  17844. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17845. case default
  17846. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17847. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  17848. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  17849. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  17850. TRACEBACK; status=1; return
  17851. end select
  17852. end do ! file types
  17853. ! ok
  17854. status = 0
  17855. end subroutine MDF_Put_Var_r4_7d
  17856. ! ***
  17857. subroutine MDF_Get_Var_r4_7d( hid, varid, values, status, &
  17858. start, count, stride, map )
  17859. #ifdef with_netcdf
  17860. use NetCDF, only : NF90_Get_Var
  17861. #endif
  17862. ! --- in/out -------------------------------------
  17863. integer, intent(in) :: hid
  17864. integer, intent(in) :: varid
  17865. real(4), intent(out) :: values(:,:,:,:,:,:,:)
  17866. integer, intent(out) :: status
  17867. integer, intent(in), optional :: start (:)
  17868. integer, intent(in), optional :: count (:)
  17869. integer, intent(in), optional :: stride(:)
  17870. integer, intent(in), optional :: map (:)
  17871. ! --- const --------------------------------------
  17872. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r4_7d'
  17873. ! --- external -----------------------------------
  17874. #ifdef with_hdf4
  17875. integer(hdf4_wpi), external :: sfRData
  17876. #endif
  17877. ! --- local --------------------------------------
  17878. type(MDF_File), pointer :: filep
  17879. type(MDF_Var), pointer :: varp
  17880. integer :: iftype
  17881. integer :: ftype
  17882. #ifdef with_hdf4
  17883. integer :: hdf4_offset(MAX_RANK)
  17884. integer :: hdf4_stride(MAX_RANK)
  17885. integer :: hdf4_count(MAX_RANK)
  17886. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  17887. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  17888. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  17889. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  17890. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  17891. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  17892. #endif
  17893. ! --- begin --------------------------------------
  17894. ! pointer to file structure:
  17895. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  17896. IF_NOT_OK_RETURN(status=1)
  17897. ! pointer to variable structure:
  17898. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  17899. IF_NOT_OK_RETURN(status=1)
  17900. ! check ...
  17901. if ( size(shape(values)) > varp%ndim ) then
  17902. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  17903. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  17904. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  17905. TRACEBACK; status=1; return
  17906. end if
  17907. ! check ...
  17908. if ( present(start ) ) then
  17909. if ( size(start ) /= varp%ndim ) then
  17910. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17911. write (gol,'(" size start : ",i6)') size(start ); call goErr
  17912. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17913. TRACEBACK; status=1; return
  17914. end if
  17915. end if
  17916. if ( present(count ) ) then
  17917. if ( size(count ) /= varp%ndim ) then
  17918. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17919. write (gol,'(" size count : ",i6)') size(count ); call goErr
  17920. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17921. TRACEBACK; status=1; return
  17922. end if
  17923. end if
  17924. if ( present(stride ) ) then
  17925. if ( size(stride ) /= varp%ndim ) then
  17926. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17927. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  17928. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17929. TRACEBACK; status=1; return
  17930. end if
  17931. end if
  17932. if ( present(map ) ) then
  17933. if ( size(map ) /= varp%ndim ) then
  17934. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  17935. write (gol,'(" size map : ",i6)') size(map ); call goErr
  17936. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  17937. TRACEBACK; status=1; return
  17938. end if
  17939. end if
  17940. ! loop over file types:
  17941. do iftype = 1, filep%nftype
  17942. ! current type:
  17943. ftype = filep%ftypes(iftype)
  17944. ! select appropriate routine for each type:
  17945. select case ( ftype )
  17946. #ifdef with_hdf4
  17947. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17948. case ( MDF_HDF4 )
  17949. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  17950. ! check ...
  17951. if ( present(map ) ) then
  17952. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  17953. TRACEBACK; status=1; return
  17954. end if
  17955. ! fill offset (zero based!), stride, and count :
  17956. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  17957. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  17958. hdf4_count = 1 ! default singleton dimension
  17959. hdf4_count(1:7) = shape(values)
  17960. ! test source type:
  17961. select case ( varp%hdf4_xtype )
  17962. case ( DFNT_INT8 )
  17963. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17964. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  17965. values = real(values_int1,kind=4)
  17966. deallocate( values_int1 )
  17967. case ( DFNT_INT16 )
  17968. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17969. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  17970. values = real(values_int2,kind=4)
  17971. deallocate( values_int2 )
  17972. case ( DFNT_INT32 )
  17973. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17974. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  17975. values = real(values_int4,kind=4)
  17976. deallocate( values_int4 )
  17977. case ( DFNT_INT64 )
  17978. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17979. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  17980. values = real(values_int8,kind=4)
  17981. deallocate( values_int8 )
  17982. case ( DFNT_FLOAT32 )
  17983. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17984. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  17985. values = real(values_real4,kind=4)
  17986. deallocate( values_real4 )
  17987. case ( DFNT_FLOAT64 )
  17988. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  17989. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  17990. values = real(values_real8,kind=4)
  17991. deallocate( values_real8 )
  17992. case default
  17993. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  17994. TRACEBACK; status=1; return
  17995. end select
  17996. if ( status == FAIL ) then
  17997. write (gol,'("reading hdf4 data set:")'); call goErr
  17998. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  17999. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  18000. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  18001. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  18002. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  18003. write (gol,'(" size : ",i6)') size(values); call goErr
  18004. TRACEBACK; status=1; return
  18005. end if
  18006. #endif
  18007. #ifdef with_netcdf
  18008. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18009. case ( MDF_NETCDF, MDF_NETCDF4 )
  18010. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18011. ! read values, converted automatically:
  18012. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  18013. start, count, stride, map )
  18014. IF_NF90_NOT_OK_RETURN(status=1)
  18015. #endif
  18016. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18017. case default
  18018. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18019. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  18020. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  18021. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  18022. TRACEBACK; status=1; return
  18023. end select
  18024. end do ! file types
  18025. ! ok
  18026. status = 0
  18027. end subroutine MDF_Get_Var_r4_7d
  18028. ! ***
  18029. subroutine MDF_Put_Var_r8_1d( hid, varid, values, status, &
  18030. start, count, stride, map )
  18031. #ifdef with_hdf5_beta
  18032. use HDF5, only : HID_T, HSIZE_T
  18033. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  18034. use HDF5, only : H5T_NATIVE_CHARACTER
  18035. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  18036. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  18037. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  18038. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  18039. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  18040. #endif
  18041. #ifdef with_netcdf
  18042. use NetCDF, only : NF90_Put_Var
  18043. #endif
  18044. ! --- in/out -------------------------------------
  18045. integer, intent(in) :: hid
  18046. integer, intent(in) :: varid
  18047. real(8), intent(in) :: values(:)
  18048. integer, intent(out) :: status
  18049. integer, intent(in), optional :: start (:)
  18050. integer, intent(in), optional :: count (:)
  18051. integer, intent(in), optional :: stride(:)
  18052. integer, intent(in), optional :: map (:)
  18053. ! --- const --------------------------------------
  18054. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_1d'
  18055. ! --- external -----------------------------------
  18056. #ifdef with_hdf4
  18057. integer(hdf4_wpi), external :: sfWData
  18058. #endif
  18059. ! --- local --------------------------------------
  18060. type(MDF_File), pointer :: filep
  18061. type(MDF_Var), pointer :: varp
  18062. integer :: iftype
  18063. integer :: ftype
  18064. #ifdef with_hdf4
  18065. integer :: hdf4_offset(MAX_RANK)
  18066. integer :: hdf4_stride(MAX_RANK)
  18067. integer :: hdf4_count(MAX_RANK)
  18068. #endif
  18069. #ifdef with_hdf5_beta
  18070. !integer(HID_T) :: hdf5_type_id
  18071. integer(HID_T) :: hdf5_file_space_id
  18072. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  18073. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  18074. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  18075. #endif
  18076. integer(1), allocatable :: values_int1(:)
  18077. integer(2), allocatable :: values_int2(:)
  18078. integer(4), allocatable :: values_int4(:)
  18079. integer(8), allocatable :: values_int8(:)
  18080. real(4), allocatable :: values_real4(:)
  18081. real(8), allocatable :: values_real8(:)
  18082. ! --- begin --------------------------------------
  18083. ! pointer to file structure:
  18084. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  18085. IF_NOT_OK_RETURN(status=1)
  18086. ! pointer to variable structure:
  18087. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  18088. IF_NOT_OK_RETURN(status=1)
  18089. ! check ...
  18090. if ( size(shape(values)) > varp%ndim ) then
  18091. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  18092. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  18093. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  18094. TRACEBACK; status=1; return
  18095. end if
  18096. ! check ...
  18097. if ( present(start ) ) then
  18098. if ( size(start ) /= varp%ndim ) then
  18099. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18100. write (gol,'(" size start : ",i6)') size(start ); call goErr
  18101. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18102. TRACEBACK; status=1; return
  18103. end if
  18104. end if
  18105. if ( present(count ) ) then
  18106. if ( size(count ) /= varp%ndim ) then
  18107. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18108. write (gol,'(" size count : ",i6)') size(count ); call goErr
  18109. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18110. TRACEBACK; status=1; return
  18111. end if
  18112. end if
  18113. if ( present(stride ) ) then
  18114. if ( size(stride ) /= varp%ndim ) then
  18115. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18116. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  18117. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18118. TRACEBACK; status=1; return
  18119. end if
  18120. end if
  18121. if ( present(map ) ) then
  18122. if ( size(map ) /= varp%ndim ) then
  18123. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18124. write (gol,'(" size map : ",i6)') size(map ); call goErr
  18125. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18126. TRACEBACK; status=1; return
  18127. end if
  18128. end if
  18129. ! loop over file types:
  18130. do iftype = 1, filep%nftype
  18131. ! current type:
  18132. ftype = filep%ftypes(iftype)
  18133. ! select appropriate routine for each type:
  18134. select case ( ftype )
  18135. #ifdef with_hdf4
  18136. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18137. case ( MDF_HDF4 )
  18138. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18139. ! check ...
  18140. if ( present(map ) ) then
  18141. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  18142. TRACEBACK; status=1; return
  18143. end if
  18144. ! fill offset (zero based!) and stride with default values:
  18145. hdf4_offset = 0
  18146. hdf4_stride = 1
  18147. ! count is by default the shape; padd with singleton dimensions:
  18148. hdf4_count = 1; hdf4_count(1:1) = shape(values)
  18149. ! replace by optional arguments if necessary:
  18150. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  18151. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  18152. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  18153. ! test target type;
  18154. ! convert to required kind before entering sfWData,
  18155. ! otherwise segmentation faults on some machines ...
  18156. select case ( varp%xtype )
  18157. case ( MDF_BYTE )
  18158. allocate( values_int1(size(values,1)) )
  18159. values_int1 = int(values,kind=1)
  18160. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18161. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  18162. deallocate( values_int1 )
  18163. case ( MDF_SHORT )
  18164. allocate( values_int2(size(values,1)) )
  18165. values_int2 = int(values,kind=2)
  18166. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18167. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  18168. deallocate( values_int2 )
  18169. case ( MDF_INT )
  18170. allocate( values_int4(size(values,1)) )
  18171. values_int4 = int(values,kind=4)
  18172. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18173. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  18174. deallocate( values_int4 )
  18175. case ( MDF_FLOAT )
  18176. allocate( values_real4(size(values,1)) )
  18177. values_real4 = real(values,kind=4)
  18178. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18179. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  18180. deallocate( values_real4 )
  18181. case ( MDF_DOUBLE )
  18182. allocate( values_real8(size(values,1)) )
  18183. values_real8 = real(values,kind=8)
  18184. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18185. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  18186. deallocate( values_real8 )
  18187. case default
  18188. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  18189. TRACEBACK; status=1; return
  18190. end select
  18191. if ( status == FAIL ) then
  18192. write (gol,'("writing hdf4 data set:")'); call goErr
  18193. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  18194. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  18195. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  18196. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  18197. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  18198. write (gol,'(" size : ",i12)') size(values); call goErr
  18199. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  18200. TRACEBACK; status=1; return
  18201. end if
  18202. #endif
  18203. #ifdef with_hdf5_beta
  18204. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18205. case ( MDF_HDF5 )
  18206. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18207. ! check ...
  18208. if ( present(map ) ) then
  18209. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  18210. TRACEBACK; status=1; return
  18211. end if
  18212. ! fill offset (zero based!), stride, and count :
  18213. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  18214. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  18215. hdf5_count = 1 ! default singleton dimension
  18216. if ( present(count) ) then
  18217. hdf5_count(1:varp%ndim) = count
  18218. else
  18219. hdf5_count(1:1) = shape(values)
  18220. end if
  18221. ! new dimension:
  18222. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  18223. ! target data space in file:
  18224. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  18225. IF_NOT_OK_RETURN(status=1)
  18226. ! chunked dataset ?
  18227. if ( varp%hdf5_chunked ) then
  18228. ! reset extend:
  18229. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  18230. IF_NOT_OK_RETURN(status=1)
  18231. end if
  18232. ! select hyperslab:
  18233. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  18234. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  18235. stride=hdf5_stride(1:varp%ndim) )
  18236. ! write data:
  18237. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  18238. int(shape(values),kind=HSIZE_T), status, &
  18239. file_space_id=hdf5_file_space_id )
  18240. IF_NOT_OK_RETURN(status=1)
  18241. ! release data space:
  18242. call H5SClose_f( hdf5_file_space_id, status )
  18243. IF_NOT_OK_RETURN(status=1)
  18244. #endif
  18245. #ifdef with_netcdf
  18246. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18247. case ( MDF_NETCDF, MDF_NETCDF4 )
  18248. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18249. ! test target type:
  18250. ! convert to required kind before entering NF90_Put_Var,
  18251. ! otherwise segmentation faults on some machines ...
  18252. select case ( varp%xtype )
  18253. case ( MDF_BYTE )
  18254. allocate( values_int1(size(values,1)) )
  18255. values_int1 = int(values,kind=1)
  18256. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  18257. start, count, stride, map )
  18258. IF_NF90_NOT_OK_RETURN(status=1)
  18259. deallocate( values_int1 )
  18260. case ( MDF_SHORT )
  18261. allocate( values_int2(size(values,1)) )
  18262. values_int2 = int(values,kind=2)
  18263. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  18264. start, count, stride, map )
  18265. IF_NF90_NOT_OK_RETURN(status=1)
  18266. deallocate( values_int2 )
  18267. case ( MDF_INT )
  18268. allocate( values_int4(size(values,1)) )
  18269. values_int4 = int(values,kind=4)
  18270. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  18271. start, count, stride, map )
  18272. IF_NF90_NOT_OK_RETURN(status=1)
  18273. deallocate( values_int4 )
  18274. case ( MDF_FLOAT )
  18275. allocate( values_real4(size(values,1)) )
  18276. values_real4 = real(values,kind=4)
  18277. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  18278. start, count, stride, map )
  18279. IF_NF90_NOT_OK_RETURN(status=1)
  18280. deallocate( values_real4 )
  18281. case ( MDF_DOUBLE )
  18282. allocate( values_real8(size(values,1)) )
  18283. values_real8 = real(values,kind=8)
  18284. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  18285. start, count, stride, map )
  18286. IF_NF90_NOT_OK_RETURN(status=1)
  18287. deallocate( values_real8 )
  18288. case default
  18289. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  18290. TRACEBACK; status=1; return
  18291. end select
  18292. ! just put; let netcdf library convert the right kind:
  18293. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  18294. ! start, count, stride, map )
  18295. !IF_NF90_NOT_OK_RETURN(status=1)
  18296. #endif
  18297. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18298. case default
  18299. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18300. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  18301. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  18302. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  18303. TRACEBACK; status=1; return
  18304. end select
  18305. end do ! file types
  18306. ! ok
  18307. status = 0
  18308. end subroutine MDF_Put_Var_r8_1d
  18309. ! ***
  18310. subroutine MDF_Get_Var_r8_1d( hid, varid, values, status, &
  18311. start, count, stride, map )
  18312. #ifdef with_netcdf
  18313. use NetCDF, only : NF90_Get_Var
  18314. #endif
  18315. ! --- in/out -------------------------------------
  18316. integer, intent(in) :: hid
  18317. integer, intent(in) :: varid
  18318. real(8), intent(out) :: values(:)
  18319. integer, intent(out) :: status
  18320. integer, intent(in), optional :: start (:)
  18321. integer, intent(in), optional :: count (:)
  18322. integer, intent(in), optional :: stride(:)
  18323. integer, intent(in), optional :: map (:)
  18324. ! --- const --------------------------------------
  18325. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_1d'
  18326. ! --- external -----------------------------------
  18327. #ifdef with_hdf4
  18328. integer(hdf4_wpi), external :: sfRData
  18329. #endif
  18330. ! --- local --------------------------------------
  18331. type(MDF_File), pointer :: filep
  18332. type(MDF_Var), pointer :: varp
  18333. integer :: iftype
  18334. integer :: ftype
  18335. #ifdef with_hdf4
  18336. integer :: hdf4_offset(MAX_RANK)
  18337. integer :: hdf4_stride(MAX_RANK)
  18338. integer :: hdf4_count(MAX_RANK)
  18339. integer(1), allocatable :: values_int1(:)
  18340. integer(2), allocatable :: values_int2(:)
  18341. integer(4), allocatable :: values_int4(:)
  18342. integer(8), allocatable :: values_int8(:)
  18343. real(4), allocatable :: values_real4(:)
  18344. real(8), allocatable :: values_real8(:)
  18345. #endif
  18346. ! --- begin --------------------------------------
  18347. ! pointer to file structure:
  18348. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  18349. IF_NOT_OK_RETURN(status=1)
  18350. ! pointer to variable structure:
  18351. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  18352. IF_NOT_OK_RETURN(status=1)
  18353. ! check ...
  18354. if ( size(shape(values)) > varp%ndim ) then
  18355. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  18356. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  18357. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  18358. TRACEBACK; status=1; return
  18359. end if
  18360. ! check ...
  18361. if ( present(start ) ) then
  18362. if ( size(start ) /= varp%ndim ) then
  18363. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18364. write (gol,'(" size start : ",i6)') size(start ); call goErr
  18365. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18366. TRACEBACK; status=1; return
  18367. end if
  18368. end if
  18369. if ( present(count ) ) then
  18370. if ( size(count ) /= varp%ndim ) then
  18371. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18372. write (gol,'(" size count : ",i6)') size(count ); call goErr
  18373. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18374. TRACEBACK; status=1; return
  18375. end if
  18376. end if
  18377. if ( present(stride ) ) then
  18378. if ( size(stride ) /= varp%ndim ) then
  18379. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18380. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  18381. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18382. TRACEBACK; status=1; return
  18383. end if
  18384. end if
  18385. if ( present(map ) ) then
  18386. if ( size(map ) /= varp%ndim ) then
  18387. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18388. write (gol,'(" size map : ",i6)') size(map ); call goErr
  18389. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18390. TRACEBACK; status=1; return
  18391. end if
  18392. end if
  18393. ! loop over file types:
  18394. do iftype = 1, filep%nftype
  18395. ! current type:
  18396. ftype = filep%ftypes(iftype)
  18397. ! select appropriate routine for each type:
  18398. select case ( ftype )
  18399. #ifdef with_hdf4
  18400. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18401. case ( MDF_HDF4 )
  18402. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18403. ! check ...
  18404. if ( present(map ) ) then
  18405. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  18406. TRACEBACK; status=1; return
  18407. end if
  18408. ! fill offset (zero based!), stride, and count :
  18409. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  18410. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  18411. hdf4_count = 1 ! default singleton dimension
  18412. hdf4_count(1:1) = shape(values)
  18413. ! test source type:
  18414. select case ( varp%hdf4_xtype )
  18415. case ( DFNT_INT8 )
  18416. allocate( values_int1(size(values,1)) )
  18417. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  18418. values = real(values_int1,kind=8)
  18419. deallocate( values_int1 )
  18420. case ( DFNT_INT16 )
  18421. allocate( values_int2(size(values,1)) )
  18422. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  18423. values = real(values_int2,kind=8)
  18424. deallocate( values_int2 )
  18425. case ( DFNT_INT32 )
  18426. allocate( values_int4(size(values,1)) )
  18427. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  18428. values = real(values_int4,kind=8)
  18429. deallocate( values_int4 )
  18430. case ( DFNT_INT64 )
  18431. allocate( values_int8(size(values,1)) )
  18432. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  18433. values = real(values_int8,kind=8)
  18434. deallocate( values_int8 )
  18435. case ( DFNT_FLOAT32 )
  18436. allocate( values_real4(size(values,1)) )
  18437. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  18438. values = real(values_real4,kind=8)
  18439. deallocate( values_real4 )
  18440. case ( DFNT_FLOAT64 )
  18441. allocate( values_real8(size(values,1)) )
  18442. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  18443. values = real(values_real8,kind=8)
  18444. deallocate( values_real8 )
  18445. case default
  18446. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  18447. TRACEBACK; status=1; return
  18448. end select
  18449. if ( status == FAIL ) then
  18450. write (gol,'("reading hdf4 data set:")'); call goErr
  18451. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  18452. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  18453. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  18454. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  18455. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  18456. write (gol,'(" size : ",i6)') size(values); call goErr
  18457. TRACEBACK; status=1; return
  18458. end if
  18459. #endif
  18460. #ifdef with_netcdf
  18461. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18462. case ( MDF_NETCDF, MDF_NETCDF4 )
  18463. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18464. ! read values, converted automatically:
  18465. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  18466. start, count, stride, map )
  18467. IF_NF90_NOT_OK_RETURN(status=1)
  18468. #endif
  18469. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18470. case default
  18471. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18472. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  18473. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  18474. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  18475. TRACEBACK; status=1; return
  18476. end select
  18477. end do ! file types
  18478. ! ok
  18479. status = 0
  18480. end subroutine MDF_Get_Var_r8_1d
  18481. ! ***
  18482. subroutine MDF_Put_Var_r8_2d( hid, varid, values, status, &
  18483. start, count, stride, map )
  18484. #ifdef with_hdf5_beta
  18485. use HDF5, only : HID_T, HSIZE_T
  18486. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  18487. use HDF5, only : H5T_NATIVE_CHARACTER
  18488. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  18489. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  18490. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  18491. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  18492. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  18493. #endif
  18494. #ifdef with_netcdf
  18495. use NetCDF, only : NF90_Put_Var
  18496. #endif
  18497. ! --- in/out -------------------------------------
  18498. integer, intent(in) :: hid
  18499. integer, intent(in) :: varid
  18500. real(8), intent(in) :: values(:,:)
  18501. integer, intent(out) :: status
  18502. integer, intent(in), optional :: start (:)
  18503. integer, intent(in), optional :: count (:)
  18504. integer, intent(in), optional :: stride(:)
  18505. integer, intent(in), optional :: map (:)
  18506. ! --- const --------------------------------------
  18507. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_2d'
  18508. ! --- external -----------------------------------
  18509. #ifdef with_hdf4
  18510. integer(hdf4_wpi), external :: sfWData
  18511. #endif
  18512. ! --- local --------------------------------------
  18513. type(MDF_File), pointer :: filep
  18514. type(MDF_Var), pointer :: varp
  18515. integer :: iftype
  18516. integer :: ftype
  18517. #ifdef with_hdf4
  18518. integer :: hdf4_offset(MAX_RANK)
  18519. integer :: hdf4_stride(MAX_RANK)
  18520. integer :: hdf4_count(MAX_RANK)
  18521. #endif
  18522. #ifdef with_hdf5_beta
  18523. !integer(HID_T) :: hdf5_type_id
  18524. integer(HID_T) :: hdf5_file_space_id
  18525. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  18526. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  18527. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  18528. #endif
  18529. integer(1), allocatable :: values_int1(:,:)
  18530. integer(2), allocatable :: values_int2(:,:)
  18531. integer(4), allocatable :: values_int4(:,:)
  18532. integer(8), allocatable :: values_int8(:,:)
  18533. real(4), allocatable :: values_real4(:,:)
  18534. real(8), allocatable :: values_real8(:,:)
  18535. ! --- begin --------------------------------------
  18536. ! pointer to file structure:
  18537. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  18538. IF_NOT_OK_RETURN(status=1)
  18539. ! pointer to variable structure:
  18540. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  18541. IF_NOT_OK_RETURN(status=1)
  18542. ! check ...
  18543. if ( size(shape(values)) > varp%ndim ) then
  18544. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  18545. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  18546. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  18547. TRACEBACK; status=1; return
  18548. end if
  18549. ! check ...
  18550. if ( present(start ) ) then
  18551. if ( size(start ) /= varp%ndim ) then
  18552. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18553. write (gol,'(" size start : ",i6)') size(start ); call goErr
  18554. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18555. TRACEBACK; status=1; return
  18556. end if
  18557. end if
  18558. if ( present(count ) ) then
  18559. if ( size(count ) /= varp%ndim ) then
  18560. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18561. write (gol,'(" size count : ",i6)') size(count ); call goErr
  18562. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18563. TRACEBACK; status=1; return
  18564. end if
  18565. end if
  18566. if ( present(stride ) ) then
  18567. if ( size(stride ) /= varp%ndim ) then
  18568. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18569. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  18570. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18571. TRACEBACK; status=1; return
  18572. end if
  18573. end if
  18574. if ( present(map ) ) then
  18575. if ( size(map ) /= varp%ndim ) then
  18576. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18577. write (gol,'(" size map : ",i6)') size(map ); call goErr
  18578. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18579. TRACEBACK; status=1; return
  18580. end if
  18581. end if
  18582. ! loop over file types:
  18583. do iftype = 1, filep%nftype
  18584. ! current type:
  18585. ftype = filep%ftypes(iftype)
  18586. ! select appropriate routine for each type:
  18587. select case ( ftype )
  18588. #ifdef with_hdf4
  18589. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18590. case ( MDF_HDF4 )
  18591. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18592. ! check ...
  18593. if ( present(map ) ) then
  18594. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  18595. TRACEBACK; status=1; return
  18596. end if
  18597. ! fill offset (zero based!) and stride with default values:
  18598. hdf4_offset = 0
  18599. hdf4_stride = 1
  18600. ! count is by default the shape; padd with singleton dimensions:
  18601. hdf4_count = 1; hdf4_count(1:2) = shape(values)
  18602. ! replace by optional arguments if necessary:
  18603. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  18604. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  18605. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  18606. ! test target type;
  18607. ! convert to required kind before entering sfWData,
  18608. ! otherwise segmentation faults on some machines ...
  18609. select case ( varp%xtype )
  18610. case ( MDF_BYTE )
  18611. allocate( values_int1(size(values,1),size(values,2)) )
  18612. values_int1 = int(values,kind=1)
  18613. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18614. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  18615. deallocate( values_int1 )
  18616. case ( MDF_SHORT )
  18617. allocate( values_int2(size(values,1),size(values,2)) )
  18618. values_int2 = int(values,kind=2)
  18619. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18620. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  18621. deallocate( values_int2 )
  18622. case ( MDF_INT )
  18623. allocate( values_int4(size(values,1),size(values,2)) )
  18624. values_int4 = int(values,kind=4)
  18625. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18626. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  18627. deallocate( values_int4 )
  18628. case ( MDF_FLOAT )
  18629. allocate( values_real4(size(values,1),size(values,2)) )
  18630. values_real4 = real(values,kind=4)
  18631. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18632. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  18633. deallocate( values_real4 )
  18634. case ( MDF_DOUBLE )
  18635. allocate( values_real8(size(values,1),size(values,2)) )
  18636. values_real8 = real(values,kind=8)
  18637. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  18638. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  18639. deallocate( values_real8 )
  18640. case default
  18641. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  18642. TRACEBACK; status=1; return
  18643. end select
  18644. if ( status == FAIL ) then
  18645. write (gol,'("writing hdf4 data set:")'); call goErr
  18646. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  18647. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  18648. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  18649. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  18650. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  18651. write (gol,'(" size : ",i12)') size(values); call goErr
  18652. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  18653. TRACEBACK; status=1; return
  18654. end if
  18655. #endif
  18656. #ifdef with_hdf5_beta
  18657. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18658. case ( MDF_HDF5 )
  18659. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18660. ! check ...
  18661. if ( present(map ) ) then
  18662. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  18663. TRACEBACK; status=1; return
  18664. end if
  18665. ! fill offset (zero based!), stride, and count :
  18666. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  18667. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  18668. hdf5_count = 1 ! default singleton dimension
  18669. if ( present(count) ) then
  18670. hdf5_count(1:varp%ndim) = count
  18671. else
  18672. hdf5_count(1:2) = shape(values)
  18673. end if
  18674. ! new dimension:
  18675. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  18676. ! target data space in file:
  18677. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  18678. IF_NOT_OK_RETURN(status=1)
  18679. ! chunked dataset ?
  18680. if ( varp%hdf5_chunked ) then
  18681. ! reset extend:
  18682. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  18683. IF_NOT_OK_RETURN(status=1)
  18684. end if
  18685. ! select hyperslab:
  18686. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  18687. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  18688. stride=hdf5_stride(1:varp%ndim) )
  18689. ! write data:
  18690. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  18691. int(shape(values),kind=HSIZE_T), status, &
  18692. file_space_id=hdf5_file_space_id )
  18693. IF_NOT_OK_RETURN(status=1)
  18694. ! release data space:
  18695. call H5SClose_f( hdf5_file_space_id, status )
  18696. IF_NOT_OK_RETURN(status=1)
  18697. #endif
  18698. #ifdef with_netcdf
  18699. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18700. case ( MDF_NETCDF, MDF_NETCDF4 )
  18701. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18702. ! test target type:
  18703. ! convert to required kind before entering NF90_Put_Var,
  18704. ! otherwise segmentation faults on some machines ...
  18705. select case ( varp%xtype )
  18706. case ( MDF_BYTE )
  18707. allocate( values_int1(size(values,1),size(values,2)) )
  18708. values_int1 = int(values,kind=1)
  18709. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  18710. start, count, stride, map )
  18711. IF_NF90_NOT_OK_RETURN(status=1)
  18712. deallocate( values_int1 )
  18713. case ( MDF_SHORT )
  18714. allocate( values_int2(size(values,1),size(values,2)) )
  18715. values_int2 = int(values,kind=2)
  18716. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  18717. start, count, stride, map )
  18718. IF_NF90_NOT_OK_RETURN(status=1)
  18719. deallocate( values_int2 )
  18720. case ( MDF_INT )
  18721. allocate( values_int4(size(values,1),size(values,2)) )
  18722. values_int4 = int(values,kind=4)
  18723. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  18724. start, count, stride, map )
  18725. IF_NF90_NOT_OK_RETURN(status=1)
  18726. deallocate( values_int4 )
  18727. case ( MDF_FLOAT )
  18728. allocate( values_real4(size(values,1),size(values,2)) )
  18729. values_real4 = real(values,kind=4)
  18730. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  18731. start, count, stride, map )
  18732. IF_NF90_NOT_OK_RETURN(status=1)
  18733. deallocate( values_real4 )
  18734. case ( MDF_DOUBLE )
  18735. allocate( values_real8(size(values,1),size(values,2)) )
  18736. values_real8 = real(values,kind=8)
  18737. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  18738. start, count, stride, map )
  18739. IF_NF90_NOT_OK_RETURN(status=1)
  18740. deallocate( values_real8 )
  18741. case default
  18742. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  18743. TRACEBACK; status=1; return
  18744. end select
  18745. ! just put; let netcdf library convert the right kind:
  18746. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  18747. ! start, count, stride, map )
  18748. !IF_NF90_NOT_OK_RETURN(status=1)
  18749. #endif
  18750. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18751. case default
  18752. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18753. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  18754. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  18755. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  18756. TRACEBACK; status=1; return
  18757. end select
  18758. end do ! file types
  18759. ! ok
  18760. status = 0
  18761. end subroutine MDF_Put_Var_r8_2d
  18762. ! ***
  18763. subroutine MDF_Get_Var_r8_2d( hid, varid, values, status, &
  18764. start, count, stride, map )
  18765. #ifdef with_netcdf
  18766. use NetCDF, only : NF90_Get_Var
  18767. #endif
  18768. ! --- in/out -------------------------------------
  18769. integer, intent(in) :: hid
  18770. integer, intent(in) :: varid
  18771. real(8), intent(out) :: values(:,:)
  18772. integer, intent(out) :: status
  18773. integer, intent(in), optional :: start (:)
  18774. integer, intent(in), optional :: count (:)
  18775. integer, intent(in), optional :: stride(:)
  18776. integer, intent(in), optional :: map (:)
  18777. ! --- const --------------------------------------
  18778. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_2d'
  18779. ! --- external -----------------------------------
  18780. #ifdef with_hdf4
  18781. integer(hdf4_wpi), external :: sfRData
  18782. #endif
  18783. ! --- local --------------------------------------
  18784. type(MDF_File), pointer :: filep
  18785. type(MDF_Var), pointer :: varp
  18786. integer :: iftype
  18787. integer :: ftype
  18788. #ifdef with_hdf4
  18789. integer :: hdf4_offset(MAX_RANK)
  18790. integer :: hdf4_stride(MAX_RANK)
  18791. integer :: hdf4_count(MAX_RANK)
  18792. integer(1), allocatable :: values_int1(:,:)
  18793. integer(2), allocatable :: values_int2(:,:)
  18794. integer(4), allocatable :: values_int4(:,:)
  18795. integer(8), allocatable :: values_int8(:,:)
  18796. real(4), allocatable :: values_real4(:,:)
  18797. real(8), allocatable :: values_real8(:,:)
  18798. #endif
  18799. ! --- begin --------------------------------------
  18800. ! pointer to file structure:
  18801. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  18802. IF_NOT_OK_RETURN(status=1)
  18803. ! pointer to variable structure:
  18804. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  18805. IF_NOT_OK_RETURN(status=1)
  18806. ! check ...
  18807. if ( size(shape(values)) > varp%ndim ) then
  18808. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  18809. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  18810. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  18811. TRACEBACK; status=1; return
  18812. end if
  18813. ! check ...
  18814. if ( present(start ) ) then
  18815. if ( size(start ) /= varp%ndim ) then
  18816. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18817. write (gol,'(" size start : ",i6)') size(start ); call goErr
  18818. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18819. TRACEBACK; status=1; return
  18820. end if
  18821. end if
  18822. if ( present(count ) ) then
  18823. if ( size(count ) /= varp%ndim ) then
  18824. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18825. write (gol,'(" size count : ",i6)') size(count ); call goErr
  18826. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18827. TRACEBACK; status=1; return
  18828. end if
  18829. end if
  18830. if ( present(stride ) ) then
  18831. if ( size(stride ) /= varp%ndim ) then
  18832. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18833. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  18834. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18835. TRACEBACK; status=1; return
  18836. end if
  18837. end if
  18838. if ( present(map ) ) then
  18839. if ( size(map ) /= varp%ndim ) then
  18840. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  18841. write (gol,'(" size map : ",i6)') size(map ); call goErr
  18842. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  18843. TRACEBACK; status=1; return
  18844. end if
  18845. end if
  18846. ! loop over file types:
  18847. do iftype = 1, filep%nftype
  18848. ! current type:
  18849. ftype = filep%ftypes(iftype)
  18850. ! select appropriate routine for each type:
  18851. select case ( ftype )
  18852. #ifdef with_hdf4
  18853. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18854. case ( MDF_HDF4 )
  18855. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18856. ! check ...
  18857. if ( present(map ) ) then
  18858. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  18859. TRACEBACK; status=1; return
  18860. end if
  18861. ! fill offset (zero based!), stride, and count :
  18862. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  18863. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  18864. hdf4_count = 1 ! default singleton dimension
  18865. hdf4_count(1:2) = shape(values)
  18866. ! test source type:
  18867. select case ( varp%hdf4_xtype )
  18868. case ( DFNT_INT8 )
  18869. allocate( values_int1(size(values,1),size(values,2)) )
  18870. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  18871. values = real(values_int1,kind=8)
  18872. deallocate( values_int1 )
  18873. case ( DFNT_INT16 )
  18874. allocate( values_int2(size(values,1),size(values,2)) )
  18875. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  18876. values = real(values_int2,kind=8)
  18877. deallocate( values_int2 )
  18878. case ( DFNT_INT32 )
  18879. allocate( values_int4(size(values,1),size(values,2)) )
  18880. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  18881. values = real(values_int4,kind=8)
  18882. deallocate( values_int4 )
  18883. case ( DFNT_INT64 )
  18884. allocate( values_int8(size(values,1),size(values,2)) )
  18885. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  18886. values = real(values_int8,kind=8)
  18887. deallocate( values_int8 )
  18888. case ( DFNT_FLOAT32 )
  18889. allocate( values_real4(size(values,1),size(values,2)) )
  18890. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  18891. values = real(values_real4,kind=8)
  18892. deallocate( values_real4 )
  18893. case ( DFNT_FLOAT64 )
  18894. allocate( values_real8(size(values,1),size(values,2)) )
  18895. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  18896. values = real(values_real8,kind=8)
  18897. deallocate( values_real8 )
  18898. case default
  18899. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  18900. TRACEBACK; status=1; return
  18901. end select
  18902. if ( status == FAIL ) then
  18903. write (gol,'("reading hdf4 data set:")'); call goErr
  18904. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  18905. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  18906. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  18907. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  18908. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  18909. write (gol,'(" size : ",i6)') size(values); call goErr
  18910. TRACEBACK; status=1; return
  18911. end if
  18912. #endif
  18913. #ifdef with_netcdf
  18914. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18915. case ( MDF_NETCDF, MDF_NETCDF4 )
  18916. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18917. ! read values, converted automatically:
  18918. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  18919. start, count, stride, map )
  18920. IF_NF90_NOT_OK_RETURN(status=1)
  18921. #endif
  18922. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18923. case default
  18924. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  18925. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  18926. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  18927. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  18928. TRACEBACK; status=1; return
  18929. end select
  18930. end do ! file types
  18931. ! ok
  18932. status = 0
  18933. end subroutine MDF_Get_Var_r8_2d
  18934. ! ***
  18935. subroutine MDF_Put_Var_r8_3d( hid, varid, values, status, &
  18936. start, count, stride, map )
  18937. #ifdef with_hdf5_beta
  18938. use HDF5, only : HID_T, HSIZE_T
  18939. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  18940. use HDF5, only : H5T_NATIVE_CHARACTER
  18941. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  18942. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  18943. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  18944. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  18945. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  18946. #endif
  18947. #ifdef with_netcdf
  18948. use NetCDF, only : NF90_Put_Var
  18949. #endif
  18950. ! --- in/out -------------------------------------
  18951. integer, intent(in) :: hid
  18952. integer, intent(in) :: varid
  18953. real(8), intent(in) :: values(:,:,:)
  18954. integer, intent(out) :: status
  18955. integer, intent(in), optional :: start (:)
  18956. integer, intent(in), optional :: count (:)
  18957. integer, intent(in), optional :: stride(:)
  18958. integer, intent(in), optional :: map (:)
  18959. ! --- const --------------------------------------
  18960. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_3d'
  18961. ! --- external -----------------------------------
  18962. #ifdef with_hdf4
  18963. integer(hdf4_wpi), external :: sfWData
  18964. #endif
  18965. ! --- local --------------------------------------
  18966. type(MDF_File), pointer :: filep
  18967. type(MDF_Var), pointer :: varp
  18968. integer :: iftype
  18969. integer :: ftype
  18970. #ifdef with_hdf4
  18971. integer :: hdf4_offset(MAX_RANK)
  18972. integer :: hdf4_stride(MAX_RANK)
  18973. integer :: hdf4_count(MAX_RANK)
  18974. #endif
  18975. #ifdef with_hdf5_beta
  18976. !integer(HID_T) :: hdf5_type_id
  18977. integer(HID_T) :: hdf5_file_space_id
  18978. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  18979. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  18980. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  18981. #endif
  18982. integer(1), allocatable :: values_int1(:,:,:)
  18983. integer(2), allocatable :: values_int2(:,:,:)
  18984. integer(4), allocatable :: values_int4(:,:,:)
  18985. integer(8), allocatable :: values_int8(:,:,:)
  18986. real(4), allocatable :: values_real4(:,:,:)
  18987. real(8), allocatable :: values_real8(:,:,:)
  18988. ! --- begin --------------------------------------
  18989. ! pointer to file structure:
  18990. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  18991. IF_NOT_OK_RETURN(status=1)
  18992. ! pointer to variable structure:
  18993. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  18994. IF_NOT_OK_RETURN(status=1)
  18995. ! check ...
  18996. if ( size(shape(values)) > varp%ndim ) then
  18997. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  18998. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  18999. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  19000. TRACEBACK; status=1; return
  19001. end if
  19002. ! check ...
  19003. if ( present(start ) ) then
  19004. if ( size(start ) /= varp%ndim ) then
  19005. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19006. write (gol,'(" size start : ",i6)') size(start ); call goErr
  19007. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19008. TRACEBACK; status=1; return
  19009. end if
  19010. end if
  19011. if ( present(count ) ) then
  19012. if ( size(count ) /= varp%ndim ) then
  19013. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19014. write (gol,'(" size count : ",i6)') size(count ); call goErr
  19015. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19016. TRACEBACK; status=1; return
  19017. end if
  19018. end if
  19019. if ( present(stride ) ) then
  19020. if ( size(stride ) /= varp%ndim ) then
  19021. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19022. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  19023. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19024. TRACEBACK; status=1; return
  19025. end if
  19026. end if
  19027. if ( present(map ) ) then
  19028. if ( size(map ) /= varp%ndim ) then
  19029. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19030. write (gol,'(" size map : ",i6)') size(map ); call goErr
  19031. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19032. TRACEBACK; status=1; return
  19033. end if
  19034. end if
  19035. ! loop over file types:
  19036. do iftype = 1, filep%nftype
  19037. ! current type:
  19038. ftype = filep%ftypes(iftype)
  19039. ! select appropriate routine for each type:
  19040. select case ( ftype )
  19041. #ifdef with_hdf4
  19042. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19043. case ( MDF_HDF4 )
  19044. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19045. ! check ...
  19046. if ( present(map ) ) then
  19047. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  19048. TRACEBACK; status=1; return
  19049. end if
  19050. ! fill offset (zero based!) and stride with default values:
  19051. hdf4_offset = 0
  19052. hdf4_stride = 1
  19053. ! count is by default the shape; padd with singleton dimensions:
  19054. hdf4_count = 1; hdf4_count(1:3) = shape(values)
  19055. ! replace by optional arguments if necessary:
  19056. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  19057. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  19058. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  19059. ! test target type;
  19060. ! convert to required kind before entering sfWData,
  19061. ! otherwise segmentation faults on some machines ...
  19062. select case ( varp%xtype )
  19063. case ( MDF_BYTE )
  19064. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  19065. values_int1 = int(values,kind=1)
  19066. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19067. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  19068. deallocate( values_int1 )
  19069. case ( MDF_SHORT )
  19070. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  19071. values_int2 = int(values,kind=2)
  19072. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19073. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  19074. deallocate( values_int2 )
  19075. case ( MDF_INT )
  19076. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  19077. values_int4 = int(values,kind=4)
  19078. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19079. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  19080. deallocate( values_int4 )
  19081. case ( MDF_FLOAT )
  19082. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  19083. values_real4 = real(values,kind=4)
  19084. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19085. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  19086. deallocate( values_real4 )
  19087. case ( MDF_DOUBLE )
  19088. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  19089. values_real8 = real(values,kind=8)
  19090. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19091. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  19092. deallocate( values_real8 )
  19093. case default
  19094. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  19095. TRACEBACK; status=1; return
  19096. end select
  19097. if ( status == FAIL ) then
  19098. write (gol,'("writing hdf4 data set:")'); call goErr
  19099. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  19100. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  19101. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  19102. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  19103. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  19104. write (gol,'(" size : ",i12)') size(values); call goErr
  19105. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  19106. TRACEBACK; status=1; return
  19107. end if
  19108. #endif
  19109. #ifdef with_hdf5_beta
  19110. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19111. case ( MDF_HDF5 )
  19112. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19113. ! check ...
  19114. if ( present(map ) ) then
  19115. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  19116. TRACEBACK; status=1; return
  19117. end if
  19118. ! fill offset (zero based!), stride, and count :
  19119. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  19120. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  19121. hdf5_count = 1 ! default singleton dimension
  19122. if ( present(count) ) then
  19123. hdf5_count(1:varp%ndim) = count
  19124. else
  19125. hdf5_count(1:3) = shape(values)
  19126. end if
  19127. ! new dimension:
  19128. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  19129. ! target data space in file:
  19130. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  19131. IF_NOT_OK_RETURN(status=1)
  19132. ! chunked dataset ?
  19133. if ( varp%hdf5_chunked ) then
  19134. ! reset extend:
  19135. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  19136. IF_NOT_OK_RETURN(status=1)
  19137. end if
  19138. ! select hyperslab:
  19139. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  19140. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  19141. stride=hdf5_stride(1:varp%ndim) )
  19142. ! write data:
  19143. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  19144. int(shape(values),kind=HSIZE_T), status, &
  19145. file_space_id=hdf5_file_space_id )
  19146. IF_NOT_OK_RETURN(status=1)
  19147. ! release data space:
  19148. call H5SClose_f( hdf5_file_space_id, status )
  19149. IF_NOT_OK_RETURN(status=1)
  19150. #endif
  19151. #ifdef with_netcdf
  19152. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19153. case ( MDF_NETCDF, MDF_NETCDF4 )
  19154. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19155. ! test target type:
  19156. ! convert to required kind before entering NF90_Put_Var,
  19157. ! otherwise segmentation faults on some machines ...
  19158. select case ( varp%xtype )
  19159. case ( MDF_BYTE )
  19160. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  19161. values_int1 = int(values,kind=1)
  19162. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  19163. start, count, stride, map )
  19164. IF_NF90_NOT_OK_RETURN(status=1)
  19165. deallocate( values_int1 )
  19166. case ( MDF_SHORT )
  19167. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  19168. values_int2 = int(values,kind=2)
  19169. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  19170. start, count, stride, map )
  19171. IF_NF90_NOT_OK_RETURN(status=1)
  19172. deallocate( values_int2 )
  19173. case ( MDF_INT )
  19174. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  19175. values_int4 = int(values,kind=4)
  19176. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  19177. start, count, stride, map )
  19178. IF_NF90_NOT_OK_RETURN(status=1)
  19179. deallocate( values_int4 )
  19180. case ( MDF_FLOAT )
  19181. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  19182. values_real4 = real(values,kind=4)
  19183. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  19184. start, count, stride, map )
  19185. IF_NF90_NOT_OK_RETURN(status=1)
  19186. deallocate( values_real4 )
  19187. case ( MDF_DOUBLE )
  19188. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  19189. values_real8 = real(values,kind=8)
  19190. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  19191. start, count, stride, map )
  19192. IF_NF90_NOT_OK_RETURN(status=1)
  19193. deallocate( values_real8 )
  19194. case default
  19195. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  19196. TRACEBACK; status=1; return
  19197. end select
  19198. ! just put; let netcdf library convert the right kind:
  19199. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  19200. ! start, count, stride, map )
  19201. !IF_NF90_NOT_OK_RETURN(status=1)
  19202. #endif
  19203. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19204. case default
  19205. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19206. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  19207. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  19208. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  19209. TRACEBACK; status=1; return
  19210. end select
  19211. end do ! file types
  19212. ! ok
  19213. status = 0
  19214. end subroutine MDF_Put_Var_r8_3d
  19215. ! ***
  19216. subroutine MDF_Get_Var_r8_3d( hid, varid, values, status, &
  19217. start, count, stride, map )
  19218. #ifdef with_netcdf
  19219. use NetCDF, only : NF90_Get_Var
  19220. #endif
  19221. ! --- in/out -------------------------------------
  19222. integer, intent(in) :: hid
  19223. integer, intent(in) :: varid
  19224. real(8), intent(out) :: values(:,:,:)
  19225. integer, intent(out) :: status
  19226. integer, intent(in), optional :: start (:)
  19227. integer, intent(in), optional :: count (:)
  19228. integer, intent(in), optional :: stride(:)
  19229. integer, intent(in), optional :: map (:)
  19230. ! --- const --------------------------------------
  19231. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_3d'
  19232. ! --- external -----------------------------------
  19233. #ifdef with_hdf4
  19234. integer(hdf4_wpi), external :: sfRData
  19235. #endif
  19236. ! --- local --------------------------------------
  19237. type(MDF_File), pointer :: filep
  19238. type(MDF_Var), pointer :: varp
  19239. integer :: iftype
  19240. integer :: ftype
  19241. #ifdef with_hdf4
  19242. integer :: hdf4_offset(MAX_RANK)
  19243. integer :: hdf4_stride(MAX_RANK)
  19244. integer :: hdf4_count(MAX_RANK)
  19245. integer(1), allocatable :: values_int1(:,:,:)
  19246. integer(2), allocatable :: values_int2(:,:,:)
  19247. integer(4), allocatable :: values_int4(:,:,:)
  19248. integer(8), allocatable :: values_int8(:,:,:)
  19249. real(4), allocatable :: values_real4(:,:,:)
  19250. real(8), allocatable :: values_real8(:,:,:)
  19251. #endif
  19252. ! --- begin --------------------------------------
  19253. ! pointer to file structure:
  19254. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  19255. IF_NOT_OK_RETURN(status=1)
  19256. ! pointer to variable structure:
  19257. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  19258. IF_NOT_OK_RETURN(status=1)
  19259. ! check ...
  19260. if ( size(shape(values)) > varp%ndim ) then
  19261. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  19262. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  19263. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  19264. TRACEBACK; status=1; return
  19265. end if
  19266. ! check ...
  19267. if ( present(start ) ) then
  19268. if ( size(start ) /= varp%ndim ) then
  19269. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19270. write (gol,'(" size start : ",i6)') size(start ); call goErr
  19271. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19272. TRACEBACK; status=1; return
  19273. end if
  19274. end if
  19275. if ( present(count ) ) then
  19276. if ( size(count ) /= varp%ndim ) then
  19277. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19278. write (gol,'(" size count : ",i6)') size(count ); call goErr
  19279. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19280. TRACEBACK; status=1; return
  19281. end if
  19282. end if
  19283. if ( present(stride ) ) then
  19284. if ( size(stride ) /= varp%ndim ) then
  19285. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19286. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  19287. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19288. TRACEBACK; status=1; return
  19289. end if
  19290. end if
  19291. if ( present(map ) ) then
  19292. if ( size(map ) /= varp%ndim ) then
  19293. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19294. write (gol,'(" size map : ",i6)') size(map ); call goErr
  19295. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19296. TRACEBACK; status=1; return
  19297. end if
  19298. end if
  19299. ! loop over file types:
  19300. do iftype = 1, filep%nftype
  19301. ! current type:
  19302. ftype = filep%ftypes(iftype)
  19303. ! select appropriate routine for each type:
  19304. select case ( ftype )
  19305. #ifdef with_hdf4
  19306. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19307. case ( MDF_HDF4 )
  19308. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19309. ! check ...
  19310. if ( present(map ) ) then
  19311. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  19312. TRACEBACK; status=1; return
  19313. end if
  19314. ! fill offset (zero based!), stride, and count :
  19315. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  19316. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  19317. hdf4_count = 1 ! default singleton dimension
  19318. hdf4_count(1:3) = shape(values)
  19319. ! test source type:
  19320. select case ( varp%hdf4_xtype )
  19321. case ( DFNT_INT8 )
  19322. allocate( values_int1(size(values,1),size(values,2),size(values,3)) )
  19323. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  19324. values = real(values_int1,kind=8)
  19325. deallocate( values_int1 )
  19326. case ( DFNT_INT16 )
  19327. allocate( values_int2(size(values,1),size(values,2),size(values,3)) )
  19328. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  19329. values = real(values_int2,kind=8)
  19330. deallocate( values_int2 )
  19331. case ( DFNT_INT32 )
  19332. allocate( values_int4(size(values,1),size(values,2),size(values,3)) )
  19333. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  19334. values = real(values_int4,kind=8)
  19335. deallocate( values_int4 )
  19336. case ( DFNT_INT64 )
  19337. allocate( values_int8(size(values,1),size(values,2),size(values,3)) )
  19338. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  19339. values = real(values_int8,kind=8)
  19340. deallocate( values_int8 )
  19341. case ( DFNT_FLOAT32 )
  19342. allocate( values_real4(size(values,1),size(values,2),size(values,3)) )
  19343. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  19344. values = real(values_real4,kind=8)
  19345. deallocate( values_real4 )
  19346. case ( DFNT_FLOAT64 )
  19347. allocate( values_real8(size(values,1),size(values,2),size(values,3)) )
  19348. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  19349. values = real(values_real8,kind=8)
  19350. deallocate( values_real8 )
  19351. case default
  19352. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  19353. TRACEBACK; status=1; return
  19354. end select
  19355. if ( status == FAIL ) then
  19356. write (gol,'("reading hdf4 data set:")'); call goErr
  19357. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  19358. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  19359. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  19360. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  19361. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  19362. write (gol,'(" size : ",i6)') size(values); call goErr
  19363. TRACEBACK; status=1; return
  19364. end if
  19365. #endif
  19366. #ifdef with_netcdf
  19367. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19368. case ( MDF_NETCDF, MDF_NETCDF4 )
  19369. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19370. ! read values, converted automatically:
  19371. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  19372. start, count, stride, map )
  19373. IF_NF90_NOT_OK_RETURN(status=1)
  19374. #endif
  19375. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19376. case default
  19377. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19378. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  19379. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  19380. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  19381. TRACEBACK; status=1; return
  19382. end select
  19383. end do ! file types
  19384. ! ok
  19385. status = 0
  19386. end subroutine MDF_Get_Var_r8_3d
  19387. ! ***
  19388. subroutine MDF_Put_Var_r8_4d( hid, varid, values, status, &
  19389. start, count, stride, map )
  19390. #ifdef with_hdf5_beta
  19391. use HDF5, only : HID_T, HSIZE_T
  19392. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  19393. use HDF5, only : H5T_NATIVE_CHARACTER
  19394. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  19395. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  19396. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  19397. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  19398. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  19399. #endif
  19400. #ifdef with_netcdf
  19401. use NetCDF, only : NF90_Put_Var
  19402. #endif
  19403. ! --- in/out -------------------------------------
  19404. integer, intent(in) :: hid
  19405. integer, intent(in) :: varid
  19406. real(8), intent(in) :: values(:,:,:,:)
  19407. integer, intent(out) :: status
  19408. integer, intent(in), optional :: start (:)
  19409. integer, intent(in), optional :: count (:)
  19410. integer, intent(in), optional :: stride(:)
  19411. integer, intent(in), optional :: map (:)
  19412. ! --- const --------------------------------------
  19413. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_4d'
  19414. ! --- external -----------------------------------
  19415. #ifdef with_hdf4
  19416. integer(hdf4_wpi), external :: sfWData
  19417. #endif
  19418. ! --- local --------------------------------------
  19419. type(MDF_File), pointer :: filep
  19420. type(MDF_Var), pointer :: varp
  19421. integer :: iftype
  19422. integer :: ftype
  19423. #ifdef with_hdf4
  19424. integer :: hdf4_offset(MAX_RANK)
  19425. integer :: hdf4_stride(MAX_RANK)
  19426. integer :: hdf4_count(MAX_RANK)
  19427. #endif
  19428. #ifdef with_hdf5_beta
  19429. !integer(HID_T) :: hdf5_type_id
  19430. integer(HID_T) :: hdf5_file_space_id
  19431. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  19432. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  19433. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  19434. #endif
  19435. integer(1), allocatable :: values_int1(:,:,:,:)
  19436. integer(2), allocatable :: values_int2(:,:,:,:)
  19437. integer(4), allocatable :: values_int4(:,:,:,:)
  19438. integer(8), allocatable :: values_int8(:,:,:,:)
  19439. real(4), allocatable :: values_real4(:,:,:,:)
  19440. real(8), allocatable :: values_real8(:,:,:,:)
  19441. ! --- begin --------------------------------------
  19442. ! pointer to file structure:
  19443. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  19444. IF_NOT_OK_RETURN(status=1)
  19445. ! pointer to variable structure:
  19446. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  19447. IF_NOT_OK_RETURN(status=1)
  19448. ! check ...
  19449. if ( size(shape(values)) > varp%ndim ) then
  19450. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  19451. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  19452. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  19453. TRACEBACK; status=1; return
  19454. end if
  19455. ! check ...
  19456. if ( present(start ) ) then
  19457. if ( size(start ) /= varp%ndim ) then
  19458. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19459. write (gol,'(" size start : ",i6)') size(start ); call goErr
  19460. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19461. TRACEBACK; status=1; return
  19462. end if
  19463. end if
  19464. if ( present(count ) ) then
  19465. if ( size(count ) /= varp%ndim ) then
  19466. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19467. write (gol,'(" size count : ",i6)') size(count ); call goErr
  19468. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19469. TRACEBACK; status=1; return
  19470. end if
  19471. end if
  19472. if ( present(stride ) ) then
  19473. if ( size(stride ) /= varp%ndim ) then
  19474. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19475. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  19476. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19477. TRACEBACK; status=1; return
  19478. end if
  19479. end if
  19480. if ( present(map ) ) then
  19481. if ( size(map ) /= varp%ndim ) then
  19482. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19483. write (gol,'(" size map : ",i6)') size(map ); call goErr
  19484. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19485. TRACEBACK; status=1; return
  19486. end if
  19487. end if
  19488. ! loop over file types:
  19489. do iftype = 1, filep%nftype
  19490. ! current type:
  19491. ftype = filep%ftypes(iftype)
  19492. ! select appropriate routine for each type:
  19493. select case ( ftype )
  19494. #ifdef with_hdf4
  19495. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19496. case ( MDF_HDF4 )
  19497. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19498. ! check ...
  19499. if ( present(map ) ) then
  19500. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  19501. TRACEBACK; status=1; return
  19502. end if
  19503. ! fill offset (zero based!) and stride with default values:
  19504. hdf4_offset = 0
  19505. hdf4_stride = 1
  19506. ! count is by default the shape; padd with singleton dimensions:
  19507. hdf4_count = 1; hdf4_count(1:4) = shape(values)
  19508. ! replace by optional arguments if necessary:
  19509. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  19510. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  19511. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  19512. ! test target type;
  19513. ! convert to required kind before entering sfWData,
  19514. ! otherwise segmentation faults on some machines ...
  19515. select case ( varp%xtype )
  19516. case ( MDF_BYTE )
  19517. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19518. values_int1 = int(values,kind=1)
  19519. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19520. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  19521. deallocate( values_int1 )
  19522. case ( MDF_SHORT )
  19523. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19524. values_int2 = int(values,kind=2)
  19525. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19526. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  19527. deallocate( values_int2 )
  19528. case ( MDF_INT )
  19529. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19530. values_int4 = int(values,kind=4)
  19531. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19532. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  19533. deallocate( values_int4 )
  19534. case ( MDF_FLOAT )
  19535. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19536. values_real4 = real(values,kind=4)
  19537. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19538. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  19539. deallocate( values_real4 )
  19540. case ( MDF_DOUBLE )
  19541. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19542. values_real8 = real(values,kind=8)
  19543. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19544. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  19545. deallocate( values_real8 )
  19546. case default
  19547. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  19548. TRACEBACK; status=1; return
  19549. end select
  19550. if ( status == FAIL ) then
  19551. write (gol,'("writing hdf4 data set:")'); call goErr
  19552. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  19553. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  19554. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  19555. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  19556. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  19557. write (gol,'(" size : ",i12)') size(values); call goErr
  19558. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  19559. TRACEBACK; status=1; return
  19560. end if
  19561. #endif
  19562. #ifdef with_hdf5_beta
  19563. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19564. case ( MDF_HDF5 )
  19565. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19566. ! check ...
  19567. if ( present(map ) ) then
  19568. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  19569. TRACEBACK; status=1; return
  19570. end if
  19571. ! fill offset (zero based!), stride, and count :
  19572. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  19573. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  19574. hdf5_count = 1 ! default singleton dimension
  19575. if ( present(count) ) then
  19576. hdf5_count(1:varp%ndim) = count
  19577. else
  19578. hdf5_count(1:4) = shape(values)
  19579. end if
  19580. ! new dimension:
  19581. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  19582. ! target data space in file:
  19583. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  19584. IF_NOT_OK_RETURN(status=1)
  19585. ! chunked dataset ?
  19586. if ( varp%hdf5_chunked ) then
  19587. ! reset extend:
  19588. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  19589. IF_NOT_OK_RETURN(status=1)
  19590. end if
  19591. ! select hyperslab:
  19592. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  19593. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  19594. stride=hdf5_stride(1:varp%ndim) )
  19595. ! write data:
  19596. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  19597. int(shape(values),kind=HSIZE_T), status, &
  19598. file_space_id=hdf5_file_space_id )
  19599. IF_NOT_OK_RETURN(status=1)
  19600. ! release data space:
  19601. call H5SClose_f( hdf5_file_space_id, status )
  19602. IF_NOT_OK_RETURN(status=1)
  19603. #endif
  19604. #ifdef with_netcdf
  19605. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19606. case ( MDF_NETCDF, MDF_NETCDF4 )
  19607. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19608. ! test target type:
  19609. ! convert to required kind before entering NF90_Put_Var,
  19610. ! otherwise segmentation faults on some machines ...
  19611. select case ( varp%xtype )
  19612. case ( MDF_BYTE )
  19613. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19614. values_int1 = int(values,kind=1)
  19615. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  19616. start, count, stride, map )
  19617. IF_NF90_NOT_OK_RETURN(status=1)
  19618. deallocate( values_int1 )
  19619. case ( MDF_SHORT )
  19620. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19621. values_int2 = int(values,kind=2)
  19622. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  19623. start, count, stride, map )
  19624. IF_NF90_NOT_OK_RETURN(status=1)
  19625. deallocate( values_int2 )
  19626. case ( MDF_INT )
  19627. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19628. values_int4 = int(values,kind=4)
  19629. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  19630. start, count, stride, map )
  19631. IF_NF90_NOT_OK_RETURN(status=1)
  19632. deallocate( values_int4 )
  19633. case ( MDF_FLOAT )
  19634. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19635. values_real4 = real(values,kind=4)
  19636. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  19637. start, count, stride, map )
  19638. IF_NF90_NOT_OK_RETURN(status=1)
  19639. deallocate( values_real4 )
  19640. case ( MDF_DOUBLE )
  19641. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19642. values_real8 = real(values,kind=8)
  19643. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  19644. start, count, stride, map )
  19645. IF_NF90_NOT_OK_RETURN(status=1)
  19646. deallocate( values_real8 )
  19647. case default
  19648. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  19649. TRACEBACK; status=1; return
  19650. end select
  19651. ! just put; let netcdf library convert the right kind:
  19652. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  19653. ! start, count, stride, map )
  19654. !IF_NF90_NOT_OK_RETURN(status=1)
  19655. #endif
  19656. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19657. case default
  19658. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19659. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  19660. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  19661. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  19662. TRACEBACK; status=1; return
  19663. end select
  19664. end do ! file types
  19665. ! ok
  19666. status = 0
  19667. end subroutine MDF_Put_Var_r8_4d
  19668. ! ***
  19669. subroutine MDF_Get_Var_r8_4d( hid, varid, values, status, &
  19670. start, count, stride, map )
  19671. #ifdef with_netcdf
  19672. use NetCDF, only : NF90_Get_Var
  19673. #endif
  19674. ! --- in/out -------------------------------------
  19675. integer, intent(in) :: hid
  19676. integer, intent(in) :: varid
  19677. real(8), intent(out) :: values(:,:,:,:)
  19678. integer, intent(out) :: status
  19679. integer, intent(in), optional :: start (:)
  19680. integer, intent(in), optional :: count (:)
  19681. integer, intent(in), optional :: stride(:)
  19682. integer, intent(in), optional :: map (:)
  19683. ! --- const --------------------------------------
  19684. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_4d'
  19685. ! --- external -----------------------------------
  19686. #ifdef with_hdf4
  19687. integer(hdf4_wpi), external :: sfRData
  19688. #endif
  19689. ! --- local --------------------------------------
  19690. type(MDF_File), pointer :: filep
  19691. type(MDF_Var), pointer :: varp
  19692. integer :: iftype
  19693. integer :: ftype
  19694. #ifdef with_hdf4
  19695. integer :: hdf4_offset(MAX_RANK)
  19696. integer :: hdf4_stride(MAX_RANK)
  19697. integer :: hdf4_count(MAX_RANK)
  19698. integer(1), allocatable :: values_int1(:,:,:,:)
  19699. integer(2), allocatable :: values_int2(:,:,:,:)
  19700. integer(4), allocatable :: values_int4(:,:,:,:)
  19701. integer(8), allocatable :: values_int8(:,:,:,:)
  19702. real(4), allocatable :: values_real4(:,:,:,:)
  19703. real(8), allocatable :: values_real8(:,:,:,:)
  19704. #endif
  19705. ! --- begin --------------------------------------
  19706. ! pointer to file structure:
  19707. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  19708. IF_NOT_OK_RETURN(status=1)
  19709. ! pointer to variable structure:
  19710. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  19711. IF_NOT_OK_RETURN(status=1)
  19712. ! check ...
  19713. if ( size(shape(values)) > varp%ndim ) then
  19714. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  19715. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  19716. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  19717. TRACEBACK; status=1; return
  19718. end if
  19719. ! check ...
  19720. if ( present(start ) ) then
  19721. if ( size(start ) /= varp%ndim ) then
  19722. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19723. write (gol,'(" size start : ",i6)') size(start ); call goErr
  19724. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19725. TRACEBACK; status=1; return
  19726. end if
  19727. end if
  19728. if ( present(count ) ) then
  19729. if ( size(count ) /= varp%ndim ) then
  19730. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19731. write (gol,'(" size count : ",i6)') size(count ); call goErr
  19732. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19733. TRACEBACK; status=1; return
  19734. end if
  19735. end if
  19736. if ( present(stride ) ) then
  19737. if ( size(stride ) /= varp%ndim ) then
  19738. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19739. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  19740. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19741. TRACEBACK; status=1; return
  19742. end if
  19743. end if
  19744. if ( present(map ) ) then
  19745. if ( size(map ) /= varp%ndim ) then
  19746. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19747. write (gol,'(" size map : ",i6)') size(map ); call goErr
  19748. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19749. TRACEBACK; status=1; return
  19750. end if
  19751. end if
  19752. ! loop over file types:
  19753. do iftype = 1, filep%nftype
  19754. ! current type:
  19755. ftype = filep%ftypes(iftype)
  19756. ! select appropriate routine for each type:
  19757. select case ( ftype )
  19758. #ifdef with_hdf4
  19759. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19760. case ( MDF_HDF4 )
  19761. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19762. ! check ...
  19763. if ( present(map ) ) then
  19764. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  19765. TRACEBACK; status=1; return
  19766. end if
  19767. ! fill offset (zero based!), stride, and count :
  19768. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  19769. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  19770. hdf4_count = 1 ! default singleton dimension
  19771. hdf4_count(1:4) = shape(values)
  19772. ! test source type:
  19773. select case ( varp%hdf4_xtype )
  19774. case ( DFNT_INT8 )
  19775. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19776. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  19777. values = real(values_int1,kind=8)
  19778. deallocate( values_int1 )
  19779. case ( DFNT_INT16 )
  19780. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19781. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  19782. values = real(values_int2,kind=8)
  19783. deallocate( values_int2 )
  19784. case ( DFNT_INT32 )
  19785. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19786. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  19787. values = real(values_int4,kind=8)
  19788. deallocate( values_int4 )
  19789. case ( DFNT_INT64 )
  19790. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19791. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  19792. values = real(values_int8,kind=8)
  19793. deallocate( values_int8 )
  19794. case ( DFNT_FLOAT32 )
  19795. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19796. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  19797. values = real(values_real4,kind=8)
  19798. deallocate( values_real4 )
  19799. case ( DFNT_FLOAT64 )
  19800. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4)) )
  19801. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  19802. values = real(values_real8,kind=8)
  19803. deallocate( values_real8 )
  19804. case default
  19805. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  19806. TRACEBACK; status=1; return
  19807. end select
  19808. if ( status == FAIL ) then
  19809. write (gol,'("reading hdf4 data set:")'); call goErr
  19810. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  19811. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  19812. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  19813. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  19814. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  19815. write (gol,'(" size : ",i6)') size(values); call goErr
  19816. TRACEBACK; status=1; return
  19817. end if
  19818. #endif
  19819. #ifdef with_netcdf
  19820. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19821. case ( MDF_NETCDF, MDF_NETCDF4 )
  19822. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19823. ! read values, converted automatically:
  19824. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  19825. start, count, stride, map )
  19826. IF_NF90_NOT_OK_RETURN(status=1)
  19827. #endif
  19828. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19829. case default
  19830. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19831. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  19832. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  19833. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  19834. TRACEBACK; status=1; return
  19835. end select
  19836. end do ! file types
  19837. ! ok
  19838. status = 0
  19839. end subroutine MDF_Get_Var_r8_4d
  19840. ! ***
  19841. subroutine MDF_Put_Var_r8_5d( hid, varid, values, status, &
  19842. start, count, stride, map )
  19843. #ifdef with_hdf5_beta
  19844. use HDF5, only : HID_T, HSIZE_T
  19845. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  19846. use HDF5, only : H5T_NATIVE_CHARACTER
  19847. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  19848. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  19849. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  19850. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  19851. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  19852. #endif
  19853. #ifdef with_netcdf
  19854. use NetCDF, only : NF90_Put_Var
  19855. #endif
  19856. ! --- in/out -------------------------------------
  19857. integer, intent(in) :: hid
  19858. integer, intent(in) :: varid
  19859. real(8), intent(in) :: values(:,:,:,:,:)
  19860. integer, intent(out) :: status
  19861. integer, intent(in), optional :: start (:)
  19862. integer, intent(in), optional :: count (:)
  19863. integer, intent(in), optional :: stride(:)
  19864. integer, intent(in), optional :: map (:)
  19865. ! --- const --------------------------------------
  19866. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_5d'
  19867. ! --- external -----------------------------------
  19868. #ifdef with_hdf4
  19869. integer(hdf4_wpi), external :: sfWData
  19870. #endif
  19871. ! --- local --------------------------------------
  19872. type(MDF_File), pointer :: filep
  19873. type(MDF_Var), pointer :: varp
  19874. integer :: iftype
  19875. integer :: ftype
  19876. #ifdef with_hdf4
  19877. integer :: hdf4_offset(MAX_RANK)
  19878. integer :: hdf4_stride(MAX_RANK)
  19879. integer :: hdf4_count(MAX_RANK)
  19880. #endif
  19881. #ifdef with_hdf5_beta
  19882. !integer(HID_T) :: hdf5_type_id
  19883. integer(HID_T) :: hdf5_file_space_id
  19884. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  19885. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  19886. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  19887. #endif
  19888. integer(1), allocatable :: values_int1(:,:,:,:,:)
  19889. integer(2), allocatable :: values_int2(:,:,:,:,:)
  19890. integer(4), allocatable :: values_int4(:,:,:,:,:)
  19891. integer(8), allocatable :: values_int8(:,:,:,:,:)
  19892. real(4), allocatable :: values_real4(:,:,:,:,:)
  19893. real(8), allocatable :: values_real8(:,:,:,:,:)
  19894. ! --- begin --------------------------------------
  19895. ! pointer to file structure:
  19896. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  19897. IF_NOT_OK_RETURN(status=1)
  19898. ! pointer to variable structure:
  19899. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  19900. IF_NOT_OK_RETURN(status=1)
  19901. ! check ...
  19902. if ( size(shape(values)) > varp%ndim ) then
  19903. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  19904. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  19905. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  19906. TRACEBACK; status=1; return
  19907. end if
  19908. ! check ...
  19909. if ( present(start ) ) then
  19910. if ( size(start ) /= varp%ndim ) then
  19911. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19912. write (gol,'(" size start : ",i6)') size(start ); call goErr
  19913. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19914. TRACEBACK; status=1; return
  19915. end if
  19916. end if
  19917. if ( present(count ) ) then
  19918. if ( size(count ) /= varp%ndim ) then
  19919. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19920. write (gol,'(" size count : ",i6)') size(count ); call goErr
  19921. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19922. TRACEBACK; status=1; return
  19923. end if
  19924. end if
  19925. if ( present(stride ) ) then
  19926. if ( size(stride ) /= varp%ndim ) then
  19927. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19928. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  19929. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19930. TRACEBACK; status=1; return
  19931. end if
  19932. end if
  19933. if ( present(map ) ) then
  19934. if ( size(map ) /= varp%ndim ) then
  19935. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  19936. write (gol,'(" size map : ",i6)') size(map ); call goErr
  19937. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  19938. TRACEBACK; status=1; return
  19939. end if
  19940. end if
  19941. ! loop over file types:
  19942. do iftype = 1, filep%nftype
  19943. ! current type:
  19944. ftype = filep%ftypes(iftype)
  19945. ! select appropriate routine for each type:
  19946. select case ( ftype )
  19947. #ifdef with_hdf4
  19948. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19949. case ( MDF_HDF4 )
  19950. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  19951. ! check ...
  19952. if ( present(map ) ) then
  19953. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  19954. TRACEBACK; status=1; return
  19955. end if
  19956. ! fill offset (zero based!) and stride with default values:
  19957. hdf4_offset = 0
  19958. hdf4_stride = 1
  19959. ! count is by default the shape; padd with singleton dimensions:
  19960. hdf4_count = 1; hdf4_count(1:5) = shape(values)
  19961. ! replace by optional arguments if necessary:
  19962. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  19963. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  19964. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  19965. ! test target type;
  19966. ! convert to required kind before entering sfWData,
  19967. ! otherwise segmentation faults on some machines ...
  19968. select case ( varp%xtype )
  19969. case ( MDF_BYTE )
  19970. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  19971. values_int1 = int(values,kind=1)
  19972. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19973. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  19974. deallocate( values_int1 )
  19975. case ( MDF_SHORT )
  19976. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  19977. values_int2 = int(values,kind=2)
  19978. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19979. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  19980. deallocate( values_int2 )
  19981. case ( MDF_INT )
  19982. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  19983. values_int4 = int(values,kind=4)
  19984. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19985. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  19986. deallocate( values_int4 )
  19987. case ( MDF_FLOAT )
  19988. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  19989. values_real4 = real(values,kind=4)
  19990. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19991. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  19992. deallocate( values_real4 )
  19993. case ( MDF_DOUBLE )
  19994. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  19995. values_real8 = real(values,kind=8)
  19996. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  19997. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  19998. deallocate( values_real8 )
  19999. case default
  20000. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  20001. TRACEBACK; status=1; return
  20002. end select
  20003. if ( status == FAIL ) then
  20004. write (gol,'("writing hdf4 data set:")'); call goErr
  20005. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  20006. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  20007. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  20008. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  20009. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  20010. write (gol,'(" size : ",i12)') size(values); call goErr
  20011. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  20012. TRACEBACK; status=1; return
  20013. end if
  20014. #endif
  20015. #ifdef with_hdf5_beta
  20016. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20017. case ( MDF_HDF5 )
  20018. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20019. ! check ...
  20020. if ( present(map ) ) then
  20021. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  20022. TRACEBACK; status=1; return
  20023. end if
  20024. ! fill offset (zero based!), stride, and count :
  20025. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  20026. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  20027. hdf5_count = 1 ! default singleton dimension
  20028. if ( present(count) ) then
  20029. hdf5_count(1:varp%ndim) = count
  20030. else
  20031. hdf5_count(1:5) = shape(values)
  20032. end if
  20033. ! new dimension:
  20034. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  20035. ! target data space in file:
  20036. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  20037. IF_NOT_OK_RETURN(status=1)
  20038. ! chunked dataset ?
  20039. if ( varp%hdf5_chunked ) then
  20040. ! reset extend:
  20041. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  20042. IF_NOT_OK_RETURN(status=1)
  20043. end if
  20044. ! select hyperslab:
  20045. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  20046. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  20047. stride=hdf5_stride(1:varp%ndim) )
  20048. ! write data:
  20049. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  20050. int(shape(values),kind=HSIZE_T), status, &
  20051. file_space_id=hdf5_file_space_id )
  20052. IF_NOT_OK_RETURN(status=1)
  20053. ! release data space:
  20054. call H5SClose_f( hdf5_file_space_id, status )
  20055. IF_NOT_OK_RETURN(status=1)
  20056. #endif
  20057. #ifdef with_netcdf
  20058. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20059. case ( MDF_NETCDF, MDF_NETCDF4 )
  20060. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20061. ! test target type:
  20062. ! convert to required kind before entering NF90_Put_Var,
  20063. ! otherwise segmentation faults on some machines ...
  20064. select case ( varp%xtype )
  20065. case ( MDF_BYTE )
  20066. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20067. values_int1 = int(values,kind=1)
  20068. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  20069. start, count, stride, map )
  20070. IF_NF90_NOT_OK_RETURN(status=1)
  20071. deallocate( values_int1 )
  20072. case ( MDF_SHORT )
  20073. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20074. values_int2 = int(values,kind=2)
  20075. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  20076. start, count, stride, map )
  20077. IF_NF90_NOT_OK_RETURN(status=1)
  20078. deallocate( values_int2 )
  20079. case ( MDF_INT )
  20080. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20081. values_int4 = int(values,kind=4)
  20082. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  20083. start, count, stride, map )
  20084. IF_NF90_NOT_OK_RETURN(status=1)
  20085. deallocate( values_int4 )
  20086. case ( MDF_FLOAT )
  20087. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20088. values_real4 = real(values,kind=4)
  20089. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  20090. start, count, stride, map )
  20091. IF_NF90_NOT_OK_RETURN(status=1)
  20092. deallocate( values_real4 )
  20093. case ( MDF_DOUBLE )
  20094. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20095. values_real8 = real(values,kind=8)
  20096. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  20097. start, count, stride, map )
  20098. IF_NF90_NOT_OK_RETURN(status=1)
  20099. deallocate( values_real8 )
  20100. case default
  20101. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  20102. TRACEBACK; status=1; return
  20103. end select
  20104. ! just put; let netcdf library convert the right kind:
  20105. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  20106. ! start, count, stride, map )
  20107. !IF_NF90_NOT_OK_RETURN(status=1)
  20108. #endif
  20109. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20110. case default
  20111. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20112. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  20113. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  20114. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  20115. TRACEBACK; status=1; return
  20116. end select
  20117. end do ! file types
  20118. ! ok
  20119. status = 0
  20120. end subroutine MDF_Put_Var_r8_5d
  20121. ! ***
  20122. subroutine MDF_Get_Var_r8_5d( hid, varid, values, status, &
  20123. start, count, stride, map )
  20124. #ifdef with_netcdf
  20125. use NetCDF, only : NF90_Get_Var
  20126. #endif
  20127. ! --- in/out -------------------------------------
  20128. integer, intent(in) :: hid
  20129. integer, intent(in) :: varid
  20130. real(8), intent(out) :: values(:,:,:,:,:)
  20131. integer, intent(out) :: status
  20132. integer, intent(in), optional :: start (:)
  20133. integer, intent(in), optional :: count (:)
  20134. integer, intent(in), optional :: stride(:)
  20135. integer, intent(in), optional :: map (:)
  20136. ! --- const --------------------------------------
  20137. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_5d'
  20138. ! --- external -----------------------------------
  20139. #ifdef with_hdf4
  20140. integer(hdf4_wpi), external :: sfRData
  20141. #endif
  20142. ! --- local --------------------------------------
  20143. type(MDF_File), pointer :: filep
  20144. type(MDF_Var), pointer :: varp
  20145. integer :: iftype
  20146. integer :: ftype
  20147. #ifdef with_hdf4
  20148. integer :: hdf4_offset(MAX_RANK)
  20149. integer :: hdf4_stride(MAX_RANK)
  20150. integer :: hdf4_count(MAX_RANK)
  20151. integer(1), allocatable :: values_int1(:,:,:,:,:)
  20152. integer(2), allocatable :: values_int2(:,:,:,:,:)
  20153. integer(4), allocatable :: values_int4(:,:,:,:,:)
  20154. integer(8), allocatable :: values_int8(:,:,:,:,:)
  20155. real(4), allocatable :: values_real4(:,:,:,:,:)
  20156. real(8), allocatable :: values_real8(:,:,:,:,:)
  20157. #endif
  20158. ! --- begin --------------------------------------
  20159. ! pointer to file structure:
  20160. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  20161. IF_NOT_OK_RETURN(status=1)
  20162. ! pointer to variable structure:
  20163. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  20164. IF_NOT_OK_RETURN(status=1)
  20165. ! check ...
  20166. if ( size(shape(values)) > varp%ndim ) then
  20167. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  20168. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  20169. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  20170. TRACEBACK; status=1; return
  20171. end if
  20172. ! check ...
  20173. if ( present(start ) ) then
  20174. if ( size(start ) /= varp%ndim ) then
  20175. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20176. write (gol,'(" size start : ",i6)') size(start ); call goErr
  20177. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20178. TRACEBACK; status=1; return
  20179. end if
  20180. end if
  20181. if ( present(count ) ) then
  20182. if ( size(count ) /= varp%ndim ) then
  20183. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20184. write (gol,'(" size count : ",i6)') size(count ); call goErr
  20185. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20186. TRACEBACK; status=1; return
  20187. end if
  20188. end if
  20189. if ( present(stride ) ) then
  20190. if ( size(stride ) /= varp%ndim ) then
  20191. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20192. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  20193. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20194. TRACEBACK; status=1; return
  20195. end if
  20196. end if
  20197. if ( present(map ) ) then
  20198. if ( size(map ) /= varp%ndim ) then
  20199. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20200. write (gol,'(" size map : ",i6)') size(map ); call goErr
  20201. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20202. TRACEBACK; status=1; return
  20203. end if
  20204. end if
  20205. ! loop over file types:
  20206. do iftype = 1, filep%nftype
  20207. ! current type:
  20208. ftype = filep%ftypes(iftype)
  20209. ! select appropriate routine for each type:
  20210. select case ( ftype )
  20211. #ifdef with_hdf4
  20212. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20213. case ( MDF_HDF4 )
  20214. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20215. ! check ...
  20216. if ( present(map ) ) then
  20217. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  20218. TRACEBACK; status=1; return
  20219. end if
  20220. ! fill offset (zero based!), stride, and count :
  20221. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  20222. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  20223. hdf4_count = 1 ! default singleton dimension
  20224. hdf4_count(1:5) = shape(values)
  20225. ! test source type:
  20226. select case ( varp%hdf4_xtype )
  20227. case ( DFNT_INT8 )
  20228. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20229. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  20230. values = real(values_int1,kind=8)
  20231. deallocate( values_int1 )
  20232. case ( DFNT_INT16 )
  20233. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20234. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  20235. values = real(values_int2,kind=8)
  20236. deallocate( values_int2 )
  20237. case ( DFNT_INT32 )
  20238. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20239. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  20240. values = real(values_int4,kind=8)
  20241. deallocate( values_int4 )
  20242. case ( DFNT_INT64 )
  20243. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20244. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  20245. values = real(values_int8,kind=8)
  20246. deallocate( values_int8 )
  20247. case ( DFNT_FLOAT32 )
  20248. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20249. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  20250. values = real(values_real4,kind=8)
  20251. deallocate( values_real4 )
  20252. case ( DFNT_FLOAT64 )
  20253. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5)) )
  20254. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  20255. values = real(values_real8,kind=8)
  20256. deallocate( values_real8 )
  20257. case default
  20258. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  20259. TRACEBACK; status=1; return
  20260. end select
  20261. if ( status == FAIL ) then
  20262. write (gol,'("reading hdf4 data set:")'); call goErr
  20263. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  20264. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  20265. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  20266. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  20267. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  20268. write (gol,'(" size : ",i6)') size(values); call goErr
  20269. TRACEBACK; status=1; return
  20270. end if
  20271. #endif
  20272. #ifdef with_netcdf
  20273. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20274. case ( MDF_NETCDF, MDF_NETCDF4 )
  20275. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20276. ! read values, converted automatically:
  20277. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  20278. start, count, stride, map )
  20279. IF_NF90_NOT_OK_RETURN(status=1)
  20280. #endif
  20281. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20282. case default
  20283. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20284. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  20285. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  20286. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  20287. TRACEBACK; status=1; return
  20288. end select
  20289. end do ! file types
  20290. ! ok
  20291. status = 0
  20292. end subroutine MDF_Get_Var_r8_5d
  20293. ! ***
  20294. subroutine MDF_Put_Var_r8_6d( hid, varid, values, status, &
  20295. start, count, stride, map )
  20296. #ifdef with_hdf5_beta
  20297. use HDF5, only : HID_T, HSIZE_T
  20298. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  20299. use HDF5, only : H5T_NATIVE_CHARACTER
  20300. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  20301. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  20302. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  20303. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  20304. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  20305. #endif
  20306. #ifdef with_netcdf
  20307. use NetCDF, only : NF90_Put_Var
  20308. #endif
  20309. ! --- in/out -------------------------------------
  20310. integer, intent(in) :: hid
  20311. integer, intent(in) :: varid
  20312. real(8), intent(in) :: values(:,:,:,:,:,:)
  20313. integer, intent(out) :: status
  20314. integer, intent(in), optional :: start (:)
  20315. integer, intent(in), optional :: count (:)
  20316. integer, intent(in), optional :: stride(:)
  20317. integer, intent(in), optional :: map (:)
  20318. ! --- const --------------------------------------
  20319. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_6d'
  20320. ! --- external -----------------------------------
  20321. #ifdef with_hdf4
  20322. integer(hdf4_wpi), external :: sfWData
  20323. #endif
  20324. ! --- local --------------------------------------
  20325. type(MDF_File), pointer :: filep
  20326. type(MDF_Var), pointer :: varp
  20327. integer :: iftype
  20328. integer :: ftype
  20329. #ifdef with_hdf4
  20330. integer :: hdf4_offset(MAX_RANK)
  20331. integer :: hdf4_stride(MAX_RANK)
  20332. integer :: hdf4_count(MAX_RANK)
  20333. #endif
  20334. #ifdef with_hdf5_beta
  20335. !integer(HID_T) :: hdf5_type_id
  20336. integer(HID_T) :: hdf5_file_space_id
  20337. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  20338. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  20339. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  20340. #endif
  20341. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  20342. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  20343. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  20344. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  20345. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  20346. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  20347. ! --- begin --------------------------------------
  20348. ! pointer to file structure:
  20349. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  20350. IF_NOT_OK_RETURN(status=1)
  20351. ! pointer to variable structure:
  20352. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  20353. IF_NOT_OK_RETURN(status=1)
  20354. ! check ...
  20355. if ( size(shape(values)) > varp%ndim ) then
  20356. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  20357. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  20358. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  20359. TRACEBACK; status=1; return
  20360. end if
  20361. ! check ...
  20362. if ( present(start ) ) then
  20363. if ( size(start ) /= varp%ndim ) then
  20364. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20365. write (gol,'(" size start : ",i6)') size(start ); call goErr
  20366. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20367. TRACEBACK; status=1; return
  20368. end if
  20369. end if
  20370. if ( present(count ) ) then
  20371. if ( size(count ) /= varp%ndim ) then
  20372. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20373. write (gol,'(" size count : ",i6)') size(count ); call goErr
  20374. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20375. TRACEBACK; status=1; return
  20376. end if
  20377. end if
  20378. if ( present(stride ) ) then
  20379. if ( size(stride ) /= varp%ndim ) then
  20380. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20381. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  20382. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20383. TRACEBACK; status=1; return
  20384. end if
  20385. end if
  20386. if ( present(map ) ) then
  20387. if ( size(map ) /= varp%ndim ) then
  20388. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20389. write (gol,'(" size map : ",i6)') size(map ); call goErr
  20390. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20391. TRACEBACK; status=1; return
  20392. end if
  20393. end if
  20394. ! loop over file types:
  20395. do iftype = 1, filep%nftype
  20396. ! current type:
  20397. ftype = filep%ftypes(iftype)
  20398. ! select appropriate routine for each type:
  20399. select case ( ftype )
  20400. #ifdef with_hdf4
  20401. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20402. case ( MDF_HDF4 )
  20403. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20404. ! check ...
  20405. if ( present(map ) ) then
  20406. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  20407. TRACEBACK; status=1; return
  20408. end if
  20409. ! fill offset (zero based!) and stride with default values:
  20410. hdf4_offset = 0
  20411. hdf4_stride = 1
  20412. ! count is by default the shape; padd with singleton dimensions:
  20413. hdf4_count = 1; hdf4_count(1:6) = shape(values)
  20414. ! replace by optional arguments if necessary:
  20415. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  20416. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  20417. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  20418. ! test target type;
  20419. ! convert to required kind before entering sfWData,
  20420. ! otherwise segmentation faults on some machines ...
  20421. select case ( varp%xtype )
  20422. case ( MDF_BYTE )
  20423. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20424. values_int1 = int(values,kind=1)
  20425. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20426. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  20427. deallocate( values_int1 )
  20428. case ( MDF_SHORT )
  20429. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20430. values_int2 = int(values,kind=2)
  20431. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20432. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  20433. deallocate( values_int2 )
  20434. case ( MDF_INT )
  20435. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20436. values_int4 = int(values,kind=4)
  20437. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20438. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  20439. deallocate( values_int4 )
  20440. case ( MDF_FLOAT )
  20441. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20442. values_real4 = real(values,kind=4)
  20443. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20444. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  20445. deallocate( values_real4 )
  20446. case ( MDF_DOUBLE )
  20447. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20448. values_real8 = real(values,kind=8)
  20449. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20450. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  20451. deallocate( values_real8 )
  20452. case default
  20453. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  20454. TRACEBACK; status=1; return
  20455. end select
  20456. if ( status == FAIL ) then
  20457. write (gol,'("writing hdf4 data set:")'); call goErr
  20458. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  20459. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  20460. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  20461. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  20462. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  20463. write (gol,'(" size : ",i12)') size(values); call goErr
  20464. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  20465. TRACEBACK; status=1; return
  20466. end if
  20467. #endif
  20468. #ifdef with_hdf5_beta
  20469. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20470. case ( MDF_HDF5 )
  20471. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20472. ! check ...
  20473. if ( present(map ) ) then
  20474. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  20475. TRACEBACK; status=1; return
  20476. end if
  20477. ! fill offset (zero based!), stride, and count :
  20478. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  20479. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  20480. hdf5_count = 1 ! default singleton dimension
  20481. if ( present(count) ) then
  20482. hdf5_count(1:varp%ndim) = count
  20483. else
  20484. hdf5_count(1:6) = shape(values)
  20485. end if
  20486. ! new dimension:
  20487. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  20488. ! target data space in file:
  20489. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  20490. IF_NOT_OK_RETURN(status=1)
  20491. ! chunked dataset ?
  20492. if ( varp%hdf5_chunked ) then
  20493. ! reset extend:
  20494. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  20495. IF_NOT_OK_RETURN(status=1)
  20496. end if
  20497. ! select hyperslab:
  20498. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  20499. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  20500. stride=hdf5_stride(1:varp%ndim) )
  20501. ! write data:
  20502. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  20503. int(shape(values),kind=HSIZE_T), status, &
  20504. file_space_id=hdf5_file_space_id )
  20505. IF_NOT_OK_RETURN(status=1)
  20506. ! release data space:
  20507. call H5SClose_f( hdf5_file_space_id, status )
  20508. IF_NOT_OK_RETURN(status=1)
  20509. #endif
  20510. #ifdef with_netcdf
  20511. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20512. case ( MDF_NETCDF, MDF_NETCDF4 )
  20513. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20514. ! test target type:
  20515. ! convert to required kind before entering NF90_Put_Var,
  20516. ! otherwise segmentation faults on some machines ...
  20517. select case ( varp%xtype )
  20518. case ( MDF_BYTE )
  20519. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20520. values_int1 = int(values,kind=1)
  20521. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  20522. start, count, stride, map )
  20523. IF_NF90_NOT_OK_RETURN(status=1)
  20524. deallocate( values_int1 )
  20525. case ( MDF_SHORT )
  20526. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20527. values_int2 = int(values,kind=2)
  20528. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  20529. start, count, stride, map )
  20530. IF_NF90_NOT_OK_RETURN(status=1)
  20531. deallocate( values_int2 )
  20532. case ( MDF_INT )
  20533. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20534. values_int4 = int(values,kind=4)
  20535. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  20536. start, count, stride, map )
  20537. IF_NF90_NOT_OK_RETURN(status=1)
  20538. deallocate( values_int4 )
  20539. case ( MDF_FLOAT )
  20540. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20541. values_real4 = real(values,kind=4)
  20542. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  20543. start, count, stride, map )
  20544. IF_NF90_NOT_OK_RETURN(status=1)
  20545. deallocate( values_real4 )
  20546. case ( MDF_DOUBLE )
  20547. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20548. values_real8 = real(values,kind=8)
  20549. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  20550. start, count, stride, map )
  20551. IF_NF90_NOT_OK_RETURN(status=1)
  20552. deallocate( values_real8 )
  20553. case default
  20554. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  20555. TRACEBACK; status=1; return
  20556. end select
  20557. ! just put; let netcdf library convert the right kind:
  20558. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  20559. ! start, count, stride, map )
  20560. !IF_NF90_NOT_OK_RETURN(status=1)
  20561. #endif
  20562. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20563. case default
  20564. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20565. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  20566. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  20567. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  20568. TRACEBACK; status=1; return
  20569. end select
  20570. end do ! file types
  20571. ! ok
  20572. status = 0
  20573. end subroutine MDF_Put_Var_r8_6d
  20574. ! ***
  20575. subroutine MDF_Get_Var_r8_6d( hid, varid, values, status, &
  20576. start, count, stride, map )
  20577. #ifdef with_netcdf
  20578. use NetCDF, only : NF90_Get_Var
  20579. #endif
  20580. ! --- in/out -------------------------------------
  20581. integer, intent(in) :: hid
  20582. integer, intent(in) :: varid
  20583. real(8), intent(out) :: values(:,:,:,:,:,:)
  20584. integer, intent(out) :: status
  20585. integer, intent(in), optional :: start (:)
  20586. integer, intent(in), optional :: count (:)
  20587. integer, intent(in), optional :: stride(:)
  20588. integer, intent(in), optional :: map (:)
  20589. ! --- const --------------------------------------
  20590. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_6d'
  20591. ! --- external -----------------------------------
  20592. #ifdef with_hdf4
  20593. integer(hdf4_wpi), external :: sfRData
  20594. #endif
  20595. ! --- local --------------------------------------
  20596. type(MDF_File), pointer :: filep
  20597. type(MDF_Var), pointer :: varp
  20598. integer :: iftype
  20599. integer :: ftype
  20600. #ifdef with_hdf4
  20601. integer :: hdf4_offset(MAX_RANK)
  20602. integer :: hdf4_stride(MAX_RANK)
  20603. integer :: hdf4_count(MAX_RANK)
  20604. integer(1), allocatable :: values_int1(:,:,:,:,:,:)
  20605. integer(2), allocatable :: values_int2(:,:,:,:,:,:)
  20606. integer(4), allocatable :: values_int4(:,:,:,:,:,:)
  20607. integer(8), allocatable :: values_int8(:,:,:,:,:,:)
  20608. real(4), allocatable :: values_real4(:,:,:,:,:,:)
  20609. real(8), allocatable :: values_real8(:,:,:,:,:,:)
  20610. #endif
  20611. ! --- begin --------------------------------------
  20612. ! pointer to file structure:
  20613. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  20614. IF_NOT_OK_RETURN(status=1)
  20615. ! pointer to variable structure:
  20616. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  20617. IF_NOT_OK_RETURN(status=1)
  20618. ! check ...
  20619. if ( size(shape(values)) > varp%ndim ) then
  20620. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  20621. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  20622. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  20623. TRACEBACK; status=1; return
  20624. end if
  20625. ! check ...
  20626. if ( present(start ) ) then
  20627. if ( size(start ) /= varp%ndim ) then
  20628. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20629. write (gol,'(" size start : ",i6)') size(start ); call goErr
  20630. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20631. TRACEBACK; status=1; return
  20632. end if
  20633. end if
  20634. if ( present(count ) ) then
  20635. if ( size(count ) /= varp%ndim ) then
  20636. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20637. write (gol,'(" size count : ",i6)') size(count ); call goErr
  20638. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20639. TRACEBACK; status=1; return
  20640. end if
  20641. end if
  20642. if ( present(stride ) ) then
  20643. if ( size(stride ) /= varp%ndim ) then
  20644. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20645. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  20646. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20647. TRACEBACK; status=1; return
  20648. end if
  20649. end if
  20650. if ( present(map ) ) then
  20651. if ( size(map ) /= varp%ndim ) then
  20652. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20653. write (gol,'(" size map : ",i6)') size(map ); call goErr
  20654. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20655. TRACEBACK; status=1; return
  20656. end if
  20657. end if
  20658. ! loop over file types:
  20659. do iftype = 1, filep%nftype
  20660. ! current type:
  20661. ftype = filep%ftypes(iftype)
  20662. ! select appropriate routine for each type:
  20663. select case ( ftype )
  20664. #ifdef with_hdf4
  20665. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20666. case ( MDF_HDF4 )
  20667. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20668. ! check ...
  20669. if ( present(map ) ) then
  20670. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  20671. TRACEBACK; status=1; return
  20672. end if
  20673. ! fill offset (zero based!), stride, and count :
  20674. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  20675. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  20676. hdf4_count = 1 ! default singleton dimension
  20677. hdf4_count(1:6) = shape(values)
  20678. ! test source type:
  20679. select case ( varp%hdf4_xtype )
  20680. case ( DFNT_INT8 )
  20681. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20682. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  20683. values = real(values_int1,kind=8)
  20684. deallocate( values_int1 )
  20685. case ( DFNT_INT16 )
  20686. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20687. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  20688. values = real(values_int2,kind=8)
  20689. deallocate( values_int2 )
  20690. case ( DFNT_INT32 )
  20691. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20692. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  20693. values = real(values_int4,kind=8)
  20694. deallocate( values_int4 )
  20695. case ( DFNT_INT64 )
  20696. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20697. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  20698. values = real(values_int8,kind=8)
  20699. deallocate( values_int8 )
  20700. case ( DFNT_FLOAT32 )
  20701. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20702. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  20703. values = real(values_real4,kind=8)
  20704. deallocate( values_real4 )
  20705. case ( DFNT_FLOAT64 )
  20706. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6)) )
  20707. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  20708. values = real(values_real8,kind=8)
  20709. deallocate( values_real8 )
  20710. case default
  20711. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  20712. TRACEBACK; status=1; return
  20713. end select
  20714. if ( status == FAIL ) then
  20715. write (gol,'("reading hdf4 data set:")'); call goErr
  20716. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  20717. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  20718. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  20719. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  20720. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  20721. write (gol,'(" size : ",i6)') size(values); call goErr
  20722. TRACEBACK; status=1; return
  20723. end if
  20724. #endif
  20725. #ifdef with_netcdf
  20726. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20727. case ( MDF_NETCDF, MDF_NETCDF4 )
  20728. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20729. ! read values, converted automatically:
  20730. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  20731. start, count, stride, map )
  20732. IF_NF90_NOT_OK_RETURN(status=1)
  20733. #endif
  20734. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20735. case default
  20736. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20737. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  20738. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  20739. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  20740. TRACEBACK; status=1; return
  20741. end select
  20742. end do ! file types
  20743. ! ok
  20744. status = 0
  20745. end subroutine MDF_Get_Var_r8_6d
  20746. ! ***
  20747. subroutine MDF_Put_Var_r8_7d( hid, varid, values, status, &
  20748. start, count, stride, map )
  20749. #ifdef with_hdf5_beta
  20750. use HDF5, only : HID_T, HSIZE_T
  20751. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  20752. use HDF5, only : H5T_NATIVE_CHARACTER
  20753. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  20754. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  20755. use HDF5, only : H5SCreate_Simple_f, H5SClose_f, H5SSelect_Hyperslab_f
  20756. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F, H5S_SELECT_SET_F
  20757. use HDF5, only : H5DWrite_f, H5DSet_Extent_f
  20758. #endif
  20759. #ifdef with_netcdf
  20760. use NetCDF, only : NF90_Put_Var
  20761. #endif
  20762. ! --- in/out -------------------------------------
  20763. integer, intent(in) :: hid
  20764. integer, intent(in) :: varid
  20765. real(8), intent(in) :: values(:,:,:,:,:,:,:)
  20766. integer, intent(out) :: status
  20767. integer, intent(in), optional :: start (:)
  20768. integer, intent(in), optional :: count (:)
  20769. integer, intent(in), optional :: stride(:)
  20770. integer, intent(in), optional :: map (:)
  20771. ! --- const --------------------------------------
  20772. character(len=*), parameter :: rname = mname//'/MDF_Put_Var_r8_7d'
  20773. ! --- external -----------------------------------
  20774. #ifdef with_hdf4
  20775. integer(hdf4_wpi), external :: sfWData
  20776. #endif
  20777. ! --- local --------------------------------------
  20778. type(MDF_File), pointer :: filep
  20779. type(MDF_Var), pointer :: varp
  20780. integer :: iftype
  20781. integer :: ftype
  20782. #ifdef with_hdf4
  20783. integer :: hdf4_offset(MAX_RANK)
  20784. integer :: hdf4_stride(MAX_RANK)
  20785. integer :: hdf4_count(MAX_RANK)
  20786. #endif
  20787. #ifdef with_hdf5_beta
  20788. !integer(HID_T) :: hdf5_type_id
  20789. integer(HID_T) :: hdf5_file_space_id
  20790. integer(HSIZE_T) :: hdf5_offset(MAX_RANK)
  20791. integer(HSIZE_T) :: hdf5_stride(MAX_RANK)
  20792. integer(HSIZE_T) :: hdf5_count (MAX_RANK)
  20793. #endif
  20794. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  20795. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  20796. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  20797. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  20798. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  20799. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  20800. ! --- begin --------------------------------------
  20801. ! pointer to file structure:
  20802. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  20803. IF_NOT_OK_RETURN(status=1)
  20804. ! pointer to variable structure:
  20805. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  20806. IF_NOT_OK_RETURN(status=1)
  20807. ! check ...
  20808. if ( size(shape(values)) > varp%ndim ) then
  20809. write (gol,'("Rank of values to be written exceeds variable dimension:")'); call goErr
  20810. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  20811. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  20812. TRACEBACK; status=1; return
  20813. end if
  20814. ! check ...
  20815. if ( present(start ) ) then
  20816. if ( size(start ) /= varp%ndim ) then
  20817. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20818. write (gol,'(" size start : ",i6)') size(start ); call goErr
  20819. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20820. TRACEBACK; status=1; return
  20821. end if
  20822. end if
  20823. if ( present(count ) ) then
  20824. if ( size(count ) /= varp%ndim ) then
  20825. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20826. write (gol,'(" size count : ",i6)') size(count ); call goErr
  20827. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20828. TRACEBACK; status=1; return
  20829. end if
  20830. end if
  20831. if ( present(stride ) ) then
  20832. if ( size(stride ) /= varp%ndim ) then
  20833. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20834. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  20835. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20836. TRACEBACK; status=1; return
  20837. end if
  20838. end if
  20839. if ( present(map ) ) then
  20840. if ( size(map ) /= varp%ndim ) then
  20841. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  20842. write (gol,'(" size map : ",i6)') size(map ); call goErr
  20843. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  20844. TRACEBACK; status=1; return
  20845. end if
  20846. end if
  20847. ! loop over file types:
  20848. do iftype = 1, filep%nftype
  20849. ! current type:
  20850. ftype = filep%ftypes(iftype)
  20851. ! select appropriate routine for each type:
  20852. select case ( ftype )
  20853. #ifdef with_hdf4
  20854. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20855. case ( MDF_HDF4 )
  20856. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20857. ! check ...
  20858. if ( present(map ) ) then
  20859. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  20860. TRACEBACK; status=1; return
  20861. end if
  20862. ! fill offset (zero based!) and stride with default values:
  20863. hdf4_offset = 0
  20864. hdf4_stride = 1
  20865. ! count is by default the shape; padd with singleton dimensions:
  20866. hdf4_count = 1; hdf4_count(1:7) = shape(values)
  20867. ! replace by optional arguments if necessary:
  20868. if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  20869. if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  20870. if ( present(count ) ) hdf4_count (1:varp%ndim) = count
  20871. ! test target type;
  20872. ! convert to required kind before entering sfWData,
  20873. ! otherwise segmentation faults on some machines ...
  20874. select case ( varp%xtype )
  20875. case ( MDF_BYTE )
  20876. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20877. values_int1 = int(values,kind=1)
  20878. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20879. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  20880. deallocate( values_int1 )
  20881. case ( MDF_SHORT )
  20882. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20883. values_int2 = int(values,kind=2)
  20884. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20885. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  20886. deallocate( values_int2 )
  20887. case ( MDF_INT )
  20888. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20889. values_int4 = int(values,kind=4)
  20890. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20891. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  20892. deallocate( values_int4 )
  20893. case ( MDF_FLOAT )
  20894. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20895. values_real4 = real(values,kind=4)
  20896. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20897. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  20898. deallocate( values_real4 )
  20899. case ( MDF_DOUBLE )
  20900. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20901. values_real8 = real(values,kind=8)
  20902. status = sfWData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), &
  20903. hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  20904. deallocate( values_real8 )
  20905. case default
  20906. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  20907. TRACEBACK; status=1; return
  20908. end select
  20909. if ( status == FAIL ) then
  20910. write (gol,'("writing hdf4 data set:")'); call goErr
  20911. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  20912. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  20913. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  20914. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  20915. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  20916. write (gol,'(" size : ",i12)') size(values); call goErr
  20917. write (gol,'("(writing a slice to a compressed data set ?)")'); call goErr
  20918. TRACEBACK; status=1; return
  20919. end if
  20920. #endif
  20921. #ifdef with_hdf5_beta
  20922. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20923. case ( MDF_HDF5 )
  20924. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20925. ! check ...
  20926. if ( present(map ) ) then
  20927. write (gol,'("argument `map` not supported for HDF5")'); call goErr
  20928. TRACEBACK; status=1; return
  20929. end if
  20930. ! fill offset (zero based!), stride, and count :
  20931. hdf5_offset = 0; if ( present(start ) ) hdf5_offset(1:varp%ndim) = start-1
  20932. hdf5_stride = 1; if ( present(stride) ) hdf5_stride(1:varp%ndim) = stride
  20933. hdf5_count = 1 ! default singleton dimension
  20934. if ( present(count) ) then
  20935. hdf5_count(1:varp%ndim) = count
  20936. else
  20937. hdf5_count(1:7) = shape(values)
  20938. end if
  20939. ! new dimension:
  20940. varp%hdf5_dims = max( varp%hdf5_dims, hdf5_offset+hdf5_count )
  20941. ! target data space in file:
  20942. call H5SCreate_Simple_f( varp%ndim, varp%hdf5_dims(1:varp%ndim), hdf5_file_space_id, status )
  20943. IF_NOT_OK_RETURN(status=1)
  20944. ! chunked dataset ?
  20945. if ( varp%hdf5_chunked ) then
  20946. ! reset extend:
  20947. call H5DSet_Extent_f( varp%hdf5_dataset_id, varp%hdf5_dims(1:varp%ndim), status )
  20948. IF_NOT_OK_RETURN(status=1)
  20949. end if
  20950. ! select hyperslab:
  20951. call H5SSelect_Hyperslab_f( hdf5_file_space_id, H5S_SELECT_SET_F, &
  20952. hdf5_offset(1:varp%ndim), hdf5_count(1:varp%ndim), status, &
  20953. stride=hdf5_stride(1:varp%ndim) )
  20954. ! write data:
  20955. call H5DWrite_f( varp%hdf5_dataset_id, H5T_NATIVE_DOUBLE, values, &
  20956. int(shape(values),kind=HSIZE_T), status, &
  20957. file_space_id=hdf5_file_space_id )
  20958. IF_NOT_OK_RETURN(status=1)
  20959. ! release data space:
  20960. call H5SClose_f( hdf5_file_space_id, status )
  20961. IF_NOT_OK_RETURN(status=1)
  20962. #endif
  20963. #ifdef with_netcdf
  20964. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20965. case ( MDF_NETCDF, MDF_NETCDF4 )
  20966. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  20967. ! test target type:
  20968. ! convert to required kind before entering NF90_Put_Var,
  20969. ! otherwise segmentation faults on some machines ...
  20970. select case ( varp%xtype )
  20971. case ( MDF_BYTE )
  20972. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20973. values_int1 = int(values,kind=1)
  20974. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int1, &
  20975. start, count, stride, map )
  20976. IF_NF90_NOT_OK_RETURN(status=1)
  20977. deallocate( values_int1 )
  20978. case ( MDF_SHORT )
  20979. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20980. values_int2 = int(values,kind=2)
  20981. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int2, &
  20982. start, count, stride, map )
  20983. IF_NF90_NOT_OK_RETURN(status=1)
  20984. deallocate( values_int2 )
  20985. case ( MDF_INT )
  20986. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20987. values_int4 = int(values,kind=4)
  20988. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_int4, &
  20989. start, count, stride, map )
  20990. IF_NF90_NOT_OK_RETURN(status=1)
  20991. deallocate( values_int4 )
  20992. case ( MDF_FLOAT )
  20993. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  20994. values_real4 = real(values,kind=4)
  20995. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real4, &
  20996. start, count, stride, map )
  20997. IF_NF90_NOT_OK_RETURN(status=1)
  20998. deallocate( values_real4 )
  20999. case ( MDF_DOUBLE )
  21000. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21001. values_real8 = real(values,kind=8)
  21002. status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values_real8, &
  21003. start, count, stride, map )
  21004. IF_NF90_NOT_OK_RETURN(status=1)
  21005. deallocate( values_real8 )
  21006. case default
  21007. write (gol,'("not implemented yet for output type : ",i6)') varp%xtype; call goPr
  21008. TRACEBACK; status=1; return
  21009. end select
  21010. ! just put; let netcdf library convert the right kind:
  21011. !status = NF90_Put_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  21012. ! start, count, stride, map )
  21013. !IF_NF90_NOT_OK_RETURN(status=1)
  21014. #endif
  21015. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21016. case default
  21017. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21018. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21019. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21020. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21021. TRACEBACK; status=1; return
  21022. end select
  21023. end do ! file types
  21024. ! ok
  21025. status = 0
  21026. end subroutine MDF_Put_Var_r8_7d
  21027. ! ***
  21028. subroutine MDF_Get_Var_r8_7d( hid, varid, values, status, &
  21029. start, count, stride, map )
  21030. #ifdef with_netcdf
  21031. use NetCDF, only : NF90_Get_Var
  21032. #endif
  21033. ! --- in/out -------------------------------------
  21034. integer, intent(in) :: hid
  21035. integer, intent(in) :: varid
  21036. real(8), intent(out) :: values(:,:,:,:,:,:,:)
  21037. integer, intent(out) :: status
  21038. integer, intent(in), optional :: start (:)
  21039. integer, intent(in), optional :: count (:)
  21040. integer, intent(in), optional :: stride(:)
  21041. integer, intent(in), optional :: map (:)
  21042. ! --- const --------------------------------------
  21043. character(len=*), parameter :: rname = mname//'/MDF_Get_Var_r8_7d'
  21044. ! --- external -----------------------------------
  21045. #ifdef with_hdf4
  21046. integer(hdf4_wpi), external :: sfRData
  21047. #endif
  21048. ! --- local --------------------------------------
  21049. type(MDF_File), pointer :: filep
  21050. type(MDF_Var), pointer :: varp
  21051. integer :: iftype
  21052. integer :: ftype
  21053. #ifdef with_hdf4
  21054. integer :: hdf4_offset(MAX_RANK)
  21055. integer :: hdf4_stride(MAX_RANK)
  21056. integer :: hdf4_count(MAX_RANK)
  21057. integer(1), allocatable :: values_int1(:,:,:,:,:,:,:)
  21058. integer(2), allocatable :: values_int2(:,:,:,:,:,:,:)
  21059. integer(4), allocatable :: values_int4(:,:,:,:,:,:,:)
  21060. integer(8), allocatable :: values_int8(:,:,:,:,:,:,:)
  21061. real(4), allocatable :: values_real4(:,:,:,:,:,:,:)
  21062. real(8), allocatable :: values_real8(:,:,:,:,:,:,:)
  21063. #endif
  21064. ! --- begin --------------------------------------
  21065. ! pointer to file structure:
  21066. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21067. IF_NOT_OK_RETURN(status=1)
  21068. ! pointer to variable structure:
  21069. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21070. IF_NOT_OK_RETURN(status=1)
  21071. ! check ...
  21072. if ( size(shape(values)) > varp%ndim ) then
  21073. write (gol,'("Rank of values to be read exceeds variable dimension:")'); call goErr
  21074. write (gol,'(" rank values : ",i6)') size(shape(values)); call goErr
  21075. write (gol,'(" variable dimension : ",i6)') varp%ndim; call goErr
  21076. TRACEBACK; status=1; return
  21077. end if
  21078. ! check ...
  21079. if ( present(start ) ) then
  21080. if ( size(start ) /= varp%ndim ) then
  21081. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  21082. write (gol,'(" size start : ",i6)') size(start ); call goErr
  21083. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  21084. TRACEBACK; status=1; return
  21085. end if
  21086. end if
  21087. if ( present(count ) ) then
  21088. if ( size(count ) /= varp%ndim ) then
  21089. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  21090. write (gol,'(" size count : ",i6)') size(count ); call goErr
  21091. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  21092. TRACEBACK; status=1; return
  21093. end if
  21094. end if
  21095. if ( present(stride ) ) then
  21096. if ( size(stride ) /= varp%ndim ) then
  21097. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  21098. write (gol,'(" size stride : ",i6)') size(stride ); call goErr
  21099. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  21100. TRACEBACK; status=1; return
  21101. end if
  21102. end if
  21103. if ( present(map ) ) then
  21104. if ( size(map ) /= varp%ndim ) then
  21105. write (gol,'("Size of position argument not equal to variable dimension:")'); call goErr
  21106. write (gol,'(" size map : ",i6)') size(map ); call goErr
  21107. write (gol,'(" var dim : ",i6)') varp%ndim; call goErr
  21108. TRACEBACK; status=1; return
  21109. end if
  21110. end if
  21111. ! loop over file types:
  21112. do iftype = 1, filep%nftype
  21113. ! current type:
  21114. ftype = filep%ftypes(iftype)
  21115. ! select appropriate routine for each type:
  21116. select case ( ftype )
  21117. #ifdef with_hdf4
  21118. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21119. case ( MDF_HDF4 )
  21120. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21121. ! check ...
  21122. if ( present(map ) ) then
  21123. write (gol,'("argument `map` not supported for HDF4")'); call goErr
  21124. TRACEBACK; status=1; return
  21125. end if
  21126. ! fill offset (zero based!), stride, and count :
  21127. hdf4_offset = 0; if ( present(start ) ) hdf4_offset(1:varp%ndim) = start-1
  21128. hdf4_stride = 1; if ( present(stride) ) hdf4_stride(1:varp%ndim) = stride
  21129. hdf4_count = 1 ! default singleton dimension
  21130. hdf4_count(1:7) = shape(values)
  21131. ! test source type:
  21132. select case ( varp%hdf4_xtype )
  21133. case ( DFNT_INT8 )
  21134. allocate( values_int1(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21135. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int1 )
  21136. values = real(values_int1,kind=8)
  21137. deallocate( values_int1 )
  21138. case ( DFNT_INT16 )
  21139. allocate( values_int2(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21140. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int2 )
  21141. values = real(values_int2,kind=8)
  21142. deallocate( values_int2 )
  21143. case ( DFNT_INT32 )
  21144. allocate( values_int4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21145. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int4 )
  21146. values = real(values_int4,kind=8)
  21147. deallocate( values_int4 )
  21148. case ( DFNT_INT64 )
  21149. allocate( values_int8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21150. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_int8 )
  21151. values = real(values_int8,kind=8)
  21152. deallocate( values_int8 )
  21153. case ( DFNT_FLOAT32 )
  21154. allocate( values_real4(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21155. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real4 )
  21156. values = real(values_real4,kind=8)
  21157. deallocate( values_real4 )
  21158. case ( DFNT_FLOAT64 )
  21159. allocate( values_real8(size(values,1),size(values,2),size(values,3),size(values,4),size(values,5),size(values,6),size(values,7)) )
  21160. status = sfRData( varp%hdf4_sdid, hdf4_offset(1:varp%ndim), hdf4_stride(1:varp%ndim), hdf4_count(1:varp%ndim), values_real8 )
  21161. values = real(values_real8,kind=8)
  21162. deallocate( values_real8 )
  21163. case default
  21164. write (gol,'("unsupported hdf4 variable type : ",i6)') varp%hdf4_xtype; call goPr
  21165. TRACEBACK; status=1; return
  21166. end select
  21167. if ( status == FAIL ) then
  21168. write (gol,'("reading hdf4 data set:")'); call goErr
  21169. write (gol,'(" file : ",a)') trim(filep%hdf4_fname); call goErr
  21170. write (gol,'(" data set : ",a)') trim(varp%name); call goErr
  21171. write (gol,'(" offset : ",100i4)') hdf4_offset(1:varp%ndim); call goErr
  21172. write (gol,'(" stride : ",100i4)') hdf4_stride(1:varp%ndim); call goErr
  21173. write (gol,'(" count : ",100i4)') hdf4_count (1:varp%ndim); call goErr
  21174. write (gol,'(" size : ",i6)') size(values); call goErr
  21175. TRACEBACK; status=1; return
  21176. end if
  21177. #endif
  21178. #ifdef with_netcdf
  21179. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21180. case ( MDF_NETCDF, MDF_NETCDF4 )
  21181. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21182. ! read values, converted automatically:
  21183. status = NF90_Get_Var( filep%netcdf_id, varp%netcdf_varid, values, &
  21184. start, count, stride, map )
  21185. IF_NF90_NOT_OK_RETURN(status=1)
  21186. #endif
  21187. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21188. case default
  21189. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21190. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21191. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21192. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21193. TRACEBACK; status=1; return
  21194. end select
  21195. end do ! file types
  21196. ! ok
  21197. status = 0
  21198. end subroutine MDF_Get_Var_r8_7d
  21199. ! ***
  21200. ! ********************************************************************
  21201. ! ***
  21202. ! *** attributes
  21203. ! ***
  21204. ! ********************************************************************
  21205. subroutine MDF_Put_Att_c1_0d( hid, varid, name, values, status )
  21206. #ifdef with_hdf5_beta
  21207. use HDF5, only : HID_T, HSIZE_T
  21208. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21209. use HDF5, only : H5T_NATIVE_CHARACTER
  21210. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  21211. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21212. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  21213. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  21214. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  21215. #endif
  21216. #ifdef with_netcdf
  21217. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  21218. #endif
  21219. ! --- in/out -------------------------------------
  21220. integer, intent(in) :: hid
  21221. integer, intent(in) :: varid
  21222. character(len=*), intent(in) :: name
  21223. character(len=*), intent(in) :: values
  21224. integer, intent(out) :: status
  21225. ! --- const --------------------------------------
  21226. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_c1_0d'
  21227. ! --- external -------------------------------
  21228. #ifdef with_hdf4
  21229. integer(hdf4_wpi), external :: sfSCAtt
  21230. integer(hdf4_wpi), external :: sfSNAtt
  21231. #endif
  21232. ! --- local --------------------------------------
  21233. type(MDF_File), pointer :: filep
  21234. type(MDF_Var), pointer :: varp
  21235. integer :: iftype
  21236. integer :: ftype
  21237. #ifdef with_hdf4
  21238. integer :: hdf4_id
  21239. #endif
  21240. #ifdef with_hdf5_beta
  21241. integer(HID_T) :: hdf5_loc_id
  21242. integer(HID_T) :: hdf5_attr_id
  21243. integer(HID_T) :: hdf5_space_id
  21244. integer(HID_T) :: hdf5_type_id
  21245. #endif
  21246. #ifdef with_netcdf
  21247. integer :: netcdf_varid
  21248. #endif
  21249. ! --- begin --------------------------------------
  21250. ! pointer to file structure:
  21251. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21252. IF_NOT_OK_RETURN(status=1)
  21253. ! global or variable attribute ?
  21254. if ( varid == MDF_GLOBAL ) then
  21255. ! increase counter:
  21256. filep%natt = filep%natt + 1
  21257. else
  21258. ! pointer to variable structure:
  21259. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21260. IF_NOT_OK_RETURN(status=1)
  21261. ! increase counter:
  21262. varp%natt = varp%natt + 1
  21263. end if
  21264. ! loop over file types:
  21265. do iftype = 1, filep%nftype
  21266. ! current type:
  21267. ftype = filep%ftypes(iftype)
  21268. ! select appropriate routine for each type:
  21269. select case ( ftype )
  21270. #ifdef with_hdf4
  21271. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21272. case ( MDF_HDF4 )
  21273. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21274. ! set variable id:
  21275. if ( varid == MDF_GLOBAL ) then
  21276. hdf4_id = filep%hdf4_id
  21277. else
  21278. hdf4_id = varp%hdf4_sdid
  21279. end if
  21280. ! store character attribute:
  21281. status = sfSCAtt( hdf4_id, trim(name), DFNT_CHAR, len(values), values )
  21282. if ( status /= SUCCEED ) then
  21283. write (*,'("writing attribute : ",a)') trim(name); call goErr
  21284. TRACEBACK; status=1; return
  21285. end if
  21286. #endif
  21287. #ifdef with_hdf5_beta
  21288. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21289. case ( MDF_HDF5 )
  21290. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21291. ! set variable id:
  21292. if ( varid == MDF_GLOBAL ) then
  21293. hdf5_loc_id = filep%hdf5_file_id
  21294. else
  21295. hdf5_loc_id = varp%hdf5_dataset_id
  21296. end if
  21297. ! data type:
  21298. call H5TCopy_f( H5T_NATIVE_CHARACTER, hdf5_type_id, status )
  21299. IF_NOT_OK_RETURN(status=1)
  21300. ! set length:
  21301. call H5TSet_Size_f( hdf5_type_id, len(values), status )
  21302. IF_NOT_OK_RETURN(status=1)
  21303. ! data space:
  21304. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  21305. IF_NOT_OK_RETURN(status=1)
  21306. ! create attribute; type in file is same as type provided to this routine:
  21307. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  21308. IF_NOT_OK_RETURN(status=1)
  21309. ! write attribute values:
  21310. call H5AWrite_f( hdf5_attr_id, hdf5_type_id, values, int((/len(values)/),kind=HSIZE_T), status )
  21311. IF_NOT_OK_RETURN(status=1)
  21312. ! release attribute:
  21313. call H5AClose_f( hdf5_attr_id, status )
  21314. IF_NOT_OK_RETURN(status=1)
  21315. ! release data space:
  21316. call H5SClose_f( hdf5_space_id, status )
  21317. IF_NOT_OK_RETURN(status=1)
  21318. ! release data type:
  21319. call H5TClose_f( hdf5_type_id, status )
  21320. IF_NOT_OK_RETURN(status=1)
  21321. #endif
  21322. #ifdef with_netcdf
  21323. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21324. case ( MDF_NETCDF, MDF_NETCDF4 )
  21325. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21326. ! set variable id:
  21327. if ( varid == MDF_GLOBAL ) then
  21328. netcdf_varid = NF90_GLOBAL
  21329. else
  21330. netcdf_varid = varp%netcdf_varid
  21331. end if
  21332. ! write attribute:
  21333. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  21334. IF_NF90_NOT_OK_RETURN(status=1)
  21335. #endif
  21336. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21337. case default
  21338. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21339. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21340. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21341. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21342. TRACEBACK; status=1; return
  21343. end select
  21344. end do ! file types
  21345. ! ok
  21346. status = 0
  21347. end subroutine MDF_Put_Att_c1_0d
  21348. ! ***
  21349. subroutine MDF_Get_Att_c1_0d( hid, varid, name, values, status )
  21350. #ifdef with_hdf5_beta
  21351. use HDF5, only : HSIZE_T
  21352. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  21353. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21354. use HDF5, only : H5T_NATIVE_CHARACTER
  21355. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  21356. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21357. #endif
  21358. #ifdef with_netcdf
  21359. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  21360. #endif
  21361. ! --- in/out -------------------------------------
  21362. integer, intent(in) :: hid
  21363. integer, intent(in) :: varid
  21364. character(len=*), intent(in) :: name
  21365. character(len=*), intent(out) :: values
  21366. integer, intent(out) :: status
  21367. ! --- const --------------------------------------
  21368. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_c1_0d'
  21369. ! --- external -------------------------------
  21370. #ifdef with_hdf4
  21371. integer(hdf4_wpi), external :: sfFAttr
  21372. integer(hdf4_wpi), external :: sfGAInfo
  21373. integer(hdf4_wpi), external :: sfRCAtt
  21374. integer(hdf4_wpi), external :: sfRNAtt
  21375. #endif
  21376. ! --- local --------------------------------------
  21377. type(MDF_File), pointer :: filep
  21378. type(MDF_Var), pointer :: varp
  21379. integer :: ftype
  21380. #ifdef with_hdf4
  21381. integer :: hdf4_id
  21382. integer :: hdf4_iatt
  21383. character(len=LEN_NAME) :: hdf4_name
  21384. integer :: hdf4_xtype
  21385. integer :: hdf4_length
  21386. #endif
  21387. #ifdef with_hdf5_beta
  21388. integer(HID_T) :: hdf5_loc_id
  21389. character(len=LEN_NAME) :: hdf5_obj_name
  21390. integer(HID_T) :: hdf5_attr_id
  21391. integer(HID_T) :: hdf5_type_id
  21392. #endif
  21393. #ifdef with_netcdf
  21394. integer :: netcdf_varid
  21395. #endif
  21396. ! --- begin --------------------------------------
  21397. ! single type:
  21398. call MDF_Get_Type( hid, ftype, status )
  21399. IF_NOT_OK_RETURN(status=1)
  21400. ! pointer to file structure:
  21401. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21402. IF_NOT_OK_RETURN(status=1)
  21403. ! pointer to variable structure if possible:
  21404. if ( varid /= MDF_GLOBAL ) then
  21405. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21406. IF_NOT_OK_RETURN(status=1)
  21407. end if
  21408. ! select appropriate routine for each type:
  21409. select case ( ftype )
  21410. #ifdef with_hdf4
  21411. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21412. case ( MDF_HDF4 )
  21413. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21414. ! set variable id:
  21415. if ( varid == MDF_GLOBAL ) then
  21416. hdf4_id = filep%hdf4_id
  21417. else
  21418. hdf4_id = varp%hdf4_sdid
  21419. end if
  21420. ! get attribute index given name:
  21421. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  21422. if ( hdf4_iatt == FAIL ) then
  21423. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  21424. TRACEBACK; status=1; return
  21425. end if
  21426. ! get type and length:
  21427. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  21428. if ( status /= SUCCEED ) then
  21429. write (gol,'("getting attribute info")') trim(name); call goErr
  21430. TRACEBACK; status=1; return
  21431. end if
  21432. ! check ...
  21433. if ( hdf4_length > len(values) ) then
  21434. write (gol,'("length of character attribute `",a,"` (",i6,") exceeds output length (",i6,") ;")') &
  21435. trim(name), hdf4_length, len(values); call goErr
  21436. TRACEBACK; status=1; return
  21437. end if
  21438. ! read character attribute:
  21439. status = sfRCAtt( hdf4_id, hdf4_iatt, values )
  21440. if ( status /= SUCCEED ) then
  21441. write (*,'("reading attribute : ",a)') trim(name); call goErr
  21442. TRACEBACK; status=1; return
  21443. end if
  21444. ! truncate ...
  21445. values = values(1:hdf4_length)
  21446. #endif
  21447. #ifdef with_hdf5_beta
  21448. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21449. case ( MDF_HDF5 )
  21450. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21451. ! set variable id:
  21452. if ( varid == MDF_GLOBAL ) then
  21453. ! file id:
  21454. hdf5_loc_id = filep%hdf5_file_id
  21455. hdf5_obj_name = '.'
  21456. else
  21457. ! file id:
  21458. hdf5_loc_id = varp%hdf5_dataset_id
  21459. hdf5_obj_name = '.'
  21460. end if
  21461. ! data type:
  21462. call H5TCopy_f( H5T_NATIVE_CHARACTER, hdf5_type_id, status )
  21463. IF_NOT_OK_RETURN(status=1)
  21464. ! set length:
  21465. call H5TSet_Size_f( hdf5_type_id, len(values), status )
  21466. IF_NOT_OK_RETURN(status=1)
  21467. ! open attribute:
  21468. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  21469. IF_NOT_OK_RETURN(status=1)
  21470. ! read:
  21471. call H5ARead_f( hdf5_attr_id, hdf5_type_id, values, int((/len(values)/),HSIZE_T), status )
  21472. IF_NOT_OK_RETURN(status=1)
  21473. ! release:
  21474. call H5TClose_f( hdf5_type_id, status )
  21475. IF_NOT_OK_RETURN(status=1)
  21476. ! release:
  21477. call H5AClose_f( hdf5_attr_id, status )
  21478. IF_NOT_OK_RETURN(status=1)
  21479. #endif
  21480. #ifdef with_netcdf
  21481. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21482. case ( MDF_NETCDF, MDF_NETCDF4 )
  21483. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21484. ! set variable id:
  21485. if ( varid == MDF_GLOBAL ) then
  21486. netcdf_varid = NF90_GLOBAL
  21487. else
  21488. netcdf_varid = varp%netcdf_varid
  21489. end if
  21490. ! read attribute:
  21491. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  21492. IF_NF90_NOT_OK_RETURN(status=1)
  21493. #endif
  21494. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21495. case default
  21496. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21497. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21498. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21499. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21500. TRACEBACK; status=1; return
  21501. end select
  21502. ! ok
  21503. status = 0
  21504. end subroutine MDF_Get_Att_c1_0d
  21505. subroutine MDF_Put_Att_i1_0d( hid, varid, name, values, status )
  21506. #ifdef with_hdf5_beta
  21507. use HDF5, only : HID_T, HSIZE_T
  21508. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21509. use HDF5, only : H5T_NATIVE_CHARACTER
  21510. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  21511. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21512. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  21513. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  21514. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  21515. #endif
  21516. #ifdef with_netcdf
  21517. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  21518. #endif
  21519. ! --- in/out -------------------------------------
  21520. integer, intent(in) :: hid
  21521. integer, intent(in) :: varid
  21522. character(len=*), intent(in) :: name
  21523. integer(1), intent(in) :: values
  21524. integer, intent(out) :: status
  21525. ! --- const --------------------------------------
  21526. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i1_0d'
  21527. ! --- external -------------------------------
  21528. #ifdef with_hdf4
  21529. integer(hdf4_wpi), external :: sfSCAtt
  21530. integer(hdf4_wpi), external :: sfSNAtt
  21531. #endif
  21532. ! --- local --------------------------------------
  21533. type(MDF_File), pointer :: filep
  21534. type(MDF_Var), pointer :: varp
  21535. integer :: iftype
  21536. integer :: ftype
  21537. #ifdef with_hdf4
  21538. integer :: hdf4_id
  21539. #endif
  21540. #ifdef with_hdf5_beta
  21541. integer(HID_T) :: hdf5_loc_id
  21542. integer(HID_T) :: hdf5_attr_id
  21543. integer(HID_T) :: hdf5_space_id
  21544. integer(HID_T) :: hdf5_type_id
  21545. #endif
  21546. #ifdef with_netcdf
  21547. integer :: netcdf_varid
  21548. #endif
  21549. ! --- begin --------------------------------------
  21550. ! pointer to file structure:
  21551. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21552. IF_NOT_OK_RETURN(status=1)
  21553. ! global or variable attribute ?
  21554. if ( varid == MDF_GLOBAL ) then
  21555. ! increase counter:
  21556. filep%natt = filep%natt + 1
  21557. else
  21558. ! pointer to variable structure:
  21559. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21560. IF_NOT_OK_RETURN(status=1)
  21561. ! increase counter:
  21562. varp%natt = varp%natt + 1
  21563. end if
  21564. ! loop over file types:
  21565. do iftype = 1, filep%nftype
  21566. ! current type:
  21567. ftype = filep%ftypes(iftype)
  21568. ! select appropriate routine for each type:
  21569. select case ( ftype )
  21570. #ifdef with_hdf4
  21571. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21572. case ( MDF_HDF4 )
  21573. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21574. ! set variable id:
  21575. if ( varid == MDF_GLOBAL ) then
  21576. hdf4_id = filep%hdf4_id
  21577. else
  21578. hdf4_id = varp%hdf4_sdid
  21579. end if
  21580. ! store numerical attribute:
  21581. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT8, 1, values )
  21582. if ( status /= SUCCEED ) then
  21583. write (*,'("writing attribute : ",a)') trim(name); call goErr
  21584. TRACEBACK; status=1; return
  21585. end if
  21586. #endif
  21587. #ifdef with_hdf5_beta
  21588. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21589. case ( MDF_HDF5 )
  21590. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21591. ! set variable id:
  21592. if ( varid == MDF_GLOBAL ) then
  21593. hdf5_loc_id = filep%hdf5_file_id
  21594. else
  21595. hdf5_loc_id = varp%hdf5_dataset_id
  21596. end if
  21597. ! data type:
  21598. call H5TCopy_f( H5T_STD_I8LE, hdf5_type_id, status )
  21599. IF_NOT_OK_RETURN(status=1)
  21600. ! data space:
  21601. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  21602. IF_NOT_OK_RETURN(status=1)
  21603. ! create attribute; type in file is same as type provided to this routine:
  21604. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  21605. IF_NOT_OK_RETURN(status=1)
  21606. ! write attribute values:
  21607. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int((/1/),kind=HSIZE_T), status )
  21608. IF_NOT_OK_RETURN(status=1)
  21609. ! release attribute:
  21610. call H5AClose_f( hdf5_attr_id, status )
  21611. IF_NOT_OK_RETURN(status=1)
  21612. ! release data space:
  21613. call H5SClose_f( hdf5_space_id, status )
  21614. IF_NOT_OK_RETURN(status=1)
  21615. ! release data type:
  21616. call H5TClose_f( hdf5_type_id, status )
  21617. IF_NOT_OK_RETURN(status=1)
  21618. #endif
  21619. #ifdef with_netcdf
  21620. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21621. case ( MDF_NETCDF, MDF_NETCDF4 )
  21622. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21623. ! set variable id:
  21624. if ( varid == MDF_GLOBAL ) then
  21625. netcdf_varid = NF90_GLOBAL
  21626. else
  21627. netcdf_varid = varp%netcdf_varid
  21628. end if
  21629. ! write attribute:
  21630. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  21631. IF_NF90_NOT_OK_RETURN(status=1)
  21632. #endif
  21633. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21634. case default
  21635. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21636. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21637. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21638. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21639. TRACEBACK; status=1; return
  21640. end select
  21641. end do ! file types
  21642. ! ok
  21643. status = 0
  21644. end subroutine MDF_Put_Att_i1_0d
  21645. ! ***
  21646. subroutine MDF_Get_Att_i1_0d( hid, varid, name, values, status )
  21647. #ifdef with_hdf5_beta
  21648. use HDF5, only : HSIZE_T
  21649. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  21650. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21651. use HDF5, only : H5T_NATIVE_CHARACTER
  21652. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  21653. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21654. #endif
  21655. #ifdef with_netcdf
  21656. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  21657. #endif
  21658. ! --- in/out -------------------------------------
  21659. integer, intent(in) :: hid
  21660. integer, intent(in) :: varid
  21661. character(len=*), intent(in) :: name
  21662. integer(1), intent(out) :: values
  21663. integer, intent(out) :: status
  21664. ! --- const --------------------------------------
  21665. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i1_0d'
  21666. ! --- external -------------------------------
  21667. #ifdef with_hdf4
  21668. integer(hdf4_wpi), external :: sfFAttr
  21669. integer(hdf4_wpi), external :: sfGAInfo
  21670. integer(hdf4_wpi), external :: sfRCAtt
  21671. integer(hdf4_wpi), external :: sfRNAtt
  21672. #endif
  21673. ! --- local --------------------------------------
  21674. type(MDF_File), pointer :: filep
  21675. type(MDF_Var), pointer :: varp
  21676. integer :: ftype
  21677. #ifdef with_hdf4
  21678. integer :: hdf4_id
  21679. integer :: hdf4_iatt
  21680. character(len=LEN_NAME) :: hdf4_name
  21681. integer :: hdf4_xtype
  21682. integer :: hdf4_length
  21683. integer(1) :: values_int1
  21684. integer(2) :: values_int2
  21685. integer(4) :: values_int4
  21686. integer(8) :: values_int8
  21687. real(4) :: values_real4
  21688. real(8) :: values_real8
  21689. #endif
  21690. #ifdef with_hdf5_beta
  21691. integer(HID_T) :: hdf5_loc_id
  21692. character(len=LEN_NAME) :: hdf5_obj_name
  21693. integer(HID_T) :: hdf5_attr_id
  21694. integer(HID_T) :: hdf5_type_id
  21695. integer(4) :: hdf5_values_int4
  21696. #endif
  21697. #ifdef with_netcdf
  21698. integer :: netcdf_varid
  21699. #endif
  21700. ! --- begin --------------------------------------
  21701. ! single type:
  21702. call MDF_Get_Type( hid, ftype, status )
  21703. IF_NOT_OK_RETURN(status=1)
  21704. ! pointer to file structure:
  21705. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21706. IF_NOT_OK_RETURN(status=1)
  21707. ! pointer to variable structure if possible:
  21708. if ( varid /= MDF_GLOBAL ) then
  21709. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21710. IF_NOT_OK_RETURN(status=1)
  21711. end if
  21712. ! select appropriate routine for each type:
  21713. select case ( ftype )
  21714. #ifdef with_hdf4
  21715. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21716. case ( MDF_HDF4 )
  21717. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21718. ! set variable id:
  21719. if ( varid == MDF_GLOBAL ) then
  21720. hdf4_id = filep%hdf4_id
  21721. else
  21722. hdf4_id = varp%hdf4_sdid
  21723. end if
  21724. ! get attribute index given name:
  21725. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  21726. if ( hdf4_iatt == FAIL ) then
  21727. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  21728. TRACEBACK; status=1; return
  21729. end if
  21730. ! get type and length:
  21731. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  21732. if ( status /= SUCCEED ) then
  21733. write (gol,'("getting attribute info")') trim(name); call goErr
  21734. TRACEBACK; status=1; return
  21735. end if
  21736. ! read numerical attribute:
  21737. select case ( hdf4_xtype )
  21738. case ( DFNT_INT8 )
  21739. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  21740. values = int(values_int1,kind=1)
  21741. case ( DFNT_INT16 )
  21742. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  21743. values = int(values_int2,kind=1)
  21744. case ( DFNT_INT32 )
  21745. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  21746. values = int(values_int4,kind=1)
  21747. case ( DFNT_INT64 )
  21748. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  21749. values = int(values_int8,kind=1)
  21750. case ( DFNT_FLOAT32 )
  21751. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  21752. values = int(values_real4,kind=1)
  21753. case ( DFNT_FLOAT64 )
  21754. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  21755. values = int(values_real8,kind=1)
  21756. case default
  21757. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  21758. TRACEBACK; status=1; return
  21759. end select
  21760. if ( status /= SUCCEED ) then
  21761. write (*,'("reading attribute : ",a)') trim(name); call goErr
  21762. TRACEBACK; status=1; return
  21763. end if
  21764. #endif
  21765. #ifdef with_hdf5_beta
  21766. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21767. case ( MDF_HDF5 )
  21768. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21769. ! set variable id:
  21770. if ( varid == MDF_GLOBAL ) then
  21771. ! file id:
  21772. hdf5_loc_id = filep%hdf5_file_id
  21773. hdf5_obj_name = '.'
  21774. else
  21775. ! file id:
  21776. hdf5_loc_id = varp%hdf5_dataset_id
  21777. hdf5_obj_name = '.'
  21778. end if
  21779. ! data type:
  21780. call H5TCopy_f( H5T_STD_I8LE, hdf5_type_id, status )
  21781. IF_NOT_OK_RETURN(status=1)
  21782. ! open attribute:
  21783. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  21784. IF_NOT_OK_RETURN(status=1)
  21785. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  21786. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int((/1/),HSIZE_T), status )
  21787. IF_NOT_OK_RETURN(status=1)
  21788. ! convert:
  21789. values = int(hdf5_values_int4,1)
  21790. ! release:
  21791. call H5TClose_f( hdf5_type_id, status )
  21792. IF_NOT_OK_RETURN(status=1)
  21793. ! release:
  21794. call H5AClose_f( hdf5_attr_id, status )
  21795. IF_NOT_OK_RETURN(status=1)
  21796. #endif
  21797. #ifdef with_netcdf
  21798. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21799. case ( MDF_NETCDF, MDF_NETCDF4 )
  21800. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21801. ! set variable id:
  21802. if ( varid == MDF_GLOBAL ) then
  21803. netcdf_varid = NF90_GLOBAL
  21804. else
  21805. netcdf_varid = varp%netcdf_varid
  21806. end if
  21807. ! read attribute:
  21808. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  21809. IF_NF90_NOT_OK_RETURN(status=1)
  21810. #endif
  21811. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21812. case default
  21813. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21814. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21815. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21816. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21817. TRACEBACK; status=1; return
  21818. end select
  21819. ! ok
  21820. status = 0
  21821. end subroutine MDF_Get_Att_i1_0d
  21822. subroutine MDF_Put_Att_i1_1d( hid, varid, name, values, status )
  21823. #ifdef with_hdf5_beta
  21824. use HDF5, only : HID_T, HSIZE_T
  21825. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21826. use HDF5, only : H5T_NATIVE_CHARACTER
  21827. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  21828. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21829. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  21830. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  21831. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  21832. #endif
  21833. #ifdef with_netcdf
  21834. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  21835. #endif
  21836. ! --- in/out -------------------------------------
  21837. integer, intent(in) :: hid
  21838. integer, intent(in) :: varid
  21839. character(len=*), intent(in) :: name
  21840. integer(1), intent(in) :: values(:)
  21841. integer, intent(out) :: status
  21842. ! --- const --------------------------------------
  21843. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i1_1d'
  21844. ! --- external -------------------------------
  21845. #ifdef with_hdf4
  21846. integer(hdf4_wpi), external :: sfSCAtt
  21847. integer(hdf4_wpi), external :: sfSNAtt
  21848. #endif
  21849. ! --- local --------------------------------------
  21850. type(MDF_File), pointer :: filep
  21851. type(MDF_Var), pointer :: varp
  21852. integer :: iftype
  21853. integer :: ftype
  21854. #ifdef with_hdf4
  21855. integer :: hdf4_id
  21856. #endif
  21857. #ifdef with_hdf5_beta
  21858. integer(HID_T) :: hdf5_loc_id
  21859. integer(HID_T) :: hdf5_attr_id
  21860. integer(HID_T) :: hdf5_space_id
  21861. integer(HID_T) :: hdf5_type_id
  21862. #endif
  21863. #ifdef with_netcdf
  21864. integer :: netcdf_varid
  21865. #endif
  21866. ! --- begin --------------------------------------
  21867. ! pointer to file structure:
  21868. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  21869. IF_NOT_OK_RETURN(status=1)
  21870. ! global or variable attribute ?
  21871. if ( varid == MDF_GLOBAL ) then
  21872. ! increase counter:
  21873. filep%natt = filep%natt + 1
  21874. else
  21875. ! pointer to variable structure:
  21876. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  21877. IF_NOT_OK_RETURN(status=1)
  21878. ! increase counter:
  21879. varp%natt = varp%natt + 1
  21880. end if
  21881. ! loop over file types:
  21882. do iftype = 1, filep%nftype
  21883. ! current type:
  21884. ftype = filep%ftypes(iftype)
  21885. ! select appropriate routine for each type:
  21886. select case ( ftype )
  21887. #ifdef with_hdf4
  21888. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21889. case ( MDF_HDF4 )
  21890. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21891. ! set variable id:
  21892. if ( varid == MDF_GLOBAL ) then
  21893. hdf4_id = filep%hdf4_id
  21894. else
  21895. hdf4_id = varp%hdf4_sdid
  21896. end if
  21897. ! strore numerical attribute:
  21898. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT8, size(values), values )
  21899. if ( status /= SUCCEED ) then
  21900. write (*,'("writing attribute : ",a)') trim(name); call goErr
  21901. TRACEBACK; status=1; return
  21902. end if
  21903. #endif
  21904. #ifdef with_hdf5_beta
  21905. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21906. case ( MDF_HDF5 )
  21907. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21908. ! set variable id:
  21909. if ( varid == MDF_GLOBAL ) then
  21910. hdf5_loc_id = filep%hdf5_file_id
  21911. else
  21912. hdf5_loc_id = varp%hdf5_dataset_id
  21913. end if
  21914. ! data type:
  21915. call H5TCopy_f( H5T_STD_I8LE, hdf5_type_id, status )
  21916. IF_NOT_OK_RETURN(status=1)
  21917. ! data space:
  21918. call H5SCreate_f( H5S_SIMPLE_F, hdf5_space_id, status )
  21919. IF_NOT_OK_RETURN(status=1)
  21920. ! set extent of the data space:
  21921. call H5SSet_Extent_Simple_f( hdf5_space_id, 1, int(shape(values),kind=HSIZE_T), int(shape(values),kind=HSIZE_T), status )
  21922. IF_NOT_OK_RETURN(status=1)
  21923. ! create attribute; type in file is same as type provided to this routine:
  21924. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  21925. IF_NOT_OK_RETURN(status=1)
  21926. ! write attribute values:
  21927. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int(shape(values),kind=HSIZE_T), status )
  21928. IF_NOT_OK_RETURN(status=1)
  21929. ! release attribute:
  21930. call H5AClose_f( hdf5_attr_id, status )
  21931. IF_NOT_OK_RETURN(status=1)
  21932. ! release data space:
  21933. call H5SClose_f( hdf5_space_id, status )
  21934. IF_NOT_OK_RETURN(status=1)
  21935. ! release data type:
  21936. call H5TClose_f( hdf5_type_id, status )
  21937. IF_NOT_OK_RETURN(status=1)
  21938. #endif
  21939. #ifdef with_netcdf
  21940. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21941. case ( MDF_NETCDF, MDF_NETCDF4 )
  21942. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21943. ! set variable id:
  21944. if ( varid == MDF_GLOBAL ) then
  21945. netcdf_varid = NF90_GLOBAL
  21946. else
  21947. netcdf_varid = varp%netcdf_varid
  21948. end if
  21949. ! write attribute:
  21950. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  21951. IF_NF90_NOT_OK_RETURN(status=1)
  21952. #endif
  21953. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21954. case default
  21955. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  21956. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  21957. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  21958. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  21959. TRACEBACK; status=1; return
  21960. end select
  21961. end do ! file types
  21962. ! ok
  21963. status = 0
  21964. end subroutine MDF_Put_Att_i1_1d
  21965. ! ***
  21966. subroutine MDF_Get_Att_i1_1d( hid, varid, name, values, status )
  21967. #ifdef with_hdf5_beta
  21968. use HDF5, only : HSIZE_T
  21969. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  21970. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  21971. use HDF5, only : H5T_NATIVE_CHARACTER
  21972. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  21973. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  21974. #endif
  21975. #ifdef with_netcdf
  21976. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  21977. #endif
  21978. ! --- in/out -------------------------------------
  21979. integer, intent(in) :: hid
  21980. integer, intent(in) :: varid
  21981. character(len=*), intent(in) :: name
  21982. integer(1), intent(out) :: values(:)
  21983. integer, intent(out) :: status
  21984. ! --- const --------------------------------------
  21985. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i1_1d'
  21986. ! --- external -------------------------------
  21987. #ifdef with_hdf4
  21988. integer(hdf4_wpi), external :: sfFAttr
  21989. integer(hdf4_wpi), external :: sfGAInfo
  21990. integer(hdf4_wpi), external :: sfRCAtt
  21991. integer(hdf4_wpi), external :: sfRNAtt
  21992. #endif
  21993. ! --- local --------------------------------------
  21994. type(MDF_File), pointer :: filep
  21995. type(MDF_Var), pointer :: varp
  21996. integer :: ftype
  21997. #ifdef with_hdf4
  21998. integer :: hdf4_id
  21999. integer :: hdf4_iatt
  22000. character(len=LEN_NAME) :: hdf4_name
  22001. integer :: hdf4_xtype
  22002. integer :: hdf4_length
  22003. integer(1), allocatable :: values_int1(:)
  22004. integer(2), allocatable :: values_int2(:)
  22005. integer(4), allocatable :: values_int4(:)
  22006. integer(8), allocatable :: values_int8(:)
  22007. real(4), allocatable :: values_real4(:)
  22008. real(8), allocatable :: values_real8(:)
  22009. #endif
  22010. #ifdef with_hdf5_beta
  22011. integer(HID_T) :: hdf5_loc_id
  22012. character(len=LEN_NAME) :: hdf5_obj_name
  22013. integer(HID_T) :: hdf5_attr_id
  22014. integer(HID_T) :: hdf5_type_id
  22015. integer(4), allocatable :: hdf5_values_int4(:)
  22016. #endif
  22017. #ifdef with_netcdf
  22018. integer :: netcdf_varid
  22019. #endif
  22020. ! --- begin --------------------------------------
  22021. ! single type:
  22022. call MDF_Get_Type( hid, ftype, status )
  22023. IF_NOT_OK_RETURN(status=1)
  22024. ! pointer to file structure:
  22025. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22026. IF_NOT_OK_RETURN(status=1)
  22027. ! pointer to variable structure if possible:
  22028. if ( varid /= MDF_GLOBAL ) then
  22029. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22030. IF_NOT_OK_RETURN(status=1)
  22031. end if
  22032. ! select appropriate routine for each type:
  22033. select case ( ftype )
  22034. #ifdef with_hdf4
  22035. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22036. case ( MDF_HDF4 )
  22037. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22038. ! set variable id:
  22039. if ( varid == MDF_GLOBAL ) then
  22040. hdf4_id = filep%hdf4_id
  22041. else
  22042. hdf4_id = varp%hdf4_sdid
  22043. end if
  22044. ! get attribute index given name:
  22045. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  22046. if ( hdf4_iatt == FAIL ) then
  22047. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  22048. TRACEBACK; status=1; return
  22049. end if
  22050. ! get type and length:
  22051. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  22052. if ( status /= SUCCEED ) then
  22053. write (gol,'("getting attribute info")') trim(name); call goErr
  22054. TRACEBACK; status=1; return
  22055. end if
  22056. ! read numerical attribute:
  22057. select case ( hdf4_xtype )
  22058. case ( DFNT_INT8 )
  22059. allocate( values_int1(hdf4_length) )
  22060. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  22061. values = int(values_int1,kind=1)
  22062. deallocate( values_int1 )
  22063. case ( DFNT_INT16 )
  22064. allocate( values_int2(hdf4_length) )
  22065. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  22066. values = int(values_int2,kind=1)
  22067. deallocate( values_int2 )
  22068. case ( DFNT_INT32 )
  22069. allocate( values_int4(hdf4_length) )
  22070. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  22071. values = int(values_int4,kind=1)
  22072. deallocate( values_int4 )
  22073. case ( DFNT_INT64 )
  22074. allocate( values_int8(hdf4_length) )
  22075. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  22076. values = int(values_int8,kind=1)
  22077. deallocate( values_int8 )
  22078. case ( DFNT_FLOAT32 )
  22079. allocate( values_real4(hdf4_length) )
  22080. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  22081. values = int(values_real4,kind=1)
  22082. deallocate( values_real4 )
  22083. case ( DFNT_FLOAT64 )
  22084. allocate( values_real8(hdf4_length) )
  22085. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  22086. values = int(values_real8,kind=1)
  22087. deallocate( values_real8 )
  22088. case default
  22089. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  22090. TRACEBACK; status=1; return
  22091. end select
  22092. if ( status /= SUCCEED ) then
  22093. write (*,'("reading attribute : ",a)') trim(name); call goErr
  22094. TRACEBACK; status=1; return
  22095. end if
  22096. #endif
  22097. #ifdef with_hdf5_beta
  22098. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22099. case ( MDF_HDF5 )
  22100. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22101. ! set variable id:
  22102. if ( varid == MDF_GLOBAL ) then
  22103. ! file id:
  22104. hdf5_loc_id = filep%hdf5_file_id
  22105. hdf5_obj_name = '.'
  22106. else
  22107. ! file id:
  22108. hdf5_loc_id = varp%hdf5_dataset_id
  22109. hdf5_obj_name = '.'
  22110. end if
  22111. ! data type:
  22112. call H5TCopy_f( H5T_STD_I8LE, hdf5_type_id, status )
  22113. IF_NOT_OK_RETURN(status=1)
  22114. ! open attribute:
  22115. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  22116. IF_NOT_OK_RETURN(status=1)
  22117. ! storage:
  22118. allocate( hdf5_values_int4(size(values)) )
  22119. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  22120. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int(shape(values),HSIZE_T), status )
  22121. IF_NOT_OK_RETURN(status=1)
  22122. ! convert:
  22123. values = int(hdf5_values_int4,1)
  22124. ! clear:
  22125. deallocate( hdf5_values_int4 )
  22126. ! release:
  22127. call H5TClose_f( hdf5_type_id, status )
  22128. IF_NOT_OK_RETURN(status=1)
  22129. ! release:
  22130. call H5AClose_f( hdf5_attr_id, status )
  22131. IF_NOT_OK_RETURN(status=1)
  22132. #endif
  22133. #ifdef with_netcdf
  22134. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22135. case ( MDF_NETCDF, MDF_NETCDF4 )
  22136. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22137. ! set variable id:
  22138. if ( varid == MDF_GLOBAL ) then
  22139. netcdf_varid = NF90_GLOBAL
  22140. else
  22141. netcdf_varid = varp%netcdf_varid
  22142. end if
  22143. ! read attribute:
  22144. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22145. IF_NF90_NOT_OK_RETURN(status=1)
  22146. #endif
  22147. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22148. case default
  22149. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22150. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22151. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22152. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22153. TRACEBACK; status=1; return
  22154. end select
  22155. ! ok
  22156. status = 0
  22157. end subroutine MDF_Get_Att_i1_1d
  22158. subroutine MDF_Put_Att_i2_0d( hid, varid, name, values, status )
  22159. #ifdef with_hdf5_beta
  22160. use HDF5, only : HID_T, HSIZE_T
  22161. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22162. use HDF5, only : H5T_NATIVE_CHARACTER
  22163. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  22164. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22165. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  22166. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  22167. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  22168. #endif
  22169. #ifdef with_netcdf
  22170. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  22171. #endif
  22172. ! --- in/out -------------------------------------
  22173. integer, intent(in) :: hid
  22174. integer, intent(in) :: varid
  22175. character(len=*), intent(in) :: name
  22176. integer(2), intent(in) :: values
  22177. integer, intent(out) :: status
  22178. ! --- const --------------------------------------
  22179. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i2_0d'
  22180. ! --- external -------------------------------
  22181. #ifdef with_hdf4
  22182. integer(hdf4_wpi), external :: sfSCAtt
  22183. integer(hdf4_wpi), external :: sfSNAtt
  22184. #endif
  22185. ! --- local --------------------------------------
  22186. type(MDF_File), pointer :: filep
  22187. type(MDF_Var), pointer :: varp
  22188. integer :: iftype
  22189. integer :: ftype
  22190. #ifdef with_hdf4
  22191. integer :: hdf4_id
  22192. #endif
  22193. #ifdef with_hdf5_beta
  22194. integer(HID_T) :: hdf5_loc_id
  22195. integer(HID_T) :: hdf5_attr_id
  22196. integer(HID_T) :: hdf5_space_id
  22197. integer(HID_T) :: hdf5_type_id
  22198. #endif
  22199. #ifdef with_netcdf
  22200. integer :: netcdf_varid
  22201. #endif
  22202. ! --- begin --------------------------------------
  22203. ! pointer to file structure:
  22204. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22205. IF_NOT_OK_RETURN(status=1)
  22206. ! global or variable attribute ?
  22207. if ( varid == MDF_GLOBAL ) then
  22208. ! increase counter:
  22209. filep%natt = filep%natt + 1
  22210. else
  22211. ! pointer to variable structure:
  22212. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22213. IF_NOT_OK_RETURN(status=1)
  22214. ! increase counter:
  22215. varp%natt = varp%natt + 1
  22216. end if
  22217. ! loop over file types:
  22218. do iftype = 1, filep%nftype
  22219. ! current type:
  22220. ftype = filep%ftypes(iftype)
  22221. ! select appropriate routine for each type:
  22222. select case ( ftype )
  22223. #ifdef with_hdf4
  22224. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22225. case ( MDF_HDF4 )
  22226. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22227. ! set variable id:
  22228. if ( varid == MDF_GLOBAL ) then
  22229. hdf4_id = filep%hdf4_id
  22230. else
  22231. hdf4_id = varp%hdf4_sdid
  22232. end if
  22233. ! store numerical attribute:
  22234. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT16, 1, values )
  22235. if ( status /= SUCCEED ) then
  22236. write (*,'("writing attribute : ",a)') trim(name); call goErr
  22237. TRACEBACK; status=1; return
  22238. end if
  22239. #endif
  22240. #ifdef with_hdf5_beta
  22241. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22242. case ( MDF_HDF5 )
  22243. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22244. ! set variable id:
  22245. if ( varid == MDF_GLOBAL ) then
  22246. hdf5_loc_id = filep%hdf5_file_id
  22247. else
  22248. hdf5_loc_id = varp%hdf5_dataset_id
  22249. end if
  22250. ! data type:
  22251. call H5TCopy_f( H5T_STD_I16LE, hdf5_type_id, status )
  22252. IF_NOT_OK_RETURN(status=1)
  22253. ! data space:
  22254. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  22255. IF_NOT_OK_RETURN(status=1)
  22256. ! create attribute; type in file is same as type provided to this routine:
  22257. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  22258. IF_NOT_OK_RETURN(status=1)
  22259. ! write attribute values:
  22260. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int((/1/),kind=HSIZE_T), status )
  22261. IF_NOT_OK_RETURN(status=1)
  22262. ! release attribute:
  22263. call H5AClose_f( hdf5_attr_id, status )
  22264. IF_NOT_OK_RETURN(status=1)
  22265. ! release data space:
  22266. call H5SClose_f( hdf5_space_id, status )
  22267. IF_NOT_OK_RETURN(status=1)
  22268. ! release data type:
  22269. call H5TClose_f( hdf5_type_id, status )
  22270. IF_NOT_OK_RETURN(status=1)
  22271. #endif
  22272. #ifdef with_netcdf
  22273. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22274. case ( MDF_NETCDF, MDF_NETCDF4 )
  22275. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22276. ! set variable id:
  22277. if ( varid == MDF_GLOBAL ) then
  22278. netcdf_varid = NF90_GLOBAL
  22279. else
  22280. netcdf_varid = varp%netcdf_varid
  22281. end if
  22282. ! write attribute:
  22283. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22284. IF_NF90_NOT_OK_RETURN(status=1)
  22285. #endif
  22286. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22287. case default
  22288. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22289. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22290. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22291. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22292. TRACEBACK; status=1; return
  22293. end select
  22294. end do ! file types
  22295. ! ok
  22296. status = 0
  22297. end subroutine MDF_Put_Att_i2_0d
  22298. ! ***
  22299. subroutine MDF_Get_Att_i2_0d( hid, varid, name, values, status )
  22300. #ifdef with_hdf5_beta
  22301. use HDF5, only : HSIZE_T
  22302. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  22303. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22304. use HDF5, only : H5T_NATIVE_CHARACTER
  22305. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  22306. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22307. #endif
  22308. #ifdef with_netcdf
  22309. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  22310. #endif
  22311. ! --- in/out -------------------------------------
  22312. integer, intent(in) :: hid
  22313. integer, intent(in) :: varid
  22314. character(len=*), intent(in) :: name
  22315. integer(2), intent(out) :: values
  22316. integer, intent(out) :: status
  22317. ! --- const --------------------------------------
  22318. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i2_0d'
  22319. ! --- external -------------------------------
  22320. #ifdef with_hdf4
  22321. integer(hdf4_wpi), external :: sfFAttr
  22322. integer(hdf4_wpi), external :: sfGAInfo
  22323. integer(hdf4_wpi), external :: sfRCAtt
  22324. integer(hdf4_wpi), external :: sfRNAtt
  22325. #endif
  22326. ! --- local --------------------------------------
  22327. type(MDF_File), pointer :: filep
  22328. type(MDF_Var), pointer :: varp
  22329. integer :: ftype
  22330. #ifdef with_hdf4
  22331. integer :: hdf4_id
  22332. integer :: hdf4_iatt
  22333. character(len=LEN_NAME) :: hdf4_name
  22334. integer :: hdf4_xtype
  22335. integer :: hdf4_length
  22336. integer(1) :: values_int1
  22337. integer(2) :: values_int2
  22338. integer(4) :: values_int4
  22339. integer(8) :: values_int8
  22340. real(4) :: values_real4
  22341. real(8) :: values_real8
  22342. #endif
  22343. #ifdef with_hdf5_beta
  22344. integer(HID_T) :: hdf5_loc_id
  22345. character(len=LEN_NAME) :: hdf5_obj_name
  22346. integer(HID_T) :: hdf5_attr_id
  22347. integer(HID_T) :: hdf5_type_id
  22348. integer(4) :: hdf5_values_int4
  22349. #endif
  22350. #ifdef with_netcdf
  22351. integer :: netcdf_varid
  22352. #endif
  22353. ! --- begin --------------------------------------
  22354. ! single type:
  22355. call MDF_Get_Type( hid, ftype, status )
  22356. IF_NOT_OK_RETURN(status=1)
  22357. ! pointer to file structure:
  22358. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22359. IF_NOT_OK_RETURN(status=1)
  22360. ! pointer to variable structure if possible:
  22361. if ( varid /= MDF_GLOBAL ) then
  22362. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22363. IF_NOT_OK_RETURN(status=1)
  22364. end if
  22365. ! select appropriate routine for each type:
  22366. select case ( ftype )
  22367. #ifdef with_hdf4
  22368. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22369. case ( MDF_HDF4 )
  22370. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22371. ! set variable id:
  22372. if ( varid == MDF_GLOBAL ) then
  22373. hdf4_id = filep%hdf4_id
  22374. else
  22375. hdf4_id = varp%hdf4_sdid
  22376. end if
  22377. ! get attribute index given name:
  22378. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  22379. if ( hdf4_iatt == FAIL ) then
  22380. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  22381. TRACEBACK; status=1; return
  22382. end if
  22383. ! get type and length:
  22384. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  22385. if ( status /= SUCCEED ) then
  22386. write (gol,'("getting attribute info")') trim(name); call goErr
  22387. TRACEBACK; status=1; return
  22388. end if
  22389. ! read numerical attribute:
  22390. select case ( hdf4_xtype )
  22391. case ( DFNT_INT8 )
  22392. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  22393. values = int(values_int1,kind=2)
  22394. case ( DFNT_INT16 )
  22395. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  22396. values = int(values_int2,kind=2)
  22397. case ( DFNT_INT32 )
  22398. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  22399. values = int(values_int4,kind=2)
  22400. case ( DFNT_INT64 )
  22401. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  22402. values = int(values_int8,kind=2)
  22403. case ( DFNT_FLOAT32 )
  22404. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  22405. values = int(values_real4,kind=2)
  22406. case ( DFNT_FLOAT64 )
  22407. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  22408. values = int(values_real8,kind=2)
  22409. case default
  22410. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  22411. TRACEBACK; status=1; return
  22412. end select
  22413. if ( status /= SUCCEED ) then
  22414. write (*,'("reading attribute : ",a)') trim(name); call goErr
  22415. TRACEBACK; status=1; return
  22416. end if
  22417. #endif
  22418. #ifdef with_hdf5_beta
  22419. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22420. case ( MDF_HDF5 )
  22421. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22422. ! set variable id:
  22423. if ( varid == MDF_GLOBAL ) then
  22424. ! file id:
  22425. hdf5_loc_id = filep%hdf5_file_id
  22426. hdf5_obj_name = '.'
  22427. else
  22428. ! file id:
  22429. hdf5_loc_id = varp%hdf5_dataset_id
  22430. hdf5_obj_name = '.'
  22431. end if
  22432. ! data type:
  22433. call H5TCopy_f( H5T_STD_I16LE, hdf5_type_id, status )
  22434. IF_NOT_OK_RETURN(status=1)
  22435. ! open attribute:
  22436. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  22437. IF_NOT_OK_RETURN(status=1)
  22438. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  22439. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int((/1/),HSIZE_T), status )
  22440. IF_NOT_OK_RETURN(status=1)
  22441. ! convert:
  22442. values = int(hdf5_values_int4,2)
  22443. ! release:
  22444. call H5TClose_f( hdf5_type_id, status )
  22445. IF_NOT_OK_RETURN(status=1)
  22446. ! release:
  22447. call H5AClose_f( hdf5_attr_id, status )
  22448. IF_NOT_OK_RETURN(status=1)
  22449. #endif
  22450. #ifdef with_netcdf
  22451. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22452. case ( MDF_NETCDF, MDF_NETCDF4 )
  22453. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22454. ! set variable id:
  22455. if ( varid == MDF_GLOBAL ) then
  22456. netcdf_varid = NF90_GLOBAL
  22457. else
  22458. netcdf_varid = varp%netcdf_varid
  22459. end if
  22460. ! read attribute:
  22461. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22462. IF_NF90_NOT_OK_RETURN(status=1)
  22463. #endif
  22464. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22465. case default
  22466. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22467. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22468. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22469. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22470. TRACEBACK; status=1; return
  22471. end select
  22472. ! ok
  22473. status = 0
  22474. end subroutine MDF_Get_Att_i2_0d
  22475. subroutine MDF_Put_Att_i2_1d( hid, varid, name, values, status )
  22476. #ifdef with_hdf5_beta
  22477. use HDF5, only : HID_T, HSIZE_T
  22478. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22479. use HDF5, only : H5T_NATIVE_CHARACTER
  22480. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  22481. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22482. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  22483. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  22484. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  22485. #endif
  22486. #ifdef with_netcdf
  22487. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  22488. #endif
  22489. ! --- in/out -------------------------------------
  22490. integer, intent(in) :: hid
  22491. integer, intent(in) :: varid
  22492. character(len=*), intent(in) :: name
  22493. integer(2), intent(in) :: values(:)
  22494. integer, intent(out) :: status
  22495. ! --- const --------------------------------------
  22496. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i2_1d'
  22497. ! --- external -------------------------------
  22498. #ifdef with_hdf4
  22499. integer(hdf4_wpi), external :: sfSCAtt
  22500. integer(hdf4_wpi), external :: sfSNAtt
  22501. #endif
  22502. ! --- local --------------------------------------
  22503. type(MDF_File), pointer :: filep
  22504. type(MDF_Var), pointer :: varp
  22505. integer :: iftype
  22506. integer :: ftype
  22507. #ifdef with_hdf4
  22508. integer :: hdf4_id
  22509. #endif
  22510. #ifdef with_hdf5_beta
  22511. integer(HID_T) :: hdf5_loc_id
  22512. integer(HID_T) :: hdf5_attr_id
  22513. integer(HID_T) :: hdf5_space_id
  22514. integer(HID_T) :: hdf5_type_id
  22515. #endif
  22516. #ifdef with_netcdf
  22517. integer :: netcdf_varid
  22518. #endif
  22519. ! --- begin --------------------------------------
  22520. ! pointer to file structure:
  22521. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22522. IF_NOT_OK_RETURN(status=1)
  22523. ! global or variable attribute ?
  22524. if ( varid == MDF_GLOBAL ) then
  22525. ! increase counter:
  22526. filep%natt = filep%natt + 1
  22527. else
  22528. ! pointer to variable structure:
  22529. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22530. IF_NOT_OK_RETURN(status=1)
  22531. ! increase counter:
  22532. varp%natt = varp%natt + 1
  22533. end if
  22534. ! loop over file types:
  22535. do iftype = 1, filep%nftype
  22536. ! current type:
  22537. ftype = filep%ftypes(iftype)
  22538. ! select appropriate routine for each type:
  22539. select case ( ftype )
  22540. #ifdef with_hdf4
  22541. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22542. case ( MDF_HDF4 )
  22543. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22544. ! set variable id:
  22545. if ( varid == MDF_GLOBAL ) then
  22546. hdf4_id = filep%hdf4_id
  22547. else
  22548. hdf4_id = varp%hdf4_sdid
  22549. end if
  22550. ! strore numerical attribute:
  22551. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT16, size(values), values )
  22552. if ( status /= SUCCEED ) then
  22553. write (*,'("writing attribute : ",a)') trim(name); call goErr
  22554. TRACEBACK; status=1; return
  22555. end if
  22556. #endif
  22557. #ifdef with_hdf5_beta
  22558. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22559. case ( MDF_HDF5 )
  22560. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22561. ! set variable id:
  22562. if ( varid == MDF_GLOBAL ) then
  22563. hdf5_loc_id = filep%hdf5_file_id
  22564. else
  22565. hdf5_loc_id = varp%hdf5_dataset_id
  22566. end if
  22567. ! data type:
  22568. call H5TCopy_f( H5T_STD_I16LE, hdf5_type_id, status )
  22569. IF_NOT_OK_RETURN(status=1)
  22570. ! data space:
  22571. call H5SCreate_f( H5S_SIMPLE_F, hdf5_space_id, status )
  22572. IF_NOT_OK_RETURN(status=1)
  22573. ! set extent of the data space:
  22574. call H5SSet_Extent_Simple_f( hdf5_space_id, 1, int(shape(values),kind=HSIZE_T), int(shape(values),kind=HSIZE_T), status )
  22575. IF_NOT_OK_RETURN(status=1)
  22576. ! create attribute; type in file is same as type provided to this routine:
  22577. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  22578. IF_NOT_OK_RETURN(status=1)
  22579. ! write attribute values:
  22580. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int(shape(values),kind=HSIZE_T), status )
  22581. IF_NOT_OK_RETURN(status=1)
  22582. ! release attribute:
  22583. call H5AClose_f( hdf5_attr_id, status )
  22584. IF_NOT_OK_RETURN(status=1)
  22585. ! release data space:
  22586. call H5SClose_f( hdf5_space_id, status )
  22587. IF_NOT_OK_RETURN(status=1)
  22588. ! release data type:
  22589. call H5TClose_f( hdf5_type_id, status )
  22590. IF_NOT_OK_RETURN(status=1)
  22591. #endif
  22592. #ifdef with_netcdf
  22593. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22594. case ( MDF_NETCDF, MDF_NETCDF4 )
  22595. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22596. ! set variable id:
  22597. if ( varid == MDF_GLOBAL ) then
  22598. netcdf_varid = NF90_GLOBAL
  22599. else
  22600. netcdf_varid = varp%netcdf_varid
  22601. end if
  22602. ! write attribute:
  22603. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22604. IF_NF90_NOT_OK_RETURN(status=1)
  22605. #endif
  22606. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22607. case default
  22608. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22609. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22610. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22611. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22612. TRACEBACK; status=1; return
  22613. end select
  22614. end do ! file types
  22615. ! ok
  22616. status = 0
  22617. end subroutine MDF_Put_Att_i2_1d
  22618. ! ***
  22619. subroutine MDF_Get_Att_i2_1d( hid, varid, name, values, status )
  22620. #ifdef with_hdf5_beta
  22621. use HDF5, only : HSIZE_T
  22622. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  22623. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22624. use HDF5, only : H5T_NATIVE_CHARACTER
  22625. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  22626. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22627. #endif
  22628. #ifdef with_netcdf
  22629. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  22630. #endif
  22631. ! --- in/out -------------------------------------
  22632. integer, intent(in) :: hid
  22633. integer, intent(in) :: varid
  22634. character(len=*), intent(in) :: name
  22635. integer(2), intent(out) :: values(:)
  22636. integer, intent(out) :: status
  22637. ! --- const --------------------------------------
  22638. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i2_1d'
  22639. ! --- external -------------------------------
  22640. #ifdef with_hdf4
  22641. integer(hdf4_wpi), external :: sfFAttr
  22642. integer(hdf4_wpi), external :: sfGAInfo
  22643. integer(hdf4_wpi), external :: sfRCAtt
  22644. integer(hdf4_wpi), external :: sfRNAtt
  22645. #endif
  22646. ! --- local --------------------------------------
  22647. type(MDF_File), pointer :: filep
  22648. type(MDF_Var), pointer :: varp
  22649. integer :: ftype
  22650. #ifdef with_hdf4
  22651. integer :: hdf4_id
  22652. integer :: hdf4_iatt
  22653. character(len=LEN_NAME) :: hdf4_name
  22654. integer :: hdf4_xtype
  22655. integer :: hdf4_length
  22656. integer(1), allocatable :: values_int1(:)
  22657. integer(2), allocatable :: values_int2(:)
  22658. integer(4), allocatable :: values_int4(:)
  22659. integer(8), allocatable :: values_int8(:)
  22660. real(4), allocatable :: values_real4(:)
  22661. real(8), allocatable :: values_real8(:)
  22662. #endif
  22663. #ifdef with_hdf5_beta
  22664. integer(HID_T) :: hdf5_loc_id
  22665. character(len=LEN_NAME) :: hdf5_obj_name
  22666. integer(HID_T) :: hdf5_attr_id
  22667. integer(HID_T) :: hdf5_type_id
  22668. integer(4), allocatable :: hdf5_values_int4(:)
  22669. #endif
  22670. #ifdef with_netcdf
  22671. integer :: netcdf_varid
  22672. #endif
  22673. ! --- begin --------------------------------------
  22674. ! single type:
  22675. call MDF_Get_Type( hid, ftype, status )
  22676. IF_NOT_OK_RETURN(status=1)
  22677. ! pointer to file structure:
  22678. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22679. IF_NOT_OK_RETURN(status=1)
  22680. ! pointer to variable structure if possible:
  22681. if ( varid /= MDF_GLOBAL ) then
  22682. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22683. IF_NOT_OK_RETURN(status=1)
  22684. end if
  22685. ! select appropriate routine for each type:
  22686. select case ( ftype )
  22687. #ifdef with_hdf4
  22688. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22689. case ( MDF_HDF4 )
  22690. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22691. ! set variable id:
  22692. if ( varid == MDF_GLOBAL ) then
  22693. hdf4_id = filep%hdf4_id
  22694. else
  22695. hdf4_id = varp%hdf4_sdid
  22696. end if
  22697. ! get attribute index given name:
  22698. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  22699. if ( hdf4_iatt == FAIL ) then
  22700. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  22701. TRACEBACK; status=1; return
  22702. end if
  22703. ! get type and length:
  22704. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  22705. if ( status /= SUCCEED ) then
  22706. write (gol,'("getting attribute info")') trim(name); call goErr
  22707. TRACEBACK; status=1; return
  22708. end if
  22709. ! read numerical attribute:
  22710. select case ( hdf4_xtype )
  22711. case ( DFNT_INT8 )
  22712. allocate( values_int1(hdf4_length) )
  22713. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  22714. values = int(values_int1,kind=2)
  22715. deallocate( values_int1 )
  22716. case ( DFNT_INT16 )
  22717. allocate( values_int2(hdf4_length) )
  22718. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  22719. values = int(values_int2,kind=2)
  22720. deallocate( values_int2 )
  22721. case ( DFNT_INT32 )
  22722. allocate( values_int4(hdf4_length) )
  22723. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  22724. values = int(values_int4,kind=2)
  22725. deallocate( values_int4 )
  22726. case ( DFNT_INT64 )
  22727. allocate( values_int8(hdf4_length) )
  22728. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  22729. values = int(values_int8,kind=2)
  22730. deallocate( values_int8 )
  22731. case ( DFNT_FLOAT32 )
  22732. allocate( values_real4(hdf4_length) )
  22733. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  22734. values = int(values_real4,kind=2)
  22735. deallocate( values_real4 )
  22736. case ( DFNT_FLOAT64 )
  22737. allocate( values_real8(hdf4_length) )
  22738. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  22739. values = int(values_real8,kind=2)
  22740. deallocate( values_real8 )
  22741. case default
  22742. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  22743. TRACEBACK; status=1; return
  22744. end select
  22745. if ( status /= SUCCEED ) then
  22746. write (*,'("reading attribute : ",a)') trim(name); call goErr
  22747. TRACEBACK; status=1; return
  22748. end if
  22749. #endif
  22750. #ifdef with_hdf5_beta
  22751. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22752. case ( MDF_HDF5 )
  22753. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22754. ! set variable id:
  22755. if ( varid == MDF_GLOBAL ) then
  22756. ! file id:
  22757. hdf5_loc_id = filep%hdf5_file_id
  22758. hdf5_obj_name = '.'
  22759. else
  22760. ! file id:
  22761. hdf5_loc_id = varp%hdf5_dataset_id
  22762. hdf5_obj_name = '.'
  22763. end if
  22764. ! data type:
  22765. call H5TCopy_f( H5T_STD_I16LE, hdf5_type_id, status )
  22766. IF_NOT_OK_RETURN(status=1)
  22767. ! open attribute:
  22768. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  22769. IF_NOT_OK_RETURN(status=1)
  22770. ! storage:
  22771. allocate( hdf5_values_int4(size(values)) )
  22772. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  22773. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int(shape(values),HSIZE_T), status )
  22774. IF_NOT_OK_RETURN(status=1)
  22775. ! convert:
  22776. values = int(hdf5_values_int4,2)
  22777. ! clear:
  22778. deallocate( hdf5_values_int4 )
  22779. ! release:
  22780. call H5TClose_f( hdf5_type_id, status )
  22781. IF_NOT_OK_RETURN(status=1)
  22782. ! release:
  22783. call H5AClose_f( hdf5_attr_id, status )
  22784. IF_NOT_OK_RETURN(status=1)
  22785. #endif
  22786. #ifdef with_netcdf
  22787. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22788. case ( MDF_NETCDF, MDF_NETCDF4 )
  22789. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22790. ! set variable id:
  22791. if ( varid == MDF_GLOBAL ) then
  22792. netcdf_varid = NF90_GLOBAL
  22793. else
  22794. netcdf_varid = varp%netcdf_varid
  22795. end if
  22796. ! read attribute:
  22797. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22798. IF_NF90_NOT_OK_RETURN(status=1)
  22799. #endif
  22800. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22801. case default
  22802. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22803. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22804. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22805. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22806. TRACEBACK; status=1; return
  22807. end select
  22808. ! ok
  22809. status = 0
  22810. end subroutine MDF_Get_Att_i2_1d
  22811. subroutine MDF_Put_Att_i4_0d( hid, varid, name, values, status )
  22812. #ifdef with_hdf5_beta
  22813. use HDF5, only : HID_T, HSIZE_T
  22814. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22815. use HDF5, only : H5T_NATIVE_CHARACTER
  22816. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  22817. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22818. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  22819. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  22820. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  22821. #endif
  22822. #ifdef with_netcdf
  22823. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  22824. #endif
  22825. ! --- in/out -------------------------------------
  22826. integer, intent(in) :: hid
  22827. integer, intent(in) :: varid
  22828. character(len=*), intent(in) :: name
  22829. integer(4), intent(in) :: values
  22830. integer, intent(out) :: status
  22831. ! --- const --------------------------------------
  22832. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i4_0d'
  22833. ! --- external -------------------------------
  22834. #ifdef with_hdf4
  22835. integer(hdf4_wpi), external :: sfSCAtt
  22836. integer(hdf4_wpi), external :: sfSNAtt
  22837. #endif
  22838. ! --- local --------------------------------------
  22839. type(MDF_File), pointer :: filep
  22840. type(MDF_Var), pointer :: varp
  22841. integer :: iftype
  22842. integer :: ftype
  22843. #ifdef with_hdf4
  22844. integer :: hdf4_id
  22845. #endif
  22846. #ifdef with_hdf5_beta
  22847. integer(HID_T) :: hdf5_loc_id
  22848. integer(HID_T) :: hdf5_attr_id
  22849. integer(HID_T) :: hdf5_space_id
  22850. integer(HID_T) :: hdf5_type_id
  22851. #endif
  22852. #ifdef with_netcdf
  22853. integer :: netcdf_varid
  22854. #endif
  22855. ! --- begin --------------------------------------
  22856. ! pointer to file structure:
  22857. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  22858. IF_NOT_OK_RETURN(status=1)
  22859. ! global or variable attribute ?
  22860. if ( varid == MDF_GLOBAL ) then
  22861. ! increase counter:
  22862. filep%natt = filep%natt + 1
  22863. else
  22864. ! pointer to variable structure:
  22865. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  22866. IF_NOT_OK_RETURN(status=1)
  22867. ! increase counter:
  22868. varp%natt = varp%natt + 1
  22869. end if
  22870. ! loop over file types:
  22871. do iftype = 1, filep%nftype
  22872. ! current type:
  22873. ftype = filep%ftypes(iftype)
  22874. ! select appropriate routine for each type:
  22875. select case ( ftype )
  22876. #ifdef with_hdf4
  22877. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22878. case ( MDF_HDF4 )
  22879. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22880. ! set variable id:
  22881. if ( varid == MDF_GLOBAL ) then
  22882. hdf4_id = filep%hdf4_id
  22883. else
  22884. hdf4_id = varp%hdf4_sdid
  22885. end if
  22886. ! store numerical attribute:
  22887. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT32, 1, values )
  22888. if ( status /= SUCCEED ) then
  22889. write (*,'("writing attribute : ",a)') trim(name); call goErr
  22890. TRACEBACK; status=1; return
  22891. end if
  22892. #endif
  22893. #ifdef with_hdf5_beta
  22894. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22895. case ( MDF_HDF5 )
  22896. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22897. ! set variable id:
  22898. if ( varid == MDF_GLOBAL ) then
  22899. hdf5_loc_id = filep%hdf5_file_id
  22900. else
  22901. hdf5_loc_id = varp%hdf5_dataset_id
  22902. end if
  22903. ! data type:
  22904. call H5TCopy_f( H5T_NATIVE_INTEGER, hdf5_type_id, status )
  22905. IF_NOT_OK_RETURN(status=1)
  22906. ! data space:
  22907. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  22908. IF_NOT_OK_RETURN(status=1)
  22909. ! create attribute; type in file is same as type provided to this routine:
  22910. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  22911. IF_NOT_OK_RETURN(status=1)
  22912. ! write attribute values:
  22913. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int((/1/),kind=HSIZE_T), status )
  22914. IF_NOT_OK_RETURN(status=1)
  22915. ! release attribute:
  22916. call H5AClose_f( hdf5_attr_id, status )
  22917. IF_NOT_OK_RETURN(status=1)
  22918. ! release data space:
  22919. call H5SClose_f( hdf5_space_id, status )
  22920. IF_NOT_OK_RETURN(status=1)
  22921. ! release data type:
  22922. call H5TClose_f( hdf5_type_id, status )
  22923. IF_NOT_OK_RETURN(status=1)
  22924. #endif
  22925. #ifdef with_netcdf
  22926. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22927. case ( MDF_NETCDF, MDF_NETCDF4 )
  22928. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22929. ! set variable id:
  22930. if ( varid == MDF_GLOBAL ) then
  22931. netcdf_varid = NF90_GLOBAL
  22932. else
  22933. netcdf_varid = varp%netcdf_varid
  22934. end if
  22935. ! write attribute:
  22936. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  22937. IF_NF90_NOT_OK_RETURN(status=1)
  22938. #endif
  22939. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22940. case default
  22941. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22942. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  22943. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  22944. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  22945. TRACEBACK; status=1; return
  22946. end select
  22947. end do ! file types
  22948. ! ok
  22949. status = 0
  22950. end subroutine MDF_Put_Att_i4_0d
  22951. ! ***
  22952. subroutine MDF_Get_Att_i4_0d( hid, varid, name, values, status )
  22953. #ifdef with_hdf5_beta
  22954. use HDF5, only : HSIZE_T
  22955. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  22956. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  22957. use HDF5, only : H5T_NATIVE_CHARACTER
  22958. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  22959. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  22960. #endif
  22961. #ifdef with_netcdf
  22962. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  22963. #endif
  22964. ! --- in/out -------------------------------------
  22965. integer, intent(in) :: hid
  22966. integer, intent(in) :: varid
  22967. character(len=*), intent(in) :: name
  22968. integer(4), intent(out) :: values
  22969. integer, intent(out) :: status
  22970. ! --- const --------------------------------------
  22971. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i4_0d'
  22972. ! --- external -------------------------------
  22973. #ifdef with_hdf4
  22974. integer(hdf4_wpi), external :: sfFAttr
  22975. integer(hdf4_wpi), external :: sfGAInfo
  22976. integer(hdf4_wpi), external :: sfRCAtt
  22977. integer(hdf4_wpi), external :: sfRNAtt
  22978. #endif
  22979. ! --- local --------------------------------------
  22980. type(MDF_File), pointer :: filep
  22981. type(MDF_Var), pointer :: varp
  22982. integer :: ftype
  22983. #ifdef with_hdf4
  22984. integer :: hdf4_id
  22985. integer :: hdf4_iatt
  22986. character(len=LEN_NAME) :: hdf4_name
  22987. integer :: hdf4_xtype
  22988. integer :: hdf4_length
  22989. integer(1) :: values_int1
  22990. integer(2) :: values_int2
  22991. integer(4) :: values_int4
  22992. integer(8) :: values_int8
  22993. real(4) :: values_real4
  22994. real(8) :: values_real8
  22995. #endif
  22996. #ifdef with_hdf5_beta
  22997. integer(HID_T) :: hdf5_loc_id
  22998. character(len=LEN_NAME) :: hdf5_obj_name
  22999. integer(HID_T) :: hdf5_attr_id
  23000. integer(HID_T) :: hdf5_type_id
  23001. integer(4) :: hdf5_values_int4
  23002. #endif
  23003. #ifdef with_netcdf
  23004. integer :: netcdf_varid
  23005. #endif
  23006. ! --- begin --------------------------------------
  23007. ! single type:
  23008. call MDF_Get_Type( hid, ftype, status )
  23009. IF_NOT_OK_RETURN(status=1)
  23010. ! pointer to file structure:
  23011. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23012. IF_NOT_OK_RETURN(status=1)
  23013. ! pointer to variable structure if possible:
  23014. if ( varid /= MDF_GLOBAL ) then
  23015. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23016. IF_NOT_OK_RETURN(status=1)
  23017. end if
  23018. ! select appropriate routine for each type:
  23019. select case ( ftype )
  23020. #ifdef with_hdf4
  23021. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23022. case ( MDF_HDF4 )
  23023. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23024. ! set variable id:
  23025. if ( varid == MDF_GLOBAL ) then
  23026. hdf4_id = filep%hdf4_id
  23027. else
  23028. hdf4_id = varp%hdf4_sdid
  23029. end if
  23030. ! get attribute index given name:
  23031. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  23032. if ( hdf4_iatt == FAIL ) then
  23033. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  23034. TRACEBACK; status=1; return
  23035. end if
  23036. ! get type and length:
  23037. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  23038. if ( status /= SUCCEED ) then
  23039. write (gol,'("getting attribute info")') trim(name); call goErr
  23040. TRACEBACK; status=1; return
  23041. end if
  23042. ! read numerical attribute:
  23043. select case ( hdf4_xtype )
  23044. case ( DFNT_INT8 )
  23045. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  23046. values = int(values_int1,kind=4)
  23047. case ( DFNT_INT16 )
  23048. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  23049. values = int(values_int2,kind=4)
  23050. case ( DFNT_INT32 )
  23051. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  23052. values = int(values_int4,kind=4)
  23053. case ( DFNT_INT64 )
  23054. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  23055. values = int(values_int8,kind=4)
  23056. case ( DFNT_FLOAT32 )
  23057. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  23058. values = int(values_real4,kind=4)
  23059. case ( DFNT_FLOAT64 )
  23060. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  23061. values = int(values_real8,kind=4)
  23062. case default
  23063. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  23064. TRACEBACK; status=1; return
  23065. end select
  23066. if ( status /= SUCCEED ) then
  23067. write (*,'("reading attribute : ",a)') trim(name); call goErr
  23068. TRACEBACK; status=1; return
  23069. end if
  23070. #endif
  23071. #ifdef with_hdf5_beta
  23072. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23073. case ( MDF_HDF5 )
  23074. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23075. ! set variable id:
  23076. if ( varid == MDF_GLOBAL ) then
  23077. ! file id:
  23078. hdf5_loc_id = filep%hdf5_file_id
  23079. hdf5_obj_name = '.'
  23080. else
  23081. ! file id:
  23082. hdf5_loc_id = varp%hdf5_dataset_id
  23083. hdf5_obj_name = '.'
  23084. end if
  23085. ! data type:
  23086. call H5TCopy_f( H5T_NATIVE_INTEGER, hdf5_type_id, status )
  23087. IF_NOT_OK_RETURN(status=1)
  23088. ! open attribute:
  23089. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  23090. IF_NOT_OK_RETURN(status=1)
  23091. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  23092. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int((/1/),HSIZE_T), status )
  23093. IF_NOT_OK_RETURN(status=1)
  23094. ! convert:
  23095. values = int(hdf5_values_int4,4)
  23096. ! release:
  23097. call H5TClose_f( hdf5_type_id, status )
  23098. IF_NOT_OK_RETURN(status=1)
  23099. ! release:
  23100. call H5AClose_f( hdf5_attr_id, status )
  23101. IF_NOT_OK_RETURN(status=1)
  23102. #endif
  23103. #ifdef with_netcdf
  23104. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23105. case ( MDF_NETCDF, MDF_NETCDF4 )
  23106. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23107. ! set variable id:
  23108. if ( varid == MDF_GLOBAL ) then
  23109. netcdf_varid = NF90_GLOBAL
  23110. else
  23111. netcdf_varid = varp%netcdf_varid
  23112. end if
  23113. ! read attribute:
  23114. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23115. IF_NF90_NOT_OK_RETURN(status=1)
  23116. #endif
  23117. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23118. case default
  23119. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23120. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23121. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23122. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23123. TRACEBACK; status=1; return
  23124. end select
  23125. ! ok
  23126. status = 0
  23127. end subroutine MDF_Get_Att_i4_0d
  23128. subroutine MDF_Put_Att_i4_1d( hid, varid, name, values, status )
  23129. #ifdef with_hdf5_beta
  23130. use HDF5, only : HID_T, HSIZE_T
  23131. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23132. use HDF5, only : H5T_NATIVE_CHARACTER
  23133. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  23134. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23135. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  23136. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  23137. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  23138. #endif
  23139. #ifdef with_netcdf
  23140. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  23141. #endif
  23142. ! --- in/out -------------------------------------
  23143. integer, intent(in) :: hid
  23144. integer, intent(in) :: varid
  23145. character(len=*), intent(in) :: name
  23146. integer(4), intent(in) :: values(:)
  23147. integer, intent(out) :: status
  23148. ! --- const --------------------------------------
  23149. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_i4_1d'
  23150. ! --- external -------------------------------
  23151. #ifdef with_hdf4
  23152. integer(hdf4_wpi), external :: sfSCAtt
  23153. integer(hdf4_wpi), external :: sfSNAtt
  23154. #endif
  23155. ! --- local --------------------------------------
  23156. type(MDF_File), pointer :: filep
  23157. type(MDF_Var), pointer :: varp
  23158. integer :: iftype
  23159. integer :: ftype
  23160. #ifdef with_hdf4
  23161. integer :: hdf4_id
  23162. #endif
  23163. #ifdef with_hdf5_beta
  23164. integer(HID_T) :: hdf5_loc_id
  23165. integer(HID_T) :: hdf5_attr_id
  23166. integer(HID_T) :: hdf5_space_id
  23167. integer(HID_T) :: hdf5_type_id
  23168. #endif
  23169. #ifdef with_netcdf
  23170. integer :: netcdf_varid
  23171. #endif
  23172. ! --- begin --------------------------------------
  23173. ! pointer to file structure:
  23174. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23175. IF_NOT_OK_RETURN(status=1)
  23176. ! global or variable attribute ?
  23177. if ( varid == MDF_GLOBAL ) then
  23178. ! increase counter:
  23179. filep%natt = filep%natt + 1
  23180. else
  23181. ! pointer to variable structure:
  23182. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23183. IF_NOT_OK_RETURN(status=1)
  23184. ! increase counter:
  23185. varp%natt = varp%natt + 1
  23186. end if
  23187. ! loop over file types:
  23188. do iftype = 1, filep%nftype
  23189. ! current type:
  23190. ftype = filep%ftypes(iftype)
  23191. ! select appropriate routine for each type:
  23192. select case ( ftype )
  23193. #ifdef with_hdf4
  23194. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23195. case ( MDF_HDF4 )
  23196. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23197. ! set variable id:
  23198. if ( varid == MDF_GLOBAL ) then
  23199. hdf4_id = filep%hdf4_id
  23200. else
  23201. hdf4_id = varp%hdf4_sdid
  23202. end if
  23203. ! strore numerical attribute:
  23204. status = sfSNAtt( hdf4_id, trim(name), DFNT_INT32, size(values), values )
  23205. if ( status /= SUCCEED ) then
  23206. write (*,'("writing attribute : ",a)') trim(name); call goErr
  23207. TRACEBACK; status=1; return
  23208. end if
  23209. #endif
  23210. #ifdef with_hdf5_beta
  23211. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23212. case ( MDF_HDF5 )
  23213. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23214. ! set variable id:
  23215. if ( varid == MDF_GLOBAL ) then
  23216. hdf5_loc_id = filep%hdf5_file_id
  23217. else
  23218. hdf5_loc_id = varp%hdf5_dataset_id
  23219. end if
  23220. ! data type:
  23221. call H5TCopy_f( H5T_NATIVE_INTEGER, hdf5_type_id, status )
  23222. IF_NOT_OK_RETURN(status=1)
  23223. ! data space:
  23224. call H5SCreate_f( H5S_SIMPLE_F, hdf5_space_id, status )
  23225. IF_NOT_OK_RETURN(status=1)
  23226. ! set extent of the data space:
  23227. call H5SSet_Extent_Simple_f( hdf5_space_id, 1, int(shape(values),kind=HSIZE_T), int(shape(values),kind=HSIZE_T), status )
  23228. IF_NOT_OK_RETURN(status=1)
  23229. ! create attribute; type in file is same as type provided to this routine:
  23230. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  23231. IF_NOT_OK_RETURN(status=1)
  23232. ! write attribute values:
  23233. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_INTEGER, int(values), int(shape(values),kind=HSIZE_T), status )
  23234. IF_NOT_OK_RETURN(status=1)
  23235. ! release attribute:
  23236. call H5AClose_f( hdf5_attr_id, status )
  23237. IF_NOT_OK_RETURN(status=1)
  23238. ! release data space:
  23239. call H5SClose_f( hdf5_space_id, status )
  23240. IF_NOT_OK_RETURN(status=1)
  23241. ! release data type:
  23242. call H5TClose_f( hdf5_type_id, status )
  23243. IF_NOT_OK_RETURN(status=1)
  23244. #endif
  23245. #ifdef with_netcdf
  23246. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23247. case ( MDF_NETCDF, MDF_NETCDF4 )
  23248. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23249. ! set variable id:
  23250. if ( varid == MDF_GLOBAL ) then
  23251. netcdf_varid = NF90_GLOBAL
  23252. else
  23253. netcdf_varid = varp%netcdf_varid
  23254. end if
  23255. ! write attribute:
  23256. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23257. IF_NF90_NOT_OK_RETURN(status=1)
  23258. #endif
  23259. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23260. case default
  23261. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23262. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23263. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23264. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23265. TRACEBACK; status=1; return
  23266. end select
  23267. end do ! file types
  23268. ! ok
  23269. status = 0
  23270. end subroutine MDF_Put_Att_i4_1d
  23271. ! ***
  23272. subroutine MDF_Get_Att_i4_1d( hid, varid, name, values, status )
  23273. #ifdef with_hdf5_beta
  23274. use HDF5, only : HSIZE_T
  23275. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  23276. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23277. use HDF5, only : H5T_NATIVE_CHARACTER
  23278. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  23279. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23280. #endif
  23281. #ifdef with_netcdf
  23282. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  23283. #endif
  23284. ! --- in/out -------------------------------------
  23285. integer, intent(in) :: hid
  23286. integer, intent(in) :: varid
  23287. character(len=*), intent(in) :: name
  23288. integer(4), intent(out) :: values(:)
  23289. integer, intent(out) :: status
  23290. ! --- const --------------------------------------
  23291. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_i4_1d'
  23292. ! --- external -------------------------------
  23293. #ifdef with_hdf4
  23294. integer(hdf4_wpi), external :: sfFAttr
  23295. integer(hdf4_wpi), external :: sfGAInfo
  23296. integer(hdf4_wpi), external :: sfRCAtt
  23297. integer(hdf4_wpi), external :: sfRNAtt
  23298. #endif
  23299. ! --- local --------------------------------------
  23300. type(MDF_File), pointer :: filep
  23301. type(MDF_Var), pointer :: varp
  23302. integer :: ftype
  23303. #ifdef with_hdf4
  23304. integer :: hdf4_id
  23305. integer :: hdf4_iatt
  23306. character(len=LEN_NAME) :: hdf4_name
  23307. integer :: hdf4_xtype
  23308. integer :: hdf4_length
  23309. integer(1), allocatable :: values_int1(:)
  23310. integer(2), allocatable :: values_int2(:)
  23311. integer(4), allocatable :: values_int4(:)
  23312. integer(8), allocatable :: values_int8(:)
  23313. real(4), allocatable :: values_real4(:)
  23314. real(8), allocatable :: values_real8(:)
  23315. #endif
  23316. #ifdef with_hdf5_beta
  23317. integer(HID_T) :: hdf5_loc_id
  23318. character(len=LEN_NAME) :: hdf5_obj_name
  23319. integer(HID_T) :: hdf5_attr_id
  23320. integer(HID_T) :: hdf5_type_id
  23321. integer(4), allocatable :: hdf5_values_int4(:)
  23322. #endif
  23323. #ifdef with_netcdf
  23324. integer :: netcdf_varid
  23325. #endif
  23326. ! --- begin --------------------------------------
  23327. ! single type:
  23328. call MDF_Get_Type( hid, ftype, status )
  23329. IF_NOT_OK_RETURN(status=1)
  23330. ! pointer to file structure:
  23331. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23332. IF_NOT_OK_RETURN(status=1)
  23333. ! pointer to variable structure if possible:
  23334. if ( varid /= MDF_GLOBAL ) then
  23335. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23336. IF_NOT_OK_RETURN(status=1)
  23337. end if
  23338. ! select appropriate routine for each type:
  23339. select case ( ftype )
  23340. #ifdef with_hdf4
  23341. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23342. case ( MDF_HDF4 )
  23343. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23344. ! set variable id:
  23345. if ( varid == MDF_GLOBAL ) then
  23346. hdf4_id = filep%hdf4_id
  23347. else
  23348. hdf4_id = varp%hdf4_sdid
  23349. end if
  23350. ! get attribute index given name:
  23351. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  23352. if ( hdf4_iatt == FAIL ) then
  23353. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  23354. TRACEBACK; status=1; return
  23355. end if
  23356. ! get type and length:
  23357. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  23358. if ( status /= SUCCEED ) then
  23359. write (gol,'("getting attribute info")') trim(name); call goErr
  23360. TRACEBACK; status=1; return
  23361. end if
  23362. ! read numerical attribute:
  23363. select case ( hdf4_xtype )
  23364. case ( DFNT_INT8 )
  23365. allocate( values_int1(hdf4_length) )
  23366. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  23367. values = int(values_int1,kind=4)
  23368. deallocate( values_int1 )
  23369. case ( DFNT_INT16 )
  23370. allocate( values_int2(hdf4_length) )
  23371. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  23372. values = int(values_int2,kind=4)
  23373. deallocate( values_int2 )
  23374. case ( DFNT_INT32 )
  23375. allocate( values_int4(hdf4_length) )
  23376. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  23377. values = int(values_int4,kind=4)
  23378. deallocate( values_int4 )
  23379. case ( DFNT_INT64 )
  23380. allocate( values_int8(hdf4_length) )
  23381. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  23382. values = int(values_int8,kind=4)
  23383. deallocate( values_int8 )
  23384. case ( DFNT_FLOAT32 )
  23385. allocate( values_real4(hdf4_length) )
  23386. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  23387. values = int(values_real4,kind=4)
  23388. deallocate( values_real4 )
  23389. case ( DFNT_FLOAT64 )
  23390. allocate( values_real8(hdf4_length) )
  23391. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  23392. values = int(values_real8,kind=4)
  23393. deallocate( values_real8 )
  23394. case default
  23395. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  23396. TRACEBACK; status=1; return
  23397. end select
  23398. if ( status /= SUCCEED ) then
  23399. write (*,'("reading attribute : ",a)') trim(name); call goErr
  23400. TRACEBACK; status=1; return
  23401. end if
  23402. #endif
  23403. #ifdef with_hdf5_beta
  23404. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23405. case ( MDF_HDF5 )
  23406. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23407. ! set variable id:
  23408. if ( varid == MDF_GLOBAL ) then
  23409. ! file id:
  23410. hdf5_loc_id = filep%hdf5_file_id
  23411. hdf5_obj_name = '.'
  23412. else
  23413. ! file id:
  23414. hdf5_loc_id = varp%hdf5_dataset_id
  23415. hdf5_obj_name = '.'
  23416. end if
  23417. ! data type:
  23418. call H5TCopy_f( H5T_NATIVE_INTEGER, hdf5_type_id, status )
  23419. IF_NOT_OK_RETURN(status=1)
  23420. ! open attribute:
  23421. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  23422. IF_NOT_OK_RETURN(status=1)
  23423. ! storage:
  23424. allocate( hdf5_values_int4(size(values)) )
  23425. ! read into integer(4), since no specific routines for kinds 1 and 2 seem available::
  23426. call H5ARead_f( hdf5_attr_id, H5T_NATIVE_INTEGER, hdf5_values_int4, int(shape(values),HSIZE_T), status )
  23427. IF_NOT_OK_RETURN(status=1)
  23428. ! convert:
  23429. values = int(hdf5_values_int4,4)
  23430. ! clear:
  23431. deallocate( hdf5_values_int4 )
  23432. ! release:
  23433. call H5TClose_f( hdf5_type_id, status )
  23434. IF_NOT_OK_RETURN(status=1)
  23435. ! release:
  23436. call H5AClose_f( hdf5_attr_id, status )
  23437. IF_NOT_OK_RETURN(status=1)
  23438. #endif
  23439. #ifdef with_netcdf
  23440. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23441. case ( MDF_NETCDF, MDF_NETCDF4 )
  23442. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23443. ! set variable id:
  23444. if ( varid == MDF_GLOBAL ) then
  23445. netcdf_varid = NF90_GLOBAL
  23446. else
  23447. netcdf_varid = varp%netcdf_varid
  23448. end if
  23449. ! read attribute:
  23450. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23451. IF_NF90_NOT_OK_RETURN(status=1)
  23452. #endif
  23453. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23454. case default
  23455. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23456. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23457. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23458. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23459. TRACEBACK; status=1; return
  23460. end select
  23461. ! ok
  23462. status = 0
  23463. end subroutine MDF_Get_Att_i4_1d
  23464. subroutine MDF_Put_Att_r4_0d( hid, varid, name, values, status )
  23465. #ifdef with_hdf5_beta
  23466. use HDF5, only : HID_T, HSIZE_T
  23467. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23468. use HDF5, only : H5T_NATIVE_CHARACTER
  23469. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  23470. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23471. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  23472. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  23473. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  23474. #endif
  23475. #ifdef with_netcdf
  23476. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  23477. #endif
  23478. ! --- in/out -------------------------------------
  23479. integer, intent(in) :: hid
  23480. integer, intent(in) :: varid
  23481. character(len=*), intent(in) :: name
  23482. real(4), intent(in) :: values
  23483. integer, intent(out) :: status
  23484. ! --- const --------------------------------------
  23485. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_r4_0d'
  23486. ! --- external -------------------------------
  23487. #ifdef with_hdf4
  23488. integer(hdf4_wpi), external :: sfSCAtt
  23489. integer(hdf4_wpi), external :: sfSNAtt
  23490. #endif
  23491. ! --- local --------------------------------------
  23492. type(MDF_File), pointer :: filep
  23493. type(MDF_Var), pointer :: varp
  23494. integer :: iftype
  23495. integer :: ftype
  23496. #ifdef with_hdf4
  23497. integer :: hdf4_id
  23498. #endif
  23499. #ifdef with_hdf5_beta
  23500. integer(HID_T) :: hdf5_loc_id
  23501. integer(HID_T) :: hdf5_attr_id
  23502. integer(HID_T) :: hdf5_space_id
  23503. integer(HID_T) :: hdf5_type_id
  23504. #endif
  23505. #ifdef with_netcdf
  23506. integer :: netcdf_varid
  23507. #endif
  23508. ! --- begin --------------------------------------
  23509. ! pointer to file structure:
  23510. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23511. IF_NOT_OK_RETURN(status=1)
  23512. ! global or variable attribute ?
  23513. if ( varid == MDF_GLOBAL ) then
  23514. ! increase counter:
  23515. filep%natt = filep%natt + 1
  23516. else
  23517. ! pointer to variable structure:
  23518. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23519. IF_NOT_OK_RETURN(status=1)
  23520. ! increase counter:
  23521. varp%natt = varp%natt + 1
  23522. end if
  23523. ! loop over file types:
  23524. do iftype = 1, filep%nftype
  23525. ! current type:
  23526. ftype = filep%ftypes(iftype)
  23527. ! select appropriate routine for each type:
  23528. select case ( ftype )
  23529. #ifdef with_hdf4
  23530. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23531. case ( MDF_HDF4 )
  23532. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23533. ! set variable id:
  23534. if ( varid == MDF_GLOBAL ) then
  23535. hdf4_id = filep%hdf4_id
  23536. else
  23537. hdf4_id = varp%hdf4_sdid
  23538. end if
  23539. ! store numerical attribute:
  23540. status = sfSNAtt( hdf4_id, trim(name), DFNT_FLOAT32, 1, values )
  23541. if ( status /= SUCCEED ) then
  23542. write (*,'("writing attribute : ",a)') trim(name); call goErr
  23543. TRACEBACK; status=1; return
  23544. end if
  23545. #endif
  23546. #ifdef with_hdf5_beta
  23547. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23548. case ( MDF_HDF5 )
  23549. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23550. ! set variable id:
  23551. if ( varid == MDF_GLOBAL ) then
  23552. hdf5_loc_id = filep%hdf5_file_id
  23553. else
  23554. hdf5_loc_id = varp%hdf5_dataset_id
  23555. end if
  23556. ! data type:
  23557. call H5TCopy_f( H5T_NATIVE_REAL, hdf5_type_id, status )
  23558. IF_NOT_OK_RETURN(status=1)
  23559. ! data space:
  23560. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  23561. IF_NOT_OK_RETURN(status=1)
  23562. ! create attribute; type in file is same as type provided to this routine:
  23563. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  23564. IF_NOT_OK_RETURN(status=1)
  23565. ! write attribute values:
  23566. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_REAL, values, int((/1/),kind=HSIZE_T), status )
  23567. IF_NOT_OK_RETURN(status=1)
  23568. ! release attribute:
  23569. call H5AClose_f( hdf5_attr_id, status )
  23570. IF_NOT_OK_RETURN(status=1)
  23571. ! release data space:
  23572. call H5SClose_f( hdf5_space_id, status )
  23573. IF_NOT_OK_RETURN(status=1)
  23574. ! release data type:
  23575. call H5TClose_f( hdf5_type_id, status )
  23576. IF_NOT_OK_RETURN(status=1)
  23577. #endif
  23578. #ifdef with_netcdf
  23579. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23580. case ( MDF_NETCDF, MDF_NETCDF4 )
  23581. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23582. ! set variable id:
  23583. if ( varid == MDF_GLOBAL ) then
  23584. netcdf_varid = NF90_GLOBAL
  23585. else
  23586. netcdf_varid = varp%netcdf_varid
  23587. end if
  23588. ! write attribute:
  23589. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23590. IF_NF90_NOT_OK_RETURN(status=1)
  23591. #endif
  23592. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23593. case default
  23594. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23595. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23596. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23597. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23598. TRACEBACK; status=1; return
  23599. end select
  23600. end do ! file types
  23601. ! ok
  23602. status = 0
  23603. end subroutine MDF_Put_Att_r4_0d
  23604. ! ***
  23605. subroutine MDF_Get_Att_r4_0d( hid, varid, name, values, status )
  23606. #ifdef with_hdf5_beta
  23607. use HDF5, only : HSIZE_T
  23608. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  23609. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23610. use HDF5, only : H5T_NATIVE_CHARACTER
  23611. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  23612. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23613. #endif
  23614. #ifdef with_netcdf
  23615. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  23616. #endif
  23617. ! --- in/out -------------------------------------
  23618. integer, intent(in) :: hid
  23619. integer, intent(in) :: varid
  23620. character(len=*), intent(in) :: name
  23621. real(4), intent(out) :: values
  23622. integer, intent(out) :: status
  23623. ! --- const --------------------------------------
  23624. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_r4_0d'
  23625. ! --- external -------------------------------
  23626. #ifdef with_hdf4
  23627. integer(hdf4_wpi), external :: sfFAttr
  23628. integer(hdf4_wpi), external :: sfGAInfo
  23629. integer(hdf4_wpi), external :: sfRCAtt
  23630. integer(hdf4_wpi), external :: sfRNAtt
  23631. #endif
  23632. ! --- local --------------------------------------
  23633. type(MDF_File), pointer :: filep
  23634. type(MDF_Var), pointer :: varp
  23635. integer :: ftype
  23636. #ifdef with_hdf4
  23637. integer :: hdf4_id
  23638. integer :: hdf4_iatt
  23639. character(len=LEN_NAME) :: hdf4_name
  23640. integer :: hdf4_xtype
  23641. integer :: hdf4_length
  23642. integer(1) :: values_int1
  23643. integer(2) :: values_int2
  23644. integer(4) :: values_int4
  23645. integer(8) :: values_int8
  23646. real(4) :: values_real4
  23647. real(8) :: values_real8
  23648. #endif
  23649. #ifdef with_hdf5_beta
  23650. integer(HID_T) :: hdf5_loc_id
  23651. character(len=LEN_NAME) :: hdf5_obj_name
  23652. integer(HID_T) :: hdf5_attr_id
  23653. integer(HID_T) :: hdf5_type_id
  23654. #endif
  23655. #ifdef with_netcdf
  23656. integer :: netcdf_varid
  23657. #endif
  23658. ! --- begin --------------------------------------
  23659. ! single type:
  23660. call MDF_Get_Type( hid, ftype, status )
  23661. IF_NOT_OK_RETURN(status=1)
  23662. ! pointer to file structure:
  23663. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23664. IF_NOT_OK_RETURN(status=1)
  23665. ! pointer to variable structure if possible:
  23666. if ( varid /= MDF_GLOBAL ) then
  23667. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23668. IF_NOT_OK_RETURN(status=1)
  23669. end if
  23670. ! select appropriate routine for each type:
  23671. select case ( ftype )
  23672. #ifdef with_hdf4
  23673. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23674. case ( MDF_HDF4 )
  23675. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23676. ! set variable id:
  23677. if ( varid == MDF_GLOBAL ) then
  23678. hdf4_id = filep%hdf4_id
  23679. else
  23680. hdf4_id = varp%hdf4_sdid
  23681. end if
  23682. ! get attribute index given name:
  23683. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  23684. if ( hdf4_iatt == FAIL ) then
  23685. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  23686. TRACEBACK; status=1; return
  23687. end if
  23688. ! get type and length:
  23689. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  23690. if ( status /= SUCCEED ) then
  23691. write (gol,'("getting attribute info")') trim(name); call goErr
  23692. TRACEBACK; status=1; return
  23693. end if
  23694. ! read numerical attribute:
  23695. select case ( hdf4_xtype )
  23696. case ( DFNT_INT8 )
  23697. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  23698. values = real(values_int1,kind=4)
  23699. case ( DFNT_INT16 )
  23700. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  23701. values = real(values_int2,kind=4)
  23702. case ( DFNT_INT32 )
  23703. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  23704. values = real(values_int4,kind=4)
  23705. case ( DFNT_INT64 )
  23706. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  23707. values = real(values_int8,kind=4)
  23708. case ( DFNT_FLOAT32 )
  23709. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  23710. values = real(values_real4,kind=4)
  23711. case ( DFNT_FLOAT64 )
  23712. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  23713. values = real(values_real8,kind=4)
  23714. case default
  23715. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  23716. TRACEBACK; status=1; return
  23717. end select
  23718. if ( status /= SUCCEED ) then
  23719. write (*,'("reading attribute : ",a)') trim(name); call goErr
  23720. TRACEBACK; status=1; return
  23721. end if
  23722. #endif
  23723. #ifdef with_hdf5_beta
  23724. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23725. case ( MDF_HDF5 )
  23726. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23727. ! set variable id:
  23728. if ( varid == MDF_GLOBAL ) then
  23729. ! file id:
  23730. hdf5_loc_id = filep%hdf5_file_id
  23731. hdf5_obj_name = '.'
  23732. else
  23733. ! file id:
  23734. hdf5_loc_id = varp%hdf5_dataset_id
  23735. hdf5_obj_name = '.'
  23736. end if
  23737. ! data type:
  23738. call H5TCopy_f( H5T_NATIVE_REAL, hdf5_type_id, status )
  23739. IF_NOT_OK_RETURN(status=1)
  23740. ! open attribute:
  23741. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  23742. IF_NOT_OK_RETURN(status=1)
  23743. ! read:
  23744. call H5ARead_f( hdf5_attr_id, hdf5_type_id, values, int((/1/),HSIZE_T), status )
  23745. IF_NOT_OK_RETURN(status=1)
  23746. ! release:
  23747. call H5TClose_f( hdf5_type_id, status )
  23748. IF_NOT_OK_RETURN(status=1)
  23749. ! release:
  23750. call H5AClose_f( hdf5_attr_id, status )
  23751. IF_NOT_OK_RETURN(status=1)
  23752. #endif
  23753. #ifdef with_netcdf
  23754. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23755. case ( MDF_NETCDF, MDF_NETCDF4 )
  23756. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23757. ! set variable id:
  23758. if ( varid == MDF_GLOBAL ) then
  23759. netcdf_varid = NF90_GLOBAL
  23760. else
  23761. netcdf_varid = varp%netcdf_varid
  23762. end if
  23763. ! read attribute:
  23764. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23765. IF_NF90_NOT_OK_RETURN(status=1)
  23766. #endif
  23767. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23768. case default
  23769. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23770. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23771. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23772. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23773. TRACEBACK; status=1; return
  23774. end select
  23775. ! ok
  23776. status = 0
  23777. end subroutine MDF_Get_Att_r4_0d
  23778. subroutine MDF_Put_Att_r4_1d( hid, varid, name, values, status )
  23779. #ifdef with_hdf5_beta
  23780. use HDF5, only : HID_T, HSIZE_T
  23781. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23782. use HDF5, only : H5T_NATIVE_CHARACTER
  23783. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  23784. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23785. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  23786. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  23787. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  23788. #endif
  23789. #ifdef with_netcdf
  23790. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  23791. #endif
  23792. ! --- in/out -------------------------------------
  23793. integer, intent(in) :: hid
  23794. integer, intent(in) :: varid
  23795. character(len=*), intent(in) :: name
  23796. real(4), intent(in) :: values(:)
  23797. integer, intent(out) :: status
  23798. ! --- const --------------------------------------
  23799. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_r4_1d'
  23800. ! --- external -------------------------------
  23801. #ifdef with_hdf4
  23802. integer(hdf4_wpi), external :: sfSCAtt
  23803. integer(hdf4_wpi), external :: sfSNAtt
  23804. #endif
  23805. ! --- local --------------------------------------
  23806. type(MDF_File), pointer :: filep
  23807. type(MDF_Var), pointer :: varp
  23808. integer :: iftype
  23809. integer :: ftype
  23810. #ifdef with_hdf4
  23811. integer :: hdf4_id
  23812. #endif
  23813. #ifdef with_hdf5_beta
  23814. integer(HID_T) :: hdf5_loc_id
  23815. integer(HID_T) :: hdf5_attr_id
  23816. integer(HID_T) :: hdf5_space_id
  23817. integer(HID_T) :: hdf5_type_id
  23818. #endif
  23819. #ifdef with_netcdf
  23820. integer :: netcdf_varid
  23821. #endif
  23822. ! --- begin --------------------------------------
  23823. ! pointer to file structure:
  23824. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23825. IF_NOT_OK_RETURN(status=1)
  23826. ! global or variable attribute ?
  23827. if ( varid == MDF_GLOBAL ) then
  23828. ! increase counter:
  23829. filep%natt = filep%natt + 1
  23830. else
  23831. ! pointer to variable structure:
  23832. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23833. IF_NOT_OK_RETURN(status=1)
  23834. ! increase counter:
  23835. varp%natt = varp%natt + 1
  23836. end if
  23837. ! loop over file types:
  23838. do iftype = 1, filep%nftype
  23839. ! current type:
  23840. ftype = filep%ftypes(iftype)
  23841. ! select appropriate routine for each type:
  23842. select case ( ftype )
  23843. #ifdef with_hdf4
  23844. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23845. case ( MDF_HDF4 )
  23846. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23847. ! set variable id:
  23848. if ( varid == MDF_GLOBAL ) then
  23849. hdf4_id = filep%hdf4_id
  23850. else
  23851. hdf4_id = varp%hdf4_sdid
  23852. end if
  23853. ! strore numerical attribute:
  23854. status = sfSNAtt( hdf4_id, trim(name), DFNT_FLOAT32, size(values), values )
  23855. if ( status /= SUCCEED ) then
  23856. write (*,'("writing attribute : ",a)') trim(name); call goErr
  23857. TRACEBACK; status=1; return
  23858. end if
  23859. #endif
  23860. #ifdef with_hdf5_beta
  23861. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23862. case ( MDF_HDF5 )
  23863. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23864. ! set variable id:
  23865. if ( varid == MDF_GLOBAL ) then
  23866. hdf5_loc_id = filep%hdf5_file_id
  23867. else
  23868. hdf5_loc_id = varp%hdf5_dataset_id
  23869. end if
  23870. ! data type:
  23871. call H5TCopy_f( H5T_NATIVE_REAL, hdf5_type_id, status )
  23872. IF_NOT_OK_RETURN(status=1)
  23873. ! data space:
  23874. call H5SCreate_f( H5S_SIMPLE_F, hdf5_space_id, status )
  23875. IF_NOT_OK_RETURN(status=1)
  23876. ! set extent of the data space:
  23877. call H5SSet_Extent_Simple_f( hdf5_space_id, 1, int(shape(values),kind=HSIZE_T), int(shape(values),kind=HSIZE_T), status )
  23878. IF_NOT_OK_RETURN(status=1)
  23879. ! create attribute; type in file is same as type provided to this routine:
  23880. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  23881. IF_NOT_OK_RETURN(status=1)
  23882. ! write attribute values:
  23883. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_REAL, values, int(shape(values),kind=HSIZE_T), status )
  23884. IF_NOT_OK_RETURN(status=1)
  23885. ! release attribute:
  23886. call H5AClose_f( hdf5_attr_id, status )
  23887. IF_NOT_OK_RETURN(status=1)
  23888. ! release data space:
  23889. call H5SClose_f( hdf5_space_id, status )
  23890. IF_NOT_OK_RETURN(status=1)
  23891. ! release data type:
  23892. call H5TClose_f( hdf5_type_id, status )
  23893. IF_NOT_OK_RETURN(status=1)
  23894. #endif
  23895. #ifdef with_netcdf
  23896. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23897. case ( MDF_NETCDF, MDF_NETCDF4 )
  23898. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23899. ! set variable id:
  23900. if ( varid == MDF_GLOBAL ) then
  23901. netcdf_varid = NF90_GLOBAL
  23902. else
  23903. netcdf_varid = varp%netcdf_varid
  23904. end if
  23905. ! write attribute:
  23906. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  23907. IF_NF90_NOT_OK_RETURN(status=1)
  23908. #endif
  23909. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23910. case default
  23911. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23912. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  23913. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  23914. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  23915. TRACEBACK; status=1; return
  23916. end select
  23917. end do ! file types
  23918. ! ok
  23919. status = 0
  23920. end subroutine MDF_Put_Att_r4_1d
  23921. ! ***
  23922. subroutine MDF_Get_Att_r4_1d( hid, varid, name, values, status )
  23923. #ifdef with_hdf5_beta
  23924. use HDF5, only : HSIZE_T
  23925. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  23926. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  23927. use HDF5, only : H5T_NATIVE_CHARACTER
  23928. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  23929. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  23930. #endif
  23931. #ifdef with_netcdf
  23932. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  23933. #endif
  23934. ! --- in/out -------------------------------------
  23935. integer, intent(in) :: hid
  23936. integer, intent(in) :: varid
  23937. character(len=*), intent(in) :: name
  23938. real(4), intent(out) :: values(:)
  23939. integer, intent(out) :: status
  23940. ! --- const --------------------------------------
  23941. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_r4_1d'
  23942. ! --- external -------------------------------
  23943. #ifdef with_hdf4
  23944. integer(hdf4_wpi), external :: sfFAttr
  23945. integer(hdf4_wpi), external :: sfGAInfo
  23946. integer(hdf4_wpi), external :: sfRCAtt
  23947. integer(hdf4_wpi), external :: sfRNAtt
  23948. #endif
  23949. ! --- local --------------------------------------
  23950. type(MDF_File), pointer :: filep
  23951. type(MDF_Var), pointer :: varp
  23952. integer :: ftype
  23953. #ifdef with_hdf4
  23954. integer :: hdf4_id
  23955. integer :: hdf4_iatt
  23956. character(len=LEN_NAME) :: hdf4_name
  23957. integer :: hdf4_xtype
  23958. integer :: hdf4_length
  23959. integer(1), allocatable :: values_int1(:)
  23960. integer(2), allocatable :: values_int2(:)
  23961. integer(4), allocatable :: values_int4(:)
  23962. integer(8), allocatable :: values_int8(:)
  23963. real(4), allocatable :: values_real4(:)
  23964. real(8), allocatable :: values_real8(:)
  23965. #endif
  23966. #ifdef with_hdf5_beta
  23967. integer(HID_T) :: hdf5_loc_id
  23968. character(len=LEN_NAME) :: hdf5_obj_name
  23969. integer(HID_T) :: hdf5_attr_id
  23970. integer(HID_T) :: hdf5_type_id
  23971. #endif
  23972. #ifdef with_netcdf
  23973. integer :: netcdf_varid
  23974. #endif
  23975. ! --- begin --------------------------------------
  23976. ! single type:
  23977. call MDF_Get_Type( hid, ftype, status )
  23978. IF_NOT_OK_RETURN(status=1)
  23979. ! pointer to file structure:
  23980. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  23981. IF_NOT_OK_RETURN(status=1)
  23982. ! pointer to variable structure if possible:
  23983. if ( varid /= MDF_GLOBAL ) then
  23984. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  23985. IF_NOT_OK_RETURN(status=1)
  23986. end if
  23987. ! select appropriate routine for each type:
  23988. select case ( ftype )
  23989. #ifdef with_hdf4
  23990. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23991. case ( MDF_HDF4 )
  23992. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  23993. ! set variable id:
  23994. if ( varid == MDF_GLOBAL ) then
  23995. hdf4_id = filep%hdf4_id
  23996. else
  23997. hdf4_id = varp%hdf4_sdid
  23998. end if
  23999. ! get attribute index given name:
  24000. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  24001. if ( hdf4_iatt == FAIL ) then
  24002. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  24003. TRACEBACK; status=1; return
  24004. end if
  24005. ! get type and length:
  24006. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  24007. if ( status /= SUCCEED ) then
  24008. write (gol,'("getting attribute info")') trim(name); call goErr
  24009. TRACEBACK; status=1; return
  24010. end if
  24011. ! read numerical attribute:
  24012. select case ( hdf4_xtype )
  24013. case ( DFNT_INT8 )
  24014. allocate( values_int1(hdf4_length) )
  24015. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  24016. values = real(values_int1,kind=4)
  24017. deallocate( values_int1 )
  24018. case ( DFNT_INT16 )
  24019. allocate( values_int2(hdf4_length) )
  24020. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  24021. values = real(values_int2,kind=4)
  24022. deallocate( values_int2 )
  24023. case ( DFNT_INT32 )
  24024. allocate( values_int4(hdf4_length) )
  24025. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  24026. values = real(values_int4,kind=4)
  24027. deallocate( values_int4 )
  24028. case ( DFNT_INT64 )
  24029. allocate( values_int8(hdf4_length) )
  24030. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  24031. values = real(values_int8,kind=4)
  24032. deallocate( values_int8 )
  24033. case ( DFNT_FLOAT32 )
  24034. allocate( values_real4(hdf4_length) )
  24035. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  24036. values = real(values_real4,kind=4)
  24037. deallocate( values_real4 )
  24038. case ( DFNT_FLOAT64 )
  24039. allocate( values_real8(hdf4_length) )
  24040. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  24041. values = real(values_real8,kind=4)
  24042. deallocate( values_real8 )
  24043. case default
  24044. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  24045. TRACEBACK; status=1; return
  24046. end select
  24047. if ( status /= SUCCEED ) then
  24048. write (*,'("reading attribute : ",a)') trim(name); call goErr
  24049. TRACEBACK; status=1; return
  24050. end if
  24051. #endif
  24052. #ifdef with_hdf5_beta
  24053. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24054. case ( MDF_HDF5 )
  24055. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24056. ! set variable id:
  24057. if ( varid == MDF_GLOBAL ) then
  24058. ! file id:
  24059. hdf5_loc_id = filep%hdf5_file_id
  24060. hdf5_obj_name = '.'
  24061. else
  24062. ! file id:
  24063. hdf5_loc_id = varp%hdf5_dataset_id
  24064. hdf5_obj_name = '.'
  24065. end if
  24066. ! data type:
  24067. call H5TCopy_f( H5T_NATIVE_REAL, hdf5_type_id, status )
  24068. IF_NOT_OK_RETURN(status=1)
  24069. ! open attribute:
  24070. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  24071. IF_NOT_OK_RETURN(status=1)
  24072. ! read:
  24073. call H5ARead_f( hdf5_attr_id, hdf5_type_id, values, int(shape(values),HSIZE_T), status )
  24074. IF_NOT_OK_RETURN(status=1)
  24075. ! release:
  24076. call H5TClose_f( hdf5_type_id, status )
  24077. IF_NOT_OK_RETURN(status=1)
  24078. ! release:
  24079. call H5AClose_f( hdf5_attr_id, status )
  24080. IF_NOT_OK_RETURN(status=1)
  24081. #endif
  24082. #ifdef with_netcdf
  24083. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24084. case ( MDF_NETCDF, MDF_NETCDF4 )
  24085. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24086. ! set variable id:
  24087. if ( varid == MDF_GLOBAL ) then
  24088. netcdf_varid = NF90_GLOBAL
  24089. else
  24090. netcdf_varid = varp%netcdf_varid
  24091. end if
  24092. ! read attribute:
  24093. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  24094. IF_NF90_NOT_OK_RETURN(status=1)
  24095. #endif
  24096. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24097. case default
  24098. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24099. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  24100. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  24101. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  24102. TRACEBACK; status=1; return
  24103. end select
  24104. ! ok
  24105. status = 0
  24106. end subroutine MDF_Get_Att_r4_1d
  24107. subroutine MDF_Put_Att_r8_0d( hid, varid, name, values, status )
  24108. #ifdef with_hdf5_beta
  24109. use HDF5, only : HID_T, HSIZE_T
  24110. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  24111. use HDF5, only : H5T_NATIVE_CHARACTER
  24112. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  24113. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  24114. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  24115. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  24116. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  24117. #endif
  24118. #ifdef with_netcdf
  24119. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  24120. #endif
  24121. ! --- in/out -------------------------------------
  24122. integer, intent(in) :: hid
  24123. integer, intent(in) :: varid
  24124. character(len=*), intent(in) :: name
  24125. real(8), intent(in) :: values
  24126. integer, intent(out) :: status
  24127. ! --- const --------------------------------------
  24128. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_r8_0d'
  24129. ! --- external -------------------------------
  24130. #ifdef with_hdf4
  24131. integer(hdf4_wpi), external :: sfSCAtt
  24132. integer(hdf4_wpi), external :: sfSNAtt
  24133. #endif
  24134. ! --- local --------------------------------------
  24135. type(MDF_File), pointer :: filep
  24136. type(MDF_Var), pointer :: varp
  24137. integer :: iftype
  24138. integer :: ftype
  24139. #ifdef with_hdf4
  24140. integer :: hdf4_id
  24141. #endif
  24142. #ifdef with_hdf5_beta
  24143. integer(HID_T) :: hdf5_loc_id
  24144. integer(HID_T) :: hdf5_attr_id
  24145. integer(HID_T) :: hdf5_space_id
  24146. integer(HID_T) :: hdf5_type_id
  24147. #endif
  24148. #ifdef with_netcdf
  24149. integer :: netcdf_varid
  24150. #endif
  24151. ! --- begin --------------------------------------
  24152. ! pointer to file structure:
  24153. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24154. IF_NOT_OK_RETURN(status=1)
  24155. ! global or variable attribute ?
  24156. if ( varid == MDF_GLOBAL ) then
  24157. ! increase counter:
  24158. filep%natt = filep%natt + 1
  24159. else
  24160. ! pointer to variable structure:
  24161. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  24162. IF_NOT_OK_RETURN(status=1)
  24163. ! increase counter:
  24164. varp%natt = varp%natt + 1
  24165. end if
  24166. ! loop over file types:
  24167. do iftype = 1, filep%nftype
  24168. ! current type:
  24169. ftype = filep%ftypes(iftype)
  24170. ! select appropriate routine for each type:
  24171. select case ( ftype )
  24172. #ifdef with_hdf4
  24173. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24174. case ( MDF_HDF4 )
  24175. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24176. ! set variable id:
  24177. if ( varid == MDF_GLOBAL ) then
  24178. hdf4_id = filep%hdf4_id
  24179. else
  24180. hdf4_id = varp%hdf4_sdid
  24181. end if
  24182. ! store numerical attribute:
  24183. status = sfSNAtt( hdf4_id, trim(name), DFNT_FLOAT64, 1, values )
  24184. if ( status /= SUCCEED ) then
  24185. write (*,'("writing attribute : ",a)') trim(name); call goErr
  24186. TRACEBACK; status=1; return
  24187. end if
  24188. #endif
  24189. #ifdef with_hdf5_beta
  24190. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24191. case ( MDF_HDF5 )
  24192. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24193. ! set variable id:
  24194. if ( varid == MDF_GLOBAL ) then
  24195. hdf5_loc_id = filep%hdf5_file_id
  24196. else
  24197. hdf5_loc_id = varp%hdf5_dataset_id
  24198. end if
  24199. ! data type:
  24200. call H5TCopy_f( H5T_NATIVE_DOUBLE, hdf5_type_id, status )
  24201. IF_NOT_OK_RETURN(status=1)
  24202. ! data space:
  24203. call H5SCreate_f( H5S_SCALAR_F, hdf5_space_id, status )
  24204. IF_NOT_OK_RETURN(status=1)
  24205. ! create attribute; type in file is same as type provided to this routine:
  24206. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  24207. IF_NOT_OK_RETURN(status=1)
  24208. ! write attribute values:
  24209. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_DOUBLE, values, int((/1/),kind=HSIZE_T), status )
  24210. IF_NOT_OK_RETURN(status=1)
  24211. ! release attribute:
  24212. call H5AClose_f( hdf5_attr_id, status )
  24213. IF_NOT_OK_RETURN(status=1)
  24214. ! release data space:
  24215. call H5SClose_f( hdf5_space_id, status )
  24216. IF_NOT_OK_RETURN(status=1)
  24217. ! release data type:
  24218. call H5TClose_f( hdf5_type_id, status )
  24219. IF_NOT_OK_RETURN(status=1)
  24220. #endif
  24221. #ifdef with_netcdf
  24222. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24223. case ( MDF_NETCDF, MDF_NETCDF4 )
  24224. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24225. ! set variable id:
  24226. if ( varid == MDF_GLOBAL ) then
  24227. netcdf_varid = NF90_GLOBAL
  24228. else
  24229. netcdf_varid = varp%netcdf_varid
  24230. end if
  24231. ! write attribute:
  24232. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  24233. IF_NF90_NOT_OK_RETURN(status=1)
  24234. #endif
  24235. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24236. case default
  24237. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24238. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  24239. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  24240. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  24241. TRACEBACK; status=1; return
  24242. end select
  24243. end do ! file types
  24244. ! ok
  24245. status = 0
  24246. end subroutine MDF_Put_Att_r8_0d
  24247. ! ***
  24248. subroutine MDF_Get_Att_r8_0d( hid, varid, name, values, status )
  24249. #ifdef with_hdf5_beta
  24250. use HDF5, only : HSIZE_T
  24251. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  24252. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  24253. use HDF5, only : H5T_NATIVE_CHARACTER
  24254. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  24255. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  24256. #endif
  24257. #ifdef with_netcdf
  24258. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  24259. #endif
  24260. ! --- in/out -------------------------------------
  24261. integer, intent(in) :: hid
  24262. integer, intent(in) :: varid
  24263. character(len=*), intent(in) :: name
  24264. real(8), intent(out) :: values
  24265. integer, intent(out) :: status
  24266. ! --- const --------------------------------------
  24267. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_r8_0d'
  24268. ! --- external -------------------------------
  24269. #ifdef with_hdf4
  24270. integer(hdf4_wpi), external :: sfFAttr
  24271. integer(hdf4_wpi), external :: sfGAInfo
  24272. integer(hdf4_wpi), external :: sfRCAtt
  24273. integer(hdf4_wpi), external :: sfRNAtt
  24274. #endif
  24275. ! --- local --------------------------------------
  24276. type(MDF_File), pointer :: filep
  24277. type(MDF_Var), pointer :: varp
  24278. integer :: ftype
  24279. #ifdef with_hdf4
  24280. integer :: hdf4_id
  24281. integer :: hdf4_iatt
  24282. character(len=LEN_NAME) :: hdf4_name
  24283. integer :: hdf4_xtype
  24284. integer :: hdf4_length
  24285. integer(1) :: values_int1
  24286. integer(2) :: values_int2
  24287. integer(4) :: values_int4
  24288. integer(8) :: values_int8
  24289. real(4) :: values_real4
  24290. real(8) :: values_real8
  24291. #endif
  24292. #ifdef with_hdf5_beta
  24293. integer(HID_T) :: hdf5_loc_id
  24294. character(len=LEN_NAME) :: hdf5_obj_name
  24295. integer(HID_T) :: hdf5_attr_id
  24296. integer(HID_T) :: hdf5_type_id
  24297. #endif
  24298. #ifdef with_netcdf
  24299. integer :: netcdf_varid
  24300. #endif
  24301. ! --- begin --------------------------------------
  24302. ! single type:
  24303. call MDF_Get_Type( hid, ftype, status )
  24304. IF_NOT_OK_RETURN(status=1)
  24305. ! pointer to file structure:
  24306. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24307. IF_NOT_OK_RETURN(status=1)
  24308. ! pointer to variable structure if possible:
  24309. if ( varid /= MDF_GLOBAL ) then
  24310. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  24311. IF_NOT_OK_RETURN(status=1)
  24312. end if
  24313. ! select appropriate routine for each type:
  24314. select case ( ftype )
  24315. #ifdef with_hdf4
  24316. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24317. case ( MDF_HDF4 )
  24318. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24319. ! set variable id:
  24320. if ( varid == MDF_GLOBAL ) then
  24321. hdf4_id = filep%hdf4_id
  24322. else
  24323. hdf4_id = varp%hdf4_sdid
  24324. end if
  24325. ! get attribute index given name:
  24326. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  24327. if ( hdf4_iatt == FAIL ) then
  24328. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  24329. TRACEBACK; status=1; return
  24330. end if
  24331. ! get type and length:
  24332. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  24333. if ( status /= SUCCEED ) then
  24334. write (gol,'("getting attribute info")') trim(name); call goErr
  24335. TRACEBACK; status=1; return
  24336. end if
  24337. ! read numerical attribute:
  24338. select case ( hdf4_xtype )
  24339. case ( DFNT_INT8 )
  24340. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  24341. values = real(values_int1,kind=8)
  24342. case ( DFNT_INT16 )
  24343. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  24344. values = real(values_int2,kind=8)
  24345. case ( DFNT_INT32 )
  24346. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  24347. values = real(values_int4,kind=8)
  24348. case ( DFNT_INT64 )
  24349. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  24350. values = real(values_int8,kind=8)
  24351. case ( DFNT_FLOAT32 )
  24352. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  24353. values = real(values_real4,kind=8)
  24354. case ( DFNT_FLOAT64 )
  24355. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  24356. values = real(values_real8,kind=8)
  24357. case default
  24358. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  24359. TRACEBACK; status=1; return
  24360. end select
  24361. if ( status /= SUCCEED ) then
  24362. write (*,'("reading attribute : ",a)') trim(name); call goErr
  24363. TRACEBACK; status=1; return
  24364. end if
  24365. #endif
  24366. #ifdef with_hdf5_beta
  24367. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24368. case ( MDF_HDF5 )
  24369. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24370. ! set variable id:
  24371. if ( varid == MDF_GLOBAL ) then
  24372. ! file id:
  24373. hdf5_loc_id = filep%hdf5_file_id
  24374. hdf5_obj_name = '.'
  24375. else
  24376. ! file id:
  24377. hdf5_loc_id = varp%hdf5_dataset_id
  24378. hdf5_obj_name = '.'
  24379. end if
  24380. ! data type:
  24381. call H5TCopy_f( H5T_NATIVE_DOUBLE, hdf5_type_id, status )
  24382. IF_NOT_OK_RETURN(status=1)
  24383. ! open attribute:
  24384. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  24385. IF_NOT_OK_RETURN(status=1)
  24386. ! read:
  24387. call H5ARead_f( hdf5_attr_id, hdf5_type_id, values, int((/1/),HSIZE_T), status )
  24388. IF_NOT_OK_RETURN(status=1)
  24389. ! release:
  24390. call H5TClose_f( hdf5_type_id, status )
  24391. IF_NOT_OK_RETURN(status=1)
  24392. ! release:
  24393. call H5AClose_f( hdf5_attr_id, status )
  24394. IF_NOT_OK_RETURN(status=1)
  24395. #endif
  24396. #ifdef with_netcdf
  24397. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24398. case ( MDF_NETCDF, MDF_NETCDF4 )
  24399. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24400. ! set variable id:
  24401. if ( varid == MDF_GLOBAL ) then
  24402. netcdf_varid = NF90_GLOBAL
  24403. else
  24404. netcdf_varid = varp%netcdf_varid
  24405. end if
  24406. ! read attribute:
  24407. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  24408. IF_NF90_NOT_OK_RETURN(status=1)
  24409. #endif
  24410. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24411. case default
  24412. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24413. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  24414. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  24415. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  24416. TRACEBACK; status=1; return
  24417. end select
  24418. ! ok
  24419. status = 0
  24420. end subroutine MDF_Get_Att_r8_0d
  24421. subroutine MDF_Put_Att_r8_1d( hid, varid, name, values, status )
  24422. #ifdef with_hdf5_beta
  24423. use HDF5, only : HID_T, HSIZE_T
  24424. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  24425. use HDF5, only : H5T_NATIVE_CHARACTER
  24426. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER
  24427. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  24428. use HDF5, only : H5SCreate_f, H5SClose_f, H5SSet_Extent_Simple_f
  24429. use HDF5, only : H5S_SCALAR_F, H5S_SIMPLE_F
  24430. use HDF5, only : H5ACreate_f, H5AClose_f, H5AWrite_f
  24431. #endif
  24432. #ifdef with_netcdf
  24433. use NetCDF, only : NF90_Put_Att, NF90_GLOBAL
  24434. #endif
  24435. ! --- in/out -------------------------------------
  24436. integer, intent(in) :: hid
  24437. integer, intent(in) :: varid
  24438. character(len=*), intent(in) :: name
  24439. real(8), intent(in) :: values(:)
  24440. integer, intent(out) :: status
  24441. ! --- const --------------------------------------
  24442. character(len=*), parameter :: rname = mname//'/MDF_Put_Att_r8_1d'
  24443. ! --- external -------------------------------
  24444. #ifdef with_hdf4
  24445. integer(hdf4_wpi), external :: sfSCAtt
  24446. integer(hdf4_wpi), external :: sfSNAtt
  24447. #endif
  24448. ! --- local --------------------------------------
  24449. type(MDF_File), pointer :: filep
  24450. type(MDF_Var), pointer :: varp
  24451. integer :: iftype
  24452. integer :: ftype
  24453. #ifdef with_hdf4
  24454. integer :: hdf4_id
  24455. #endif
  24456. #ifdef with_hdf5_beta
  24457. integer(HID_T) :: hdf5_loc_id
  24458. integer(HID_T) :: hdf5_attr_id
  24459. integer(HID_T) :: hdf5_space_id
  24460. integer(HID_T) :: hdf5_type_id
  24461. #endif
  24462. #ifdef with_netcdf
  24463. integer :: netcdf_varid
  24464. #endif
  24465. ! --- begin --------------------------------------
  24466. ! pointer to file structure:
  24467. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24468. IF_NOT_OK_RETURN(status=1)
  24469. ! global or variable attribute ?
  24470. if ( varid == MDF_GLOBAL ) then
  24471. ! increase counter:
  24472. filep%natt = filep%natt + 1
  24473. else
  24474. ! pointer to variable structure:
  24475. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  24476. IF_NOT_OK_RETURN(status=1)
  24477. ! increase counter:
  24478. varp%natt = varp%natt + 1
  24479. end if
  24480. ! loop over file types:
  24481. do iftype = 1, filep%nftype
  24482. ! current type:
  24483. ftype = filep%ftypes(iftype)
  24484. ! select appropriate routine for each type:
  24485. select case ( ftype )
  24486. #ifdef with_hdf4
  24487. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24488. case ( MDF_HDF4 )
  24489. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24490. ! set variable id:
  24491. if ( varid == MDF_GLOBAL ) then
  24492. hdf4_id = filep%hdf4_id
  24493. else
  24494. hdf4_id = varp%hdf4_sdid
  24495. end if
  24496. ! strore numerical attribute:
  24497. status = sfSNAtt( hdf4_id, trim(name), DFNT_FLOAT64, size(values), values )
  24498. if ( status /= SUCCEED ) then
  24499. write (*,'("writing attribute : ",a)') trim(name); call goErr
  24500. TRACEBACK; status=1; return
  24501. end if
  24502. #endif
  24503. #ifdef with_hdf5_beta
  24504. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24505. case ( MDF_HDF5 )
  24506. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24507. ! set variable id:
  24508. if ( varid == MDF_GLOBAL ) then
  24509. hdf5_loc_id = filep%hdf5_file_id
  24510. else
  24511. hdf5_loc_id = varp%hdf5_dataset_id
  24512. end if
  24513. ! data type:
  24514. call H5TCopy_f( H5T_NATIVE_DOUBLE, hdf5_type_id, status )
  24515. IF_NOT_OK_RETURN(status=1)
  24516. ! data space:
  24517. call H5SCreate_f( H5S_SIMPLE_F, hdf5_space_id, status )
  24518. IF_NOT_OK_RETURN(status=1)
  24519. ! set extent of the data space:
  24520. call H5SSet_Extent_Simple_f( hdf5_space_id, 1, int(shape(values),kind=HSIZE_T), int(shape(values),kind=HSIZE_T), status )
  24521. IF_NOT_OK_RETURN(status=1)
  24522. ! create attribute; type in file is same as type provided to this routine:
  24523. call H5ACreate_f( hdf5_loc_id, trim(name), hdf5_type_id, hdf5_space_id, hdf5_attr_id, status )
  24524. IF_NOT_OK_RETURN(status=1)
  24525. ! write attribute values:
  24526. call H5AWrite_f( hdf5_attr_id, H5T_NATIVE_DOUBLE, values, int(shape(values),kind=HSIZE_T), status )
  24527. IF_NOT_OK_RETURN(status=1)
  24528. ! release attribute:
  24529. call H5AClose_f( hdf5_attr_id, status )
  24530. IF_NOT_OK_RETURN(status=1)
  24531. ! release data space:
  24532. call H5SClose_f( hdf5_space_id, status )
  24533. IF_NOT_OK_RETURN(status=1)
  24534. ! release data type:
  24535. call H5TClose_f( hdf5_type_id, status )
  24536. IF_NOT_OK_RETURN(status=1)
  24537. #endif
  24538. #ifdef with_netcdf
  24539. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24540. case ( MDF_NETCDF, MDF_NETCDF4 )
  24541. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24542. ! set variable id:
  24543. if ( varid == MDF_GLOBAL ) then
  24544. netcdf_varid = NF90_GLOBAL
  24545. else
  24546. netcdf_varid = varp%netcdf_varid
  24547. end if
  24548. ! write attribute:
  24549. status = NF90_Put_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  24550. IF_NF90_NOT_OK_RETURN(status=1)
  24551. #endif
  24552. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24553. case default
  24554. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24555. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  24556. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  24557. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  24558. TRACEBACK; status=1; return
  24559. end select
  24560. end do ! file types
  24561. ! ok
  24562. status = 0
  24563. end subroutine MDF_Put_Att_r8_1d
  24564. ! ***
  24565. subroutine MDF_Get_Att_r8_1d( hid, varid, name, values, status )
  24566. #ifdef with_hdf5_beta
  24567. use HDF5, only : HSIZE_T
  24568. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f, H5ARead_f
  24569. use HDF5, only : H5TCopy_f, H5TSet_Size_f, H5TClose_f
  24570. use HDF5, only : H5T_NATIVE_CHARACTER
  24571. use HDF5, only : H5T_STD_I8LE, H5T_STD_I16LE, H5T_NATIVE_INTEGER, H5T_STD_I64LE
  24572. use HDF5, only : H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE
  24573. #endif
  24574. #ifdef with_netcdf
  24575. use NetCDF, only : NF90_Get_Att, NF90_GLOBAL
  24576. #endif
  24577. ! --- in/out -------------------------------------
  24578. integer, intent(in) :: hid
  24579. integer, intent(in) :: varid
  24580. character(len=*), intent(in) :: name
  24581. real(8), intent(out) :: values(:)
  24582. integer, intent(out) :: status
  24583. ! --- const --------------------------------------
  24584. character(len=*), parameter :: rname = mname//'/MDF_Get_Att_r8_1d'
  24585. ! --- external -------------------------------
  24586. #ifdef with_hdf4
  24587. integer(hdf4_wpi), external :: sfFAttr
  24588. integer(hdf4_wpi), external :: sfGAInfo
  24589. integer(hdf4_wpi), external :: sfRCAtt
  24590. integer(hdf4_wpi), external :: sfRNAtt
  24591. #endif
  24592. ! --- local --------------------------------------
  24593. type(MDF_File), pointer :: filep
  24594. type(MDF_Var), pointer :: varp
  24595. integer :: ftype
  24596. #ifdef with_hdf4
  24597. integer :: hdf4_id
  24598. integer :: hdf4_iatt
  24599. character(len=LEN_NAME) :: hdf4_name
  24600. integer :: hdf4_xtype
  24601. integer :: hdf4_length
  24602. integer(1), allocatable :: values_int1(:)
  24603. integer(2), allocatable :: values_int2(:)
  24604. integer(4), allocatable :: values_int4(:)
  24605. integer(8), allocatable :: values_int8(:)
  24606. real(4), allocatable :: values_real4(:)
  24607. real(8), allocatable :: values_real8(:)
  24608. #endif
  24609. #ifdef with_hdf5_beta
  24610. integer(HID_T) :: hdf5_loc_id
  24611. character(len=LEN_NAME) :: hdf5_obj_name
  24612. integer(HID_T) :: hdf5_attr_id
  24613. integer(HID_T) :: hdf5_type_id
  24614. #endif
  24615. #ifdef with_netcdf
  24616. integer :: netcdf_varid
  24617. #endif
  24618. ! --- begin --------------------------------------
  24619. ! single type:
  24620. call MDF_Get_Type( hid, ftype, status )
  24621. IF_NOT_OK_RETURN(status=1)
  24622. ! pointer to file structure:
  24623. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24624. IF_NOT_OK_RETURN(status=1)
  24625. ! pointer to variable structure if possible:
  24626. if ( varid /= MDF_GLOBAL ) then
  24627. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  24628. IF_NOT_OK_RETURN(status=1)
  24629. end if
  24630. ! select appropriate routine for each type:
  24631. select case ( ftype )
  24632. #ifdef with_hdf4
  24633. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24634. case ( MDF_HDF4 )
  24635. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24636. ! set variable id:
  24637. if ( varid == MDF_GLOBAL ) then
  24638. hdf4_id = filep%hdf4_id
  24639. else
  24640. hdf4_id = varp%hdf4_sdid
  24641. end if
  24642. ! get attribute index given name:
  24643. hdf4_iatt = sfFAttr( hdf4_id , trim(name) )
  24644. if ( hdf4_iatt == FAIL ) then
  24645. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  24646. TRACEBACK; status=1; return
  24647. end if
  24648. ! get type and length:
  24649. status = sfGAInfo( hdf4_id, hdf4_iatt, hdf4_name, hdf4_xtype, hdf4_length )
  24650. if ( status /= SUCCEED ) then
  24651. write (gol,'("getting attribute info")') trim(name); call goErr
  24652. TRACEBACK; status=1; return
  24653. end if
  24654. ! read numerical attribute:
  24655. select case ( hdf4_xtype )
  24656. case ( DFNT_INT8 )
  24657. allocate( values_int1(hdf4_length) )
  24658. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int1 )
  24659. values = real(values_int1,kind=8)
  24660. deallocate( values_int1 )
  24661. case ( DFNT_INT16 )
  24662. allocate( values_int2(hdf4_length) )
  24663. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int2 )
  24664. values = real(values_int2,kind=8)
  24665. deallocate( values_int2 )
  24666. case ( DFNT_INT32 )
  24667. allocate( values_int4(hdf4_length) )
  24668. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int4 )
  24669. values = real(values_int4,kind=8)
  24670. deallocate( values_int4 )
  24671. case ( DFNT_INT64 )
  24672. allocate( values_int8(hdf4_length) )
  24673. status = sfRNAtt( hdf4_id, hdf4_iatt, values_int8 )
  24674. values = real(values_int8,kind=8)
  24675. deallocate( values_int8 )
  24676. case ( DFNT_FLOAT32 )
  24677. allocate( values_real4(hdf4_length) )
  24678. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real4 )
  24679. values = real(values_real4,kind=8)
  24680. deallocate( values_real4 )
  24681. case ( DFNT_FLOAT64 )
  24682. allocate( values_real8(hdf4_length) )
  24683. status = sfRNAtt( hdf4_id, hdf4_iatt, values_real8 )
  24684. values = real(values_real8,kind=8)
  24685. deallocate( values_real8 )
  24686. case default
  24687. write (gol,'("not implemented for hdf4 data type ",i6)') hdf4_xtype
  24688. TRACEBACK; status=1; return
  24689. end select
  24690. if ( status /= SUCCEED ) then
  24691. write (*,'("reading attribute : ",a)') trim(name); call goErr
  24692. TRACEBACK; status=1; return
  24693. end if
  24694. #endif
  24695. #ifdef with_hdf5_beta
  24696. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24697. case ( MDF_HDF5 )
  24698. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24699. ! set variable id:
  24700. if ( varid == MDF_GLOBAL ) then
  24701. ! file id:
  24702. hdf5_loc_id = filep%hdf5_file_id
  24703. hdf5_obj_name = '.'
  24704. else
  24705. ! file id:
  24706. hdf5_loc_id = varp%hdf5_dataset_id
  24707. hdf5_obj_name = '.'
  24708. end if
  24709. ! data type:
  24710. call H5TCopy_f( H5T_NATIVE_DOUBLE, hdf5_type_id, status )
  24711. IF_NOT_OK_RETURN(status=1)
  24712. ! open attribute:
  24713. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  24714. IF_NOT_OK_RETURN(status=1)
  24715. ! read:
  24716. call H5ARead_f( hdf5_attr_id, hdf5_type_id, values, int(shape(values),HSIZE_T), status )
  24717. IF_NOT_OK_RETURN(status=1)
  24718. ! release:
  24719. call H5TClose_f( hdf5_type_id, status )
  24720. IF_NOT_OK_RETURN(status=1)
  24721. ! release:
  24722. call H5AClose_f( hdf5_attr_id, status )
  24723. IF_NOT_OK_RETURN(status=1)
  24724. #endif
  24725. #ifdef with_netcdf
  24726. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24727. case ( MDF_NETCDF, MDF_NETCDF4 )
  24728. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24729. ! set variable id:
  24730. if ( varid == MDF_GLOBAL ) then
  24731. netcdf_varid = NF90_GLOBAL
  24732. else
  24733. netcdf_varid = varp%netcdf_varid
  24734. end if
  24735. ! read attribute:
  24736. status = NF90_Get_Att( filep%netcdf_id, netcdf_varid, trim(name), values )
  24737. IF_NF90_NOT_OK_RETURN(status=1)
  24738. #endif
  24739. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24740. case default
  24741. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  24742. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  24743. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  24744. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  24745. TRACEBACK; status=1; return
  24746. end select
  24747. ! ok
  24748. status = 0
  24749. end subroutine MDF_Get_Att_r8_1d
  24750. ! ********************************************************************
  24751. ! ***
  24752. ! *** inquire
  24753. ! ***
  24754. ! ********************************************************************
  24755. subroutine MDF_Get_Type( hid, ftype, status )
  24756. ! --- in/out -------------------------------------
  24757. integer, intent(in) :: hid
  24758. integer, intent(out) :: ftype
  24759. integer, intent(out) :: status
  24760. ! --- const --------------------------------------
  24761. character(len=*), parameter :: rname = mname//'/MDF_Get_Type'
  24762. ! --- local --------------------------------------
  24763. type(MDF_File), pointer :: filep
  24764. integer :: iftype
  24765. ! --- begin --------------------------------------
  24766. ! pointer to file structure:
  24767. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24768. IF_NOT_OK_RETURN(status=1)
  24769. ! check ...
  24770. if ( filep%nftype /= 1 ) then
  24771. write (gol,'("mdf file not defined for single type but for ",i6," ...")') filep%nftype; call goErr
  24772. do iftype = 1, filep%nftype
  24773. select case ( filep%ftypes(iftype) )
  24774. #ifdef with_hdf4
  24775. case ( MDF_HDF4 )
  24776. write (gol,'(" hdf4 file : ",a)') trim(filep%hdf4_fname); call goErr
  24777. #endif
  24778. #ifdef with_netcdf
  24779. case ( MDF_NETCDF, MDF_NETCDF4 )
  24780. write (gol,'(" netcdf file : ",a)') trim(filep%netcdf_fname); call goErr
  24781. #endif
  24782. case default
  24783. write (gol,'(" (unsupported type)")'); call goErr
  24784. end select
  24785. end do
  24786. TRACEBACK; status=1; return
  24787. end if
  24788. ! return single type:
  24789. ftype = filep%ftypes(1)
  24790. ! ok
  24791. status = 0
  24792. end subroutine MDF_Get_Type
  24793. ! ***
  24794. subroutine MDF_Inquire( hid, status, &
  24795. nDimensions, nVariables, nAttributes )
  24796. ! --- in/out -------------------------------------
  24797. integer, intent(in) :: hid
  24798. integer, intent(out) :: status
  24799. integer, intent(out), optional :: nDimensions
  24800. integer, intent(out), optional :: nVariables
  24801. integer, intent(out), optional :: nAttributes
  24802. ! --- const --------------------------------------
  24803. character(len=*), parameter :: rname = mname//'/MDF_Inquire'
  24804. ! --- local --------------------------------------
  24805. type(MDF_File), pointer :: filep
  24806. ! --- begin --------------------------------------
  24807. ! pointer to file structure:
  24808. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24809. IF_NOT_OK_RETURN(status=1)
  24810. ! return number of dimensions ?
  24811. if ( present(nDimensions) ) then
  24812. ! get number of elements in list:
  24813. call MDF_Dim_List_Inquire( filep%Dim_List, status, n=nDimensions )
  24814. IF_NOT_OK_RETURN(status=1)
  24815. end if
  24816. ! return number of variables ?
  24817. if ( present(nVariables) ) then
  24818. ! get number of elements in list:
  24819. call MDF_Var_List_Inquire( filep%Var_List, status, n=nVariables )
  24820. IF_NOT_OK_RETURN(status=1)
  24821. end if
  24822. ! return number of global attributes ?
  24823. if ( present(nAttributes) ) then
  24824. ! copy from structure:
  24825. nAttributes = filep%natt
  24826. end if
  24827. ! ok
  24828. status = 0
  24829. end subroutine MDF_Inquire
  24830. ! ***
  24831. subroutine MDF_Inq_DimID( hid, name, dimid, status )
  24832. ! --- in/out -------------------------------------
  24833. integer, intent(in) :: hid
  24834. character(len=*), intent(in) :: name
  24835. integer, intent(out) :: dimid
  24836. integer, intent(out) :: status
  24837. ! --- const --------------------------------------
  24838. character(len=*), parameter :: rname = mname//'/MDF_Inq_DimID'
  24839. ! --- local --------------------------------------
  24840. type(MDF_File), pointer :: filep
  24841. integer :: ndim, idim
  24842. character(len=LEN_NAME) :: dimname
  24843. ! --- begin --------------------------------------
  24844. ! pointer to file structure:
  24845. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24846. IF_NOT_OK_RETURN(status=1)
  24847. ! dummy ...
  24848. dimid = -1
  24849. ! number of variables:
  24850. call MDF_Inquire( hid, status, ndimensions=ndim )
  24851. IF_NOT_OK_RETURN(status=1)
  24852. ! list variables ?
  24853. if ( ndim > 0 ) then
  24854. ! loop over variables:
  24855. do idim = 1, ndim
  24856. ! get name:
  24857. call MDF_Inquire_Dimension( hid, idim, status, name=dimname )
  24858. IF_NOT_OK_RETURN(status=1)
  24859. ! similar ?
  24860. if ( trim(name) == trim(dimname) ) then
  24861. ! store current id:
  24862. dimid = idim
  24863. ! leave:
  24864. exit
  24865. end if
  24866. end do ! variables
  24867. end if
  24868. ! check ...
  24869. if ( dimid < 0 ) then
  24870. write (gol,'("no dimension `",a,"` found in file : ",a)') trim(name), trim(filep%filename); call goErr
  24871. TRACEBACK; status=1; return
  24872. end if
  24873. ! ok
  24874. status = 0
  24875. end subroutine MDF_Inq_DimID
  24876. ! ***
  24877. subroutine MDF_Inquire_Dimension( hid, dimid, status, name, length, unlimited, named )
  24878. ! --- in/out -------------------------------------
  24879. integer, intent(in) :: hid
  24880. integer, intent(in) :: dimid
  24881. integer, intent(out) :: status
  24882. character(len=*), intent(out), optional :: name
  24883. integer, intent(out), optional :: length
  24884. logical, intent(out), optional :: unlimited
  24885. logical, intent(out), optional :: named
  24886. ! --- const --------------------------------------
  24887. character(len=*), parameter :: rname = mname//'/MDF_Inquire_Dimension'
  24888. ! --- local --------------------------------------
  24889. type(MDF_File), pointer :: filep
  24890. type(MDF_Dim), pointer :: dimp
  24891. ! --- begin --------------------------------------
  24892. ! pointer to file structure:
  24893. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24894. IF_NOT_OK_RETURN(status=1)
  24895. ! pointer to dimension structure:
  24896. call MDF_Dim_List_Get_Pointer( filep%Dim_List, dimid, dimp, status )
  24897. IF_NOT_OK_RETURN(status=1)
  24898. ! return value ?
  24899. if ( present(name ) ) name = trim(dimp%name)
  24900. if ( present(length ) ) length = dimp%length
  24901. if ( present(unlimited) ) unlimited = dimp%unlimited
  24902. if ( present(named ) ) named = dimp%named
  24903. ! ok
  24904. status = 0
  24905. end subroutine MDF_Inquire_Dimension
  24906. ! ***
  24907. subroutine MDF_Inq_VarID( hid, name, varid, status )
  24908. ! --- in/out -------------------------------------
  24909. integer, intent(in) :: hid
  24910. character(len=*), intent(in) :: name
  24911. integer, intent(out) :: varid
  24912. integer, intent(out) :: status
  24913. ! --- const --------------------------------------
  24914. character(len=*), parameter :: rname = mname//'/MDF_Inq_VarID'
  24915. ! --- local --------------------------------------
  24916. type(MDF_File), pointer :: filep
  24917. integer :: nvar, ivar
  24918. character(len=LEN_NAME) :: varname
  24919. ! --- begin --------------------------------------
  24920. ! pointer to file structure:
  24921. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24922. IF_NOT_OK_RETURN(status=1)
  24923. ! dummy ...
  24924. varid = -1
  24925. ! number of variables:
  24926. call MDF_Inquire( hid, status, nVariables=nvar )
  24927. IF_NOT_OK_RETURN(status=1)
  24928. ! list variables ?
  24929. if ( nvar > 0 ) then
  24930. ! loop over variables:
  24931. do ivar = 1, nvar
  24932. ! get name:
  24933. call MDF_Inquire_Variable( hid, ivar, status, name=varname )
  24934. IF_NOT_OK_RETURN(status=1)
  24935. ! similar ?
  24936. if ( trim(name) == trim(varname) ) then
  24937. ! store current id:
  24938. varid = ivar
  24939. ! leave:
  24940. exit
  24941. end if
  24942. end do ! variables
  24943. end if
  24944. ! check ...
  24945. if ( varid < 0 ) then
  24946. write (gol,'("no variable `",a,"` found in file : ",a)') trim(name), trim(filep%filename); call goErr
  24947. TRACEBACK; status=varid; return
  24948. end if
  24949. ! ok
  24950. status = 0
  24951. end subroutine MDF_Inq_VarID
  24952. ! ***
  24953. subroutine MDF_Inquire_Variable( hid, varid, status, &
  24954. name, xtype, ndims, dimids, natts, &
  24955. shp )
  24956. ! --- in/out -------------------------------------
  24957. integer, intent(in) :: hid
  24958. integer, intent(in) :: varid
  24959. integer, intent(out) :: status
  24960. character(len=*), intent(out), optional :: name
  24961. integer, intent(out), optional :: xtype
  24962. integer, intent(out), optional :: ndims
  24963. integer, intent(out), optional :: dimids(:)
  24964. integer, intent(out), optional :: natts
  24965. integer, intent(out), optional :: shp(:)
  24966. ! --- const --------------------------------------
  24967. character(len=*), parameter :: rname = mname//'/MDF_Inquire_Variable'
  24968. ! --- local --------------------------------------
  24969. integer :: ftype
  24970. type(MDF_File), pointer :: filep
  24971. type(MDF_Var), pointer :: varp
  24972. ! --- begin --------------------------------------
  24973. ! single type:
  24974. call MDF_Get_Type( hid, ftype, status )
  24975. IF_NOT_OK_RETURN(status=1)
  24976. ! pointer to file structure:
  24977. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  24978. IF_NOT_OK_RETURN(status=1)
  24979. ! pointer to variable structure:
  24980. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  24981. IF_NOT_OK_RETURN(status=1)
  24982. ! return value ?
  24983. if ( present(name ) ) name = trim(varp%name)
  24984. if ( present(xtype ) ) xtype = varp%xtype
  24985. if ( present(ndims ) ) ndims = varp%ndim
  24986. if ( present(dimids ) ) then
  24987. if ( size(dimids) /= varp%ndim ) then
  24988. write (gol,'("size of dimension id array (",i6,") should equal number of dimensions (",i6,")")') size(dimids), varp%ndim; call goErr
  24989. TRACEBACK; status=1; return
  24990. end if
  24991. dimids = varp%dimids(1:varp%ndim)
  24992. end if
  24993. if ( present(natts) ) then
  24994. natts = varp%natt
  24995. end if
  24996. ! special:
  24997. if ( present(shp) ) then
  24998. if ( size(shp) /= varp%ndim ) then
  24999. write (gol,'("size of shape array (",i6,") should equal number of dimensions (",i6,")")') size(shp), varp%ndim; call goErr
  25000. TRACEBACK; status=1; return
  25001. end if
  25002. shp = varp%shp(1:varp%ndim)
  25003. end if
  25004. ! ok
  25005. status = 0
  25006. end subroutine MDF_Inquire_Variable
  25007. ! ***
  25008. subroutine MDF_Inquire_Attribute( hid, varid, name, status, xtype, length )
  25009. #ifdef with_hdf5_beta
  25010. use HDF5, only : HSIZE_T
  25011. use HDF5, only : H5AOpen_By_Name_f, H5AClose_f
  25012. use HDF5, only : H5AGet_Type_f
  25013. use HDF5, only : H5TGet_Native_Type_f, H5TClose_f
  25014. use HDF5, only : H5T_DIR_ASCEND_F
  25015. use HDF5, only : H5AGet_Space_f
  25016. use HDF5, only : H5SGet_Simple_Extent_Dims_f, H5SClose_f
  25017. #endif
  25018. #ifdef with_netcdf
  25019. use NetCDF, only : NF90_Inquire_Attribute
  25020. use NetCDF, only : NF90_GLOBAL
  25021. use NetCDF, only : NF90_CHAR, NF90_BYTE, NF90_SHORT, NF90_INT, NF90_FLOAT, NF90_DOUBLE
  25022. #endif
  25023. ! --- in/out -------------------------------------
  25024. integer, intent(in) :: hid
  25025. integer, intent(in) :: varid
  25026. character(len=*), intent(in) :: name
  25027. integer, intent(out) :: status
  25028. integer, intent(out), optional :: xtype
  25029. integer, intent(out), optional :: length
  25030. ! --- const --------------------------------------
  25031. character(len=*), parameter :: rname = mname//'/MDF_Inquire_Attribute'
  25032. ! --- external -------------------------------
  25033. #ifdef with_hdf4
  25034. integer(hdf4_wpi), external :: sfFAttr
  25035. integer(hdf4_wpi), external :: sfGAInfo
  25036. #endif
  25037. ! --- local --------------------------------------
  25038. integer :: ftype
  25039. type(MDF_File), pointer :: filep
  25040. type(MDF_Var), pointer :: varp
  25041. #ifdef with_hdf4
  25042. integer :: hdf4_id
  25043. integer :: hdf4_attind
  25044. character(len=LEN_NAME) :: hdf4_name
  25045. integer :: hdf4_xtype
  25046. #endif
  25047. #ifdef with_hdf5_beta
  25048. integer(HID_T) :: hdf5_loc_id
  25049. character(len=LEN_NAME) :: hdf5_obj_name
  25050. integer(HID_T) :: hdf5_attr_id
  25051. integer(HID_T) :: hdf5_type_id
  25052. integer(HID_T) :: hdf5_space_id
  25053. integer(HSIZE_T) :: hdf5_dims(MAX_RANK)
  25054. integer(HSIZE_T) :: hdf5_maxdims(MAX_RANK)
  25055. integer :: hdf5_rank
  25056. #endif
  25057. #ifdef with_netcdf
  25058. integer :: netcdf_id
  25059. #endif
  25060. ! --- begin --------------------------------------
  25061. ! single type:
  25062. call MDF_Get_Type( hid, ftype, status )
  25063. IF_NOT_OK_RETURN(status=1)
  25064. ! pointer to file structure:
  25065. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  25066. IF_NOT_OK_RETURN(status=1)
  25067. ! select appropriate routine:
  25068. select case ( ftype )
  25069. #ifdef with_hdf4
  25070. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25071. case ( MDF_HDF4 )
  25072. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25073. ! global or variable attribute ?
  25074. if ( varid == MDF_GLOBAL ) then
  25075. ! file id:
  25076. hdf4_id = filep%hdf4_id
  25077. else
  25078. ! pointer to variable structure:
  25079. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  25080. IF_NOT_OK_RETURN(status=1)
  25081. ! variable id:
  25082. hdf4_id = varp%hdf4_sdid
  25083. end if
  25084. ! get attribute number given name:
  25085. hdf4_attind = sfFAttr( hdf4_id, trim(name) )
  25086. if ( hdf4_attind == FAIL ) then
  25087. write (gol,'("finding attribute `",a,"`")') trim(name); call goErr
  25088. TRACEBACK; status=1; return
  25089. status=-1; return
  25090. end if
  25091. ! extract info:
  25092. status = sfGAInfo( hdf4_id, hdf4_attind, hdf4_name, hdf4_xtype, length )
  25093. if ( status /= SUCCEED ) then
  25094. write (gol,'("getting attribute info:")'); call goErr
  25095. write (gol,'(" hdf4 file : ",a)') trim(filep%hdf4_fname); call goErr
  25096. if ( varid /= MDF_GLOBAL ) then
  25097. write (gol,'(" variable name : ",a)') trim(varp%name); call goErr
  25098. end if
  25099. write (gol,'(" hdf4 attribute index : ",i6)') hdf4_attind; call goErr
  25100. TRACEBACK; status=1; return
  25101. end if
  25102. ! return type ?
  25103. if ( present(xtype) ) then
  25104. ! convert:
  25105. select case ( hdf4_xtype )
  25106. case ( DFNT_CHAR ) ; xtype = MDF_CHAR
  25107. case ( DFNT_INT8 ) ; xtype = MDF_BYTE
  25108. case ( DFNT_INT16 ) ; xtype = MDF_SHORT
  25109. case ( DFNT_INT32 ) ; xtype = MDF_INT
  25110. case ( DFNT_FLOAT32 ) ; xtype = MDF_FLOAT
  25111. case ( DFNT_FLOAT64 ) ; xtype = MDF_DOUBLE
  25112. case default
  25113. write (gol,'("unsupported data type : ",i6)') hdf4_xtype; call goErr
  25114. TRACEBACK; status=1; return
  25115. end select
  25116. end if
  25117. #endif
  25118. #ifdef with_hdf5_beta
  25119. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25120. case ( MDF_HDF5 )
  25121. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25122. ! global or variable attribute ?
  25123. if ( varid == MDF_GLOBAL ) then
  25124. ! file id:
  25125. hdf5_loc_id = filep%hdf5_file_id
  25126. hdf5_obj_name = '.'
  25127. else
  25128. ! pointer to variable structure:
  25129. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  25130. IF_NOT_OK_RETURN(status=1)
  25131. ! dataset id:
  25132. hdf5_loc_id = varp%hdf5_dataset_id
  25133. hdf5_obj_name = '.'
  25134. end if
  25135. ! open attribute:
  25136. call H5AOpen_By_Name_f( hdf5_loc_id, hdf5_obj_name, trim(name), hdf5_attr_id, status )
  25137. IF_NOT_OK_RETURN(status=1)
  25138. ! get type ?
  25139. if ( present(xtype) ) then
  25140. ! get data type id:
  25141. call H5AGet_Type_f( hdf5_attr_id, hdf5_type_id, status )
  25142. IF_NOT_OK_RETURN(status=1)
  25143. ! convert to mdf type code:
  25144. call HDF5_Get_MDF_Type( hdf5_type_id, xtype, status )
  25145. IF_NOT_OK_RETURN(status=1)
  25146. ! release:
  25147. call H5TClose_f( hdf5_type_id, status )
  25148. IF_NOT_OK_RETURN(status=1)
  25149. end if
  25150. ! return length ?
  25151. if ( present(length) ) then
  25152. ! get data space id:
  25153. call H5AGet_Space_f( hdf5_attr_id, hdf5_space_id, status )
  25154. IF_NOT_OK_RETURN(status=1)
  25155. ! get dimensions:
  25156. call H5SGet_Simple_Extent_Dims_f( hdf5_space_id, hdf5_dims, hdf5_maxdims, status )
  25157. if ( status < 0 ) then
  25158. write (gol,'("could not extract dimensions for attribute : ",a)') trim(name); call goErr
  25159. TRACEBACK; status=1; return
  25160. else
  25161. hdf5_rank = status
  25162. end if
  25163. ! extract length:
  25164. if ( hdf5_rank == 0 ) then
  25165. length = 1 ! scalar
  25166. else if ( hdf5_rank == 1 ) then
  25167. length = hdf5_dims(1) ! 1d array
  25168. else
  25169. write (gol,'("hdf5 attributes not supported for rank ",i6)') hdf5_rank; call goErr
  25170. TRACEBACK; status=1; return
  25171. endif
  25172. ! release:
  25173. call H5SClose_f( hdf5_space_id, status )
  25174. IF_NOT_OK_RETURN(status=1)
  25175. end if
  25176. ! release:
  25177. call H5AClose_f( hdf5_attr_id, status )
  25178. IF_NOT_OK_RETURN(status=1)
  25179. #endif
  25180. #ifdef with_netcdf
  25181. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25182. case ( MDF_NETCDF, MDF_NETCDF4 )
  25183. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25184. ! global or variable attribute ?
  25185. if ( varid == MDF_GLOBAL ) then
  25186. ! file id:
  25187. netcdf_id = NF90_GLOBAL
  25188. else
  25189. ! pointer to variable structure:
  25190. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  25191. IF_NOT_OK_RETURN(status=1)
  25192. ! variable id:
  25193. netcdf_id = varp%netcdf_varid
  25194. end if
  25195. ! get type etc:
  25196. status = NF90_Inquire_Attribute( filep%netcdf_id, netcdf_id, trim(name), &
  25197. xtype=xtype, len=length )
  25198. IF_NF90_NOT_OK_RETURN(status=1)
  25199. ! return type ?
  25200. if ( present(xtype) ) then
  25201. ! convert:
  25202. select case ( xtype )
  25203. case ( NF90_CHAR ) ; xtype = MDF_CHAR
  25204. case ( NF90_BYTE ) ; xtype = MDF_BYTE
  25205. case ( NF90_SHORT ) ; xtype = MDF_SHORT
  25206. case ( NF90_INT ) ; xtype = MDF_INT
  25207. case ( NF90_FLOAT ) ; xtype = MDF_FLOAT
  25208. case ( NF90_DOUBLE ) ; xtype = MDF_DOUBLE
  25209. case default
  25210. write (gol,'("unsupported data type : ",i6)') xtype; call goErr
  25211. TRACEBACK; status=1; return
  25212. end select
  25213. end if
  25214. #endif
  25215. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25216. case default
  25217. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25218. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  25219. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  25220. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  25221. TRACEBACK; status=1; return
  25222. end select
  25223. ! ok
  25224. status = 0
  25225. end subroutine MDF_Inquire_Attribute
  25226. ! ***
  25227. subroutine MDF_Inq_AttName( hid, varid, attnum, name, status )
  25228. #ifdef with_hdf5_beta
  25229. use HDF5, only : HSIZE_T
  25230. use HDF5, only : H5AGet_Name_By_Idx_f
  25231. use HDF5, only : H5_INDEX_CRT_ORDER_F, H5_ITER_NATIVE_F
  25232. #endif
  25233. #ifdef with_netcdf
  25234. use NetCDF, only : NF90_Inq_AttName, NF90_GLOBAL
  25235. #endif
  25236. ! --- in/out -------------------------------------
  25237. integer, intent(in) :: hid
  25238. integer, intent(in) :: varid
  25239. integer, intent(in) :: attnum ! 1,..,natt
  25240. character(len=*), intent(out) :: name
  25241. integer, intent(out) :: status
  25242. ! --- const --------------------------------------
  25243. character(len=*), parameter :: rname = mname//'/MDF_Inq_AttName'
  25244. ! --- external -------------------------------
  25245. #ifdef with_hdf4
  25246. integer(hdf4_wpi), external :: sfGAInfo
  25247. #endif
  25248. ! --- local --------------------------------------
  25249. integer :: ftype
  25250. type(MDF_File), pointer :: filep
  25251. type(MDF_Var), pointer :: varp
  25252. #ifdef with_hdf4
  25253. integer :: hdf4_xtype
  25254. integer :: hdf4_length
  25255. #endif
  25256. #ifdef with_hdf5_beta
  25257. integer(HSIZE_T) :: hdf5_idx
  25258. #endif
  25259. ! --- begin --------------------------------------
  25260. ! single type:
  25261. call MDF_Get_Type( hid, ftype, status )
  25262. IF_NOT_OK_RETURN(status=1)
  25263. ! pointer to file structure:
  25264. call MDF_File_List_Get_Pointer( File_List, hid, filep, status )
  25265. IF_NOT_OK_RETURN(status=1)
  25266. ! global attribute ?
  25267. if ( varid == MDF_GLOBAL ) then
  25268. ! select appropriate routine:
  25269. select case ( ftype )
  25270. #ifdef with_hdf4
  25271. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25272. case ( MDF_HDF4 )
  25273. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25274. ! extract info:
  25275. status = sfGAInfo( filep%hdf4_id, attnum-1, name, hdf4_xtype, hdf4_length )
  25276. if ( status /= SUCCEED ) then
  25277. write (gol,'("getting attribute info:")'); call goErr
  25278. write (gol,'(" hdf4 file : ",a)') trim(filep%hdf4_fname); call goErr
  25279. write (gol,'(" attribute number : ",i6)') attnum; call goErr
  25280. TRACEBACK; status=1; return
  25281. end if
  25282. #endif
  25283. #ifdef with_hdf5_beta
  25284. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25285. case ( MDF_HDF5 )
  25286. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25287. ! open attribute:
  25288. call H5AGet_Name_By_Idx_f( filep%hdf5_file_id, '.', &
  25289. H5_INDEX_CRT_ORDER_F, H5_ITER_NATIVE_F, int(attnum-1,HSIZE_T), &
  25290. name, status )
  25291. IF_NOT_OK_RETURN(status=1)
  25292. #endif
  25293. #ifdef with_netcdf
  25294. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25295. case ( MDF_NETCDF, MDF_NETCDF4 )
  25296. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25297. ! get name:
  25298. status = NF90_Inq_AttName( filep%netcdf_id, NF90_GLOBAL, attnum, name )
  25299. IF_NF90_NOT_OK_RETURN(status=1)
  25300. #endif
  25301. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25302. case default
  25303. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25304. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  25305. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  25306. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  25307. TRACEBACK; status=1; return
  25308. end select
  25309. else ! variable attribute
  25310. ! pointer to variable structure:
  25311. call MDF_Var_List_Get_Pointer( filep%Var_List, varid, varp, status )
  25312. IF_NOT_OK_RETURN(status=1)
  25313. ! select appropriate routine:
  25314. select case ( ftype )
  25315. #ifdef with_hdf4
  25316. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25317. case ( MDF_HDF4 )
  25318. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25319. ! extract info:
  25320. status = sfGAInfo( varp%hdf4_sdid, attnum-1, name, hdf4_xtype, hdf4_length )
  25321. if ( status /= SUCCEED ) then
  25322. write (gol,'("getting attribute info:")'); call goErr
  25323. write (gol,'(" hdf4 file : ",a)') trim(filep%hdf4_fname); call goErr
  25324. write (gol,'(" variable name : ",a)') trim(varp%name); call goErr
  25325. write (gol,'(" attribute number : ",i6)') attnum; call goErr
  25326. TRACEBACK; status=1; return
  25327. end if
  25328. #endif
  25329. #ifdef with_hdf5_beta
  25330. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25331. case ( MDF_HDF5 )
  25332. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25333. ! index number:
  25334. hdf5_idx = attnum-1
  25335. ! open attribute:
  25336. call H5AGet_Name_By_Idx_f( varp%hdf5_dataset_id, '.', &
  25337. H5_INDEX_CRT_ORDER_F, H5_ITER_NATIVE_F, hdf5_idx, &
  25338. name, status )
  25339. IF_NOT_OK_RETURN(status=1)
  25340. #endif
  25341. #ifdef with_netcdf
  25342. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25343. case ( MDF_NETCDF, MDF_NETCDF4 )
  25344. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25345. ! get name:
  25346. status = NF90_Inq_AttName( filep%netcdf_id, varp%netcdf_varid, attnum, name )
  25347. IF_NF90_NOT_OK_RETURN(status=1)
  25348. #endif
  25349. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25350. case default
  25351. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
  25352. write (gol,'("unsupported filetype : ",i6)') ftype; call goErr
  25353. write (gol,'(" filetype name : ",a)') trim(MDF_FILETYPE_NAME(ftype)); call goErr
  25354. write (gol,'(" compiled without macro `with_*` defined ?")'); call goErr
  25355. TRACEBACK; status=1; return
  25356. end select
  25357. end if ! global or variable attribute
  25358. ! ok
  25359. status = 0
  25360. end subroutine MDF_Inq_AttName
  25361. ! ********************************************************************
  25362. ! ***
  25363. ! *** show content
  25364. ! ***
  25365. ! ********************************************************************
  25366. subroutine MDF_Show( filename, status, filetype, show_data )
  25367. ! --- in/out -------------------------------------
  25368. character(len=*), intent(in) :: filename
  25369. integer, intent(out) :: status
  25370. integer, intent(in), optional :: filetype
  25371. logical, intent(in), optional :: show_data
  25372. ! --- const --------------------------------------
  25373. character(len=*), parameter :: rname = mname//'/MDF_Show'
  25374. ! --- local --------------------------------------
  25375. integer :: l
  25376. integer :: ftype
  25377. logical :: do_show_data
  25378. integer :: hid
  25379. integer :: ndim, idim
  25380. integer :: nvar, ivar
  25381. integer :: natt
  25382. logical :: named
  25383. character(len=LEN_NAME) :: ftype_name
  25384. character(len=LEN_NAME) :: name
  25385. integer :: length
  25386. logical :: unlimited
  25387. logical :: isfirst
  25388. integer :: xtype
  25389. integer :: dimids(MAX_RANK)
  25390. integer :: shp(MAX_RANK)
  25391. character(len=LEN_LINE) :: line
  25392. character(len=LEN_NAME) :: val
  25393. ! --- begin --------------------------------------
  25394. ! show data ?
  25395. do_show_data = .false.
  25396. if ( present(show_data) ) do_show_data = show_data
  25397. ! guess file type by default, or set to optional argument:
  25398. ftype = MDF_NONE
  25399. if ( present(filetype) ) ftype = filetype
  25400. ! guess file type ?
  25401. if ( ftype == MDF_NONE ) then
  25402. ! length of filename:
  25403. l = len_trim(filename)
  25404. ! guess ...
  25405. if ( (l > 3) .and. (filename(l-2:l) == '.nc') ) then
  25406. ftype = MDF_NETCDF
  25407. else if ( (l > 3) .and. (filename(l-2:l) == '.h5') ) then
  25408. ftype = MDF_HDF5
  25409. else if ( (l > 4) .and. (filename(l-3:l) == '.hdf') ) then
  25410. ftype = MDF_HDF4
  25411. else
  25412. write (gol,'("could not guess file type from file name:")'); call goErr
  25413. write (gol,'(" ",a)') trim(filename); call goErr
  25414. TRACEBACK; status=1; return
  25415. end if
  25416. end if
  25417. ! filetype name:
  25418. ftype_name = trim(MDF_FILETYPE_NAME(ftype))
  25419. #ifdef with_netcdf
  25420. if ( ftype == MDF_NETCDF ) then
  25421. call NetCDF_Get_FileType( trim(filename), ftype_name, status )
  25422. IF_NOT_OK_RETURN(status=1)
  25423. end if
  25424. #endif
  25425. ! open file:
  25426. call MDF_Open( trim(filename), ftype, MDF_READ, hid, status )
  25427. IF_NOT_OK_RETURN(status=1)
  25428. ! header line:
  25429. ! <filetype> <filename> {
  25430. write (gol,'(a," ",a," {")') trim(ftype_name), trim(filename); call goPr
  25431. ! number of dimensions:
  25432. call MDF_Inquire( hid, status, nDimensions=ndim )
  25433. IF_NOT_OK_RETURN(status=1)
  25434. ! list dimensions ?
  25435. if ( ndim > 0 ) then
  25436. ! init flag:
  25437. isfirst = .true.
  25438. ! loop over dimensions:
  25439. do idim = 1, ndim
  25440. ! write lines:
  25441. ! x = 4 ;
  25442. ! t = UNLIMITED ; // (5 currently)
  25443. ! ...
  25444. ! get name and length:
  25445. call MDF_Inquire_Dimension( hid, idim, status, name=name, named=named, &
  25446. length=length, unlimited=unlimited )
  25447. IF_NOT_OK_RETURN(status=1)
  25448. ! skip ?
  25449. if ( .not. named ) cycle
  25450. ! display header ?
  25451. if ( isfirst ) then
  25452. write (gol,'("dimensions:")'); call goPr
  25453. isfirst = .false.
  25454. end if
  25455. ! display:
  25456. if ( unlimited ) then
  25457. write (val,*) length
  25458. val = adjustl(val)
  25459. write (gol,'(" ",a," = UNLIMITED ; // (",a," currently)")') trim(name), trim(val); call goPr
  25460. else if ( named ) then
  25461. write (gol,'(" ",a," = ",i6," ;")') trim(name), length; call goPr
  25462. end if
  25463. end do ! dimensions
  25464. end if ! ndim > 0
  25465. ! number of variables:
  25466. call MDF_Inquire( hid, status, nVariables=nvar )
  25467. IF_NOT_OK_RETURN(status=1)
  25468. ! list variables ?
  25469. if ( nvar > 0 ) then
  25470. ! start:
  25471. write (gol,'("variables:")'); call goPr
  25472. ! loop over variables:
  25473. do ivar = 1, nvar
  25474. ! write lines:
  25475. ! float afield(y, x) ;
  25476. ! afield:unit = "m" ;
  25477. ! ...
  25478. ! get name etc:
  25479. call MDF_Inquire_Variable( hid, ivar, status, name=name, xtype=xtype, ndims=ndim, natts=natt )
  25480. IF_NOT_OK_RETURN(status=1)
  25481. ! get dimension id's now the number is known:
  25482. call MDF_Inquire_Variable( hid, ivar, status, dimids=dimids(1:ndim) )
  25483. IF_NOT_OK_RETURN(status=1)
  25484. ! start line with type and variable name:
  25485. write (line,'(" ",a," ",a,"(")') trim(MDF_DATATYPE_NAME(xtype)), trim(name)
  25486. ! loop over dimensions:
  25487. shp = 1
  25488. do idim = 1, ndim
  25489. ! get dimension name:
  25490. call MDF_Inquire_Dimension( hid, dimids(idim), status, name=name, named=named, &
  25491. length=length, unlimited=unlimited )
  25492. IF_NOT_OK_RETURN(status=1)
  25493. ! add to line:
  25494. if ( idim > 1 ) line = trim(line)//','
  25495. ! name or number ...
  25496. if ( named ) then
  25497. line = trim(line)//' '//trim(name)
  25498. else
  25499. write (val,*) length
  25500. line = trim(line)//' '//adjustl(val)
  25501. if (unlimited) line = trim(line)//'/Inf'
  25502. end if
  25503. ! store for show_data:
  25504. shp(idim) = length
  25505. end do
  25506. ! close line:
  25507. line = trim(line)//' ) ;'
  25508. ! display dimension name(dims) line:
  25509. write (gol,'(a)') trim(line); call goPr
  25510. ! write attributes:
  25511. call MDF_Show_Attributes( hid, ivar, natt, status )
  25512. IF_NOT_OK_RETURN(status=1)
  25513. ! show data ?
  25514. if ( do_show_data ) then
  25515. ! display data:
  25516. call MDF_Show_Data( hid, ivar, xtype, ndim, shp, status )
  25517. IF_NOT_OK_RETURN(status=1)
  25518. end if
  25519. end do ! variables
  25520. end if ! nvar > 0
  25521. ! number of global attributes:
  25522. call MDF_Inquire( hid, status, nAttributes=natt )
  25523. IF_NOT_OK_RETURN(status=1)
  25524. ! global attributes ?
  25525. if ( natt > 0 ) then
  25526. ! intro:
  25527. write (gol,'("")'); call goPr
  25528. write (gol,'("// global attributes:")'); call goPr
  25529. ! display attributes:
  25530. call MDF_Show_Attributes( hid, MDF_GLOBAL, natt, status )
  25531. IF_NOT_OK_RETURN(status=1)
  25532. end if
  25533. ! closure:
  25534. ! }
  25535. write (gol,'("}")'); call goPr
  25536. ! close file:
  25537. call MDF_Close( hid, status )
  25538. IF_NOT_OK_RETURN(status=1)
  25539. ! ok
  25540. status = 0
  25541. end subroutine MDF_Show
  25542. ! ***
  25543. subroutine MDF_Show_Attributes( hid, ivar, natt, status )
  25544. ! --- in/out -------------------------------------
  25545. integer, intent(in) :: hid
  25546. integer, intent(in) :: ivar
  25547. integer, intent(in) :: natt
  25548. integer, intent(out) :: status
  25549. ! --- const --------------------------------------
  25550. character(len=*), parameter :: rname = mname//'/MDF_Show_Attributes'
  25551. ! --- local --------------------------------------
  25552. integer :: l
  25553. integer :: iatt
  25554. character(len=LEN_NAME) :: name
  25555. integer :: length
  25556. integer :: xtype
  25557. character(len=LEN_LINE) :: line
  25558. character(len=LEN_NAME) :: val
  25559. integer :: ival
  25560. integer(4), allocatable :: values_i4(:)
  25561. real(8), allocatable :: values_r8(:)
  25562. ! --- begin --------------------------------------
  25563. ! loop over attributes:
  25564. do iatt = 1, natt
  25565. ! get name:
  25566. call MDF_Inq_AttName( hid, ivar, iatt, name, status )
  25567. IF_NOT_OK_RETURN(status=1)
  25568. ! get type and length:
  25569. call MDF_Inquire_Attribute( hid, ivar, name, status, xtype=xtype, length=length )
  25570. IF_NOT_OK_RETURN(status=1)
  25571. !! info ...
  25572. !write (gol,'(" ",a," <",a,"> ",i4," ;")') trim(name), trim(MDF_DATATYPE_NAME(xtype)), length; call goPr
  25573. ! different per type ...
  25574. select case ( xtype )
  25575. !character values
  25576. case ( MDF_CHAR )
  25577. ! get value:
  25578. call MDF_Get_Att( hid, ivar, name, line, status )
  25579. if (status/=0) then
  25580. ! somthing went wrong (attribute too large ?)
  25581. line = '...'
  25582. else
  25583. ! ok; but not too much to the screen ...
  25584. if ( len_trim(line) > 400 ) line = line(1:400)//'...'
  25585. end if
  25586. ! display ..
  25587. ! variable rank etc:
  25588. write (gol,'(" ",a," = """,a,""" ;")') trim(name), trim(line); call goPr
  25589. !integer values
  25590. case ( MDF_BYTE, MDF_SHORT, MDF_INT )
  25591. ! storage:
  25592. allocate( values_i4(length) )
  25593. ! fill:
  25594. call MDF_Get_Att( hid, ivar, name, values_i4, status )
  25595. if (status/=0) then
  25596. ! somthing went wrong (attribute too large ?)
  25597. line = '...'
  25598. else
  25599. ! loop over values:
  25600. line = ''
  25601. do ival = 1, min(length,50)
  25602. ! add seperation if necessary:
  25603. if ( ival > 1 ) line = trim(line)//','
  25604. ! dump value:
  25605. write (val,*) values_i4(ival)
  25606. ! shift to left:
  25607. val = adjustl(val)
  25608. ! add to line:
  25609. line = trim(line)//' '//trim(val)
  25610. ! add type indicator if necessary:
  25611. if ( xtype == MDF_BYTE ) line = trim(line)//'b'
  25612. if ( xtype == MDF_SHORT ) line = trim(line)//'s'
  25613. end do
  25614. if ( ival < length ) line=trim(line)//' ...'
  25615. end if
  25616. ! display:
  25617. write (gol,'(" ",a," =",a)') trim(name), trim(line); call goPr
  25618. ! clear:
  25619. deallocate( values_i4 )
  25620. !floating point values
  25621. case ( MDF_FLOAT, MDF_DOUBLE )
  25622. ! storage:
  25623. allocate( values_r8(length) )
  25624. ! fill:
  25625. call MDF_Get_Att( hid, ivar, name, values_r8, status )
  25626. if (status/=0) then
  25627. ! somthing went wrong (attribute too large ?)
  25628. line = '...'
  25629. else
  25630. ! loop over values:
  25631. line = ''
  25632. do ival = 1, min(length,50)
  25633. ! add seperation if necessary:
  25634. if ( ival > 1 ) line = trim(line)//','
  25635. ! dump value:
  25636. write (val,*) values_r8(ival)
  25637. ! remove tailing zeros:
  25638. do l = len_trim(val), 1, -1
  25639. if ( val(l:l) /= '0' ) exit
  25640. val(l:l) = ' '
  25641. end do
  25642. ! shift to left:
  25643. val = adjustl(val)
  25644. ! add to line:
  25645. line = trim(line)//' '//trim(val)
  25646. ! add type indicator if necessary:
  25647. if ( xtype == MDF_FLOAT ) line = trim(line)//'f'
  25648. end do
  25649. if ( ival < length ) line=trim(line)//' ...'
  25650. end if
  25651. ! display:
  25652. write (gol,'(" ",a," =",a)') trim(name), trim(line); call goPr
  25653. ! clear:
  25654. deallocate( values_r8 )
  25655. !other ...
  25656. case default
  25657. write (gol,'("INTERNAL - unsupported data type : ",i6)') xtype; call goErr
  25658. TRACEBACK; status=1; return
  25659. end select
  25660. end do
  25661. ! ok
  25662. status = 0
  25663. end subroutine MDF_Show_Attributes
  25664. ! ***
  25665. subroutine MDF_Show_Data( hid, ivar, xtype, rank, shp, status )
  25666. ! --- in/out -------------------------------------
  25667. integer, intent(in) :: hid
  25668. integer, intent(in) :: ivar
  25669. integer, intent(in) :: xtype
  25670. integer, intent(in) :: rank
  25671. integer, intent(in) :: shp(MAX_RANK)
  25672. integer, intent(out) :: status
  25673. ! --- const --------------------------------------
  25674. character(len=*), parameter :: rname = mname//'/MDF_Show_Data'
  25675. ! --- local --------------------------------------
  25676. character(len=LEN_LINE) :: line
  25677. character(len=LEN_NAME) :: val
  25678. integer :: l
  25679. integer :: i1,i2,i3,i4,i5,i6,i7
  25680. integer(4), allocatable :: values_i4(:,:,:,:,:,:,:)
  25681. real(8), allocatable :: values_r8(:,:,:,:,:,:,:)
  25682. character(len=shp(1)), allocatable :: values_c (:,:,:,:,:,:)
  25683. ! --- begin --------------------------------------
  25684. ! per type:
  25685. select case ( xtype )
  25686. ! character values:
  25687. case ( MDF_CHAR )
  25688. ! storage:
  25689. allocate( values_c(shp(2),shp(3),shp(4),shp(5),shp(6),shp(7)), stat=status )
  25690. IF_NOT_OK_RETURN(status=1)
  25691. ! read:
  25692. select case ( rank )
  25693. case ( 1 ) ; call MDF_Get_Var( hid, ivar, values_c(1,1,1,1,1,1), status, count=shp(1:rank) )
  25694. case ( 2 ) ; call MDF_Get_Var( hid, ivar, values_c(:,1,1,1,1,1), status, count=shp(1:rank) )
  25695. case ( 3 ) ; call MDF_Get_Var( hid, ivar, values_c(:,:,1,1,1,1), status, count=shp(1:rank) )
  25696. case ( 4 ) ; call MDF_Get_Var( hid, ivar, values_c(:,:,:,1,1,1), status, count=shp(1:rank) )
  25697. case ( 5 ) ; call MDF_Get_Var( hid, ivar, values_c(:,:,:,:,1,1), status, count=shp(1:rank) )
  25698. case ( 6 ) ; call MDF_Get_Var( hid, ivar, values_c(:,:,:,:,:,1), status, count=shp(1:rank) )
  25699. case ( 7 ) ; call MDF_Get_Var( hid, ivar, values_c(:,:,:,:,:,:), status, count=shp(1:rank) )
  25700. case default
  25701. write (gol,'("INTERNAL - unsupported rank : ",i6)') rank; call goErr
  25702. TRACEBACK; status=1; return
  25703. end select
  25704. IF_NOT_OK_RETURN(status=1)
  25705. ! loop over higher dimensions:
  25706. do i7 = 1, shp(7)
  25707. do i6 = 1, shp(6)
  25708. do i5 = 1, shp(5)
  25709. do i4 = 1, shp(4)
  25710. do i3 = 1, shp(3)
  25711. ! plot index of higer dimensions ?
  25712. if ( rank > 2 ) then
  25713. line = ' (:,:'
  25714. if ( rank >= 3 ) write (line,'(a,",",i4)') trim(line), i3
  25715. if ( rank >= 4 ) write (line,'(a,",",i4)') trim(line), i4
  25716. if ( rank >= 5 ) write (line,'(a,",",i4)') trim(line), i5
  25717. if ( rank >= 6 ) write (line,'(a,",",i4)') trim(line), i6
  25718. if ( rank >= 7 ) write (line,'(a,",",i4)') trim(line), i7
  25719. line = trim(line)//')'
  25720. write (gol,'(a)') trim(line); call goPr
  25721. end if
  25722. ! display matrix:
  25723. do i2 = 1, shp(2)
  25724. ! copy value:
  25725. line = values_c(i2,i3,i4,i5,i6,i7)
  25726. ! display:
  25727. write (gol,'(" `",a,"` ;")') trim(line); call goPr
  25728. end do ! i2
  25729. end do ! i3
  25730. end do ! i4
  25731. end do ! i5
  25732. end do ! i6
  25733. end do ! i7
  25734. ! clear:
  25735. deallocate( values_c, stat=status )
  25736. IF_NOT_OK_RETURN(status=1)
  25737. ! integer values:
  25738. case ( MDF_BYTE, MDF_SHORT, MDF_INT )
  25739. ! storage:
  25740. allocate( values_i4(shp(1),shp(2),shp(3),shp(4),shp(5),shp(6),shp(7)), stat=status )
  25741. IF_NOT_OK_RETURN(status=1)
  25742. ! read:
  25743. select case ( rank )
  25744. case ( 1 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,1,1,1,1,1,1), status )
  25745. case ( 2 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,1,1,1,1,1), status )
  25746. case ( 3 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,:,1,1,1,1), status )
  25747. case ( 4 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,:,:,1,1,1), status )
  25748. case ( 5 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,:,:,:,1,1), status )
  25749. case ( 6 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,:,:,:,:,1), status )
  25750. case ( 7 ) ; call MDF_Get_Var( hid, ivar, values_i4(:,:,:,:,:,:,:), status )
  25751. case default
  25752. write (gol,'("INTERNAL - unsupported rank : ",i6)') rank; call goErr
  25753. TRACEBACK; status=1; return
  25754. end select
  25755. IF_NOT_OK_RETURN(status=1)
  25756. ! loop over higher dimensions:
  25757. do i7 = 1, shp(7)
  25758. do i6 = 1, shp(6)
  25759. do i5 = 1, shp(5)
  25760. do i4 = 1, shp(4)
  25761. do i3 = 1, shp(3)
  25762. ! plot index of higer dimensions ?
  25763. if ( rank > 2 ) then
  25764. line = ' (:,:'
  25765. if ( rank >= 3 ) write (line,'(a,",",i4)') trim(line), i3
  25766. if ( rank >= 4 ) write (line,'(a,",",i4)') trim(line), i4
  25767. if ( rank >= 5 ) write (line,'(a,",",i4)') trim(line), i5
  25768. if ( rank >= 6 ) write (line,'(a,",",i4)') trim(line), i6
  25769. if ( rank >= 7 ) write (line,'(a,",",i4)') trim(line), i7
  25770. line = trim(line)//')'
  25771. write (gol,'(a)') trim(line); call goPr
  25772. end if
  25773. ! display matrix:
  25774. do i2 = 1, shp(2)
  25775. line = ''
  25776. do i1 = 1, shp(1)
  25777. !! not all ?
  25778. !if ( i1 > 10 ) then
  25779. ! line = trim(line)//' ...'
  25780. ! exit
  25781. !end if
  25782. ! add seperation if necessary:
  25783. if ( i1 > 1 ) line = trim(line)//','
  25784. ! dump value:
  25785. write (val,*) values_i4(i1,i2,i3,i4,i5,i6,i7)
  25786. ! shift to left:
  25787. val = adjustl(val)
  25788. ! add to line:
  25789. line = trim(line)//' '//trim(val)
  25790. ! add type indicator if necessary:
  25791. if ( xtype == MDF_BYTE ) line = trim(line)//'b'
  25792. if ( xtype == MDF_SHORT ) line = trim(line)//'s'
  25793. ! line too long already ?
  25794. if ( len_trim(line) > 72 ) then
  25795. ! display:
  25796. write (gol,'(" ",a," ;")') trim(line); call goPr
  25797. ! empty:
  25798. line = ''
  25799. end if
  25800. end do ! i1
  25801. ! display:
  25802. if ( len_trim(line) > 0 ) then
  25803. write (gol,'(" ",a," ;")') trim(line); call goPr
  25804. end if
  25805. end do ! i2
  25806. end do ! i3
  25807. end do ! i4
  25808. end do ! i5
  25809. end do ! i6
  25810. end do ! i7
  25811. ! clear:
  25812. deallocate( values_i4, stat=status )
  25813. IF_NOT_OK_RETURN(status=1)
  25814. ! real values:
  25815. case ( MDF_FLOAT, MDF_DOUBLE )
  25816. ! storage:
  25817. allocate( values_r8(shp(1),shp(2),shp(3),shp(4),shp(5),shp(6),shp(7)), stat=status )
  25818. IF_NOT_OK_RETURN(status=1)
  25819. ! read:
  25820. select case ( rank )
  25821. case ( 1 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,1,1,1,1,1,1), status )
  25822. case ( 2 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,1,1,1,1,1), status )
  25823. case ( 3 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,:,1,1,1,1), status )
  25824. case ( 4 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,:,:,1,1,1), status )
  25825. case ( 5 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,:,:,:,1,1), status )
  25826. case ( 6 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,:,:,:,:,1), status )
  25827. case ( 7 ) ; call MDF_Get_Var( hid, ivar, values_r8(:,:,:,:,:,:,:), status )
  25828. case default
  25829. write (gol,'("INTERNAL - unsupported rank : ",i6)') rank; call goErr
  25830. TRACEBACK; status=1; return
  25831. end select
  25832. IF_NOT_OK_RETURN(status=1)
  25833. ! loop over higher dimensions:
  25834. do i7 = 1, shp(7)
  25835. do i6 = 1, shp(6)
  25836. do i5 = 1, shp(5)
  25837. do i4 = 1, shp(4)
  25838. do i3 = 1, shp(3)
  25839. ! plot index of higer dimensions ?
  25840. if ( rank > 2 ) then
  25841. line = ' (:,:'
  25842. if ( rank >= 3 ) write (line,'(a,",",i4)') trim(line), i3
  25843. if ( rank >= 4 ) write (line,'(a,",",i4)') trim(line), i4
  25844. if ( rank >= 5 ) write (line,'(a,",",i4)') trim(line), i5
  25845. if ( rank >= 6 ) write (line,'(a,",",i4)') trim(line), i6
  25846. if ( rank >= 7 ) write (line,'(a,",",i4)') trim(line), i7
  25847. line = trim(line)//')'
  25848. write (gol,'(a)') trim(line); call goPr
  25849. end if
  25850. ! display matrix:
  25851. do i2 = 1, shp(2)
  25852. line = ''
  25853. do i1 = 1, shp(1)
  25854. !! not all ?
  25855. !if ( i1 > 10 ) then
  25856. ! line = trim(line)//' ...'
  25857. ! exit
  25858. !end if
  25859. ! add seperation if necessary:
  25860. if ( i1 > 1 ) line = trim(line)//','
  25861. ! dump value:
  25862. write (val,*) values_r8(i1,i2,i3,i4,i5,i6,i7)
  25863. ! remove tailing zeros:
  25864. do l = len_trim(val), 1, -1
  25865. if ( val(l:l) /= '0' ) exit
  25866. val(l:l) = ' '
  25867. end do
  25868. ! shift to left:
  25869. val = adjustl(val)
  25870. ! add to line:
  25871. line = trim(line)//' '//trim(val)
  25872. ! add type indicator if necessary:
  25873. if ( xtype == MDF_FLOAT ) line = trim(line)//'f'
  25874. ! line too long already ?
  25875. if ( len_trim(line) > 72 ) then
  25876. ! display:
  25877. write (gol,'(" ",a," ;")') trim(line); call goPr
  25878. ! empty:
  25879. line = ''
  25880. end if
  25881. end do ! i1
  25882. ! display:
  25883. if ( len_trim(line) > 0 ) then
  25884. write (gol,'(" ",a," ;")') trim(line); call goPr
  25885. end if
  25886. end do ! i2
  25887. end do ! i3
  25888. end do ! i4
  25889. end do ! i5
  25890. end do ! i6
  25891. end do ! i7
  25892. ! clear:
  25893. deallocate( values_r8, stat=status )
  25894. IF_NOT_OK_RETURN(status=1)
  25895. case default
  25896. write (gol,'("INTERNAL - unsupported data type : ",i6)') xtype; call goErr
  25897. TRACEBACK; status=1; return
  25898. end select
  25899. ! ok
  25900. status = 0
  25901. end subroutine MDF_Show_Data
  25902. end module MDF