;+
; NAME: clmSoilsWTexture
;
; PURPOSE: Runs clm for all soils of a given texture specified in a pair of file.
;          Looks through the database of SHPs generated by MOSCEM (runMoscemSHP.pro)
;          and compHT2HK.pro, and uses the general.txt file from UNSODA to pick out texture
;
; CATEGORY: Batch running clm
;
;
; CALLING SEQUENCE: clmSoilsWTexture, texture, datafilename, texturefilename
;
; INPUTS: texture = a string identifying the texture you wish to run clm for
;                   e.g. "sandy loam" "clay" "silt clay loam" see the routine textIndex
;                   for a complete list of textures
;         datafilename = filename of compHT2HK.pro outputfile
;         texturefilename = filename of "general.txt" file from UNSODA database
;
;
; OPTIONAL INPUTS: <none>
;
; KEYWORD PARAMETERS: <none>
;
; OUTPUTS: clm output files named "out_texture_soilNumber.nc"
;            where : texture = the inputtexture name (without spaces)
;                    soilNumber= the soil index number in the UNSODA database
;
; OPTIONAL OUTPUTS: <none>
;
; COMMON BLOCKS: <none>
;
; SIDE EFFECTS: files tmpSevilleta_srf.txt and sevilleta_srf.nc in ../../inputdata/sev/srfdata/ are overwritten
;
; RESTRICTIONS: Current directory must be clm/bld/offline/
;
; PROCEDURE: Get an array of [soilNumber,Texture] from the texture file.
;            Read through the datafile, for each soil
;              If it matches the texture requested, and SHPs are reasonable
;                Write tmpSevilleta_srf.txt file then ncgen sevilleta_srf.nc file
;                Run clm
;                Rename output file
;
; EXAMPLE:
;
; MODIFICATION HISTORY:
;           1/25/2005 edg - Original modified from noahSoilsWTexture.pro
;-


FUNCTION getTextures, textureFile
  openr, un, /get, textureFile
  line=''
  output=strarr(2)
  i=0
  WHILE NOT eof(un) DO BEGIN
     readf, un, line
     data=strsplit(line, '~', /extract, /preserve_null)
     texture=(strsplit(data[3], '"', /extract))[0]
     output=[[output],[[data[0], texture] ]]
     i++
  ENDWHILE
  close, un
  free_lun, un
  output=output[*,1:--i]
  return, output
END

PRO matchNwrite10, un, oun, match, value
  line=''
  readf, un, line
  WHILE NOT strmatch(line, match) DO BEGIN 
     printf, oun, line
     readf, un, line
  ENDWHILE
  printf, oun, line

  FOR i=1,9 DO BEGIN
     readf, un, line
     printf, oun, string(value)+','
  ENDFOR
  readf, un, line
  printf, oun, string(value)+' ;'

END

;; Writes a one line SOILPARM.TBL file for input to the Clm model.
;; IHOPstyp must be set to soil number 1
PRO writeSoilFile, data, index, vg=vg, cam=cam, convert=convert
  data=float(data)
  b=data[5] ; n if vg
  MAXSMC=data[8]

  IF keyword_set(cam) THEN $
    SATPSI=data[6]*10.         ; convert cm to mm
  IF keyword_set(vg) THEN BEGIN
    ALPHA=data[6]/10.         ; convert 1/cm to 1/mm  alpha
    p=3+2.0*(1.0/(data[5]-1.0))
    SATPSI = (1.0/(data[6]/10.0)) * (p+3)/(2*p*(p-1)) * (147.8+8.1*p + 0.092*(p^2))/(55.6+7.4*p + p^2)
    DRYSMC=data[9]
 ENDIF

  Ks=data[7]/8640. ; convert cm/day to mm/s

  IF keyword_set(cam) AND keyword_set(convert) THEN BEGIN
     b=1.0/(data[5]-1.0)
     p=3+2.0*b
     SATSPI = (1.0/(data[6]/10.0)) * (p+3)/(2*p*(p-1)) * (147.8+8.1*p + 0.092*(p^2))/(55.6+7.4*p + p^2)
  ENDIF

  IF Ks EQ 0 THEN BEGIN
     print, "ERROR, ks = 0"
     print, "data[7]=",data[7]
  ENDIF

;  IF keyword_set(vg) THEN tmpb=2*(1.0-1.0/b) ELSE tmpb=b
  srffile=file_search('srfdata/*_srf.*') ; srffile[0]=.nc, srffile[1]=.txt
  IF n_elements(srffile) EQ 1 THEN BEGIN
     txtfile=(strsplit(srffile[0], /extract, '.nc'))[0]+'.txt'
     srffile=[srffile,txtfile]
     spawn, 'ncdump '+srffile[0]+' >'+txtfile
  ENDIF
  tmpfile=srffile[1]+'.tmp'
;; this is the master file we are going to copy
  openr, un, /get, srffile[1]
;; this is the new file we are writing
  openw, oun, /get, tmpfile

  IF keyword_set(cam) THEN BEGIN 
     matchNwrite10, un, oun, '*SUC_SAT =*', SATPSI
     matchNwrite10, un, oun, '*HK_SAT =*', Ks
     matchNwrite10, un, oun, '*B_SW =*', b
     matchNwrite10, un, oun, '*WAT_SAT =*', MAXSMC
  ENDIF ELSE IF keyword_set(vg) THEN BEGIN 
     matchNwrite10, un, oun, '*SUC_SAT =*', SATPSI
     matchNwrite10, un, oun, '*HK_SAT =*', Ks
     matchNwrite10, un, oun, '*VG_N =*', b
     matchNwrite10, un, oun, '*VG_ALPHA =*', ALPHA
     matchNwrite10, un, oun, '*WAT_DRY =*', DRYSMC
     matchNwrite10, un, oun, '*WAT_SAT =*', MAXSMC
  ENDIF


  line=''
  WHILE NOT eof(un) DO BEGIN 
     readf, un, line
     printf, oun, line
  ENDWHILE

  close, oun, un
  free_lun, oun, un

  spawn, 'ncgen -o '+srffile[0]+' '+tmpfile
END

;; run the clm model and rename the output file
PRO runClm, i, texture
  inputfile=file_search('*.stdin')
  print, "running clm "+texture+strcompress(i)
  spawn, '../clm < '+inputfile[0]+' >&/dev/null'
  spawn, 'mv clm3run_*clm2.h0* out'+"_"+strcompress(texture, /remove_all)+"_"+strcompress(fix(i), /remove_all)+'.nc'
;  spawn, 'rm ../../clm3run/clm.log.*'
END

;; for now this index is used into the arrays F11 and QTZ in writeSoilFile
FUNCTION textIndex, texture
  CASE strlowcase(texture) OF 
     "sand" :            index=0
     "loamy sand" :      index=1
     "sandy loam" :      index=2
     "silt loam" :       index=3
     "silt" :            index=4
     "loam" :            index=5
     "sandy clay loam" : index=6
     "silty clay loam" : index=7
     "clay loam" :       index=8
     "sandy clay" :      index=9
     "silty clay" :      index=10
     "clay" :            index=11
  ENDCASE
  return, index
END



PRO clmSoilsWTexture, texture, dataFile, textureFile, vg=vg, cam=cam, convert=convert, skipn=skipn

  IF NOT keyword_set(vg) THEN cam=1

  textData=getTextures(textureFile)
  textureIndex=textIndex(texture)
  line=''
  openr, un, /get, dataFile
;  openw, oun, /get, strcompress(texture, /remove_all)+".data"
  readf, un, line ; read in the column headings and discard
  IF NOT keyword_set(skipn) THEN skipn=1
  nthsoil=0l
  WHILE NOT eof(un) DO BEGIN
     readf, un, line
     data=float(strsplit(line, /extract))
     
     IF (data[1] LT 999.9 AND data[1] NE 0 AND data[4] GT 0.25 AND $
         data[6] LT 10000000000 AND data[7] LT 10000000000 AND data[7] GT 0) THEN BEGIN
        
        dex=where(textData[0,*] EQ data[0])
        IF dex[0] NE -1 THEN BEGIN
           IF textData[1,dex] EQ texture OR $
             strcompress(textData[1,dex], /remove_all) $
             EQ strcompress(texture, /remove_all) $
             THEN BEGIN
;              printf, oun, data
              IF nthsoil MOD skipn EQ 0 THEN BEGIN 
                 writeSoilFile, data, textureIndex[0], cam=cam, vg=vg, convert=convert
                 runClm, data[0], texture
              endif
              nthsoil++
           endIF
        ENDIF
     ENDIF
  ENDWHILE

  close, un;, oun
  free_lun, un;, oun
END
