68 type(dict_struct),
pointer :: dict => null()
70 character(*),
parameter :: HEADER =
"Content-type: application/json; charset=utf-8"//char(10)//&
71 "Content-Disposition: attachment; filename=data.json"//char(10)
73 logical,
parameter :: DEBUG = .false.
74 integer,
parameter :: DEBUG_UNIT = 0
78 integer,
parameter :: MAX_PARAM_LENGTH = 500
79 integer,
parameter :: TMP_UNIT = 142
80 real(kind=EIRAM_DP) :: NEG_INF = -huge(1.d0)
81 character(MAX_PARAM_LENGTH) :: input =
""
82 character(MAX_PARAM_LENGTH),
dimension(:),
allocatable :: files, types, reactions, arg1s, arg2s
83 integer :: nFiles, nTypes, nReactions, nArg1s, nArg2s
85 real(kind=EIRAM_DP),
dimension(:),
allocatable :: xs, ys
86 real(kind=EIRAM_DP) :: epsfilter = 0d0
88 integer,
parameter :: MAX_POINTS = 1000000
90 open(tmp_unit, iostat=err, status=
'scratch', action=
'readwrite')
92 write(tmp_unit, *)
"BEGIN OF LOG"
93 write(tmp_unit, *)
"CGI: not initialized"
95 call get_environment_variable(
"QUERY_STRING", input)
96 if(index(input,
'=') == 0)
then
102 call getcsvparameter(dict,
"files",
"no file names provided", files, nfiles)
103 call getcsvparameter(dict,
"types",
"no type names provided", types, ntypes)
104 call getcsvparameter(dict,
"reactions",
"no reaction indices provided", reactions, nreactions)
105 call getcsvparameter(dict,
"arg1s",
"no first arguments provided", arg1s, narg1s)
106 call getcsvparameter(dict,
"arg2s",
"no second arguments provided", arg2s, narg2s)
107 call cgi_get(dict,
"epsfilter", epsfilter)
109 if(debug)
write(debug_unit, *) nfiles, files
110 if(debug)
write(debug_unit, *) ntypes, types
111 if(debug)
write(debug_unit, *) nreactions, reactions
112 if(debug)
write(debug_unit, *) narg1s, arg1s
113 if(debug)
write(debug_unit, *) narg2s, arg2s
115 if(.not.all((/nfiles, ntypes, nreactions, narg1s/) == narg2s))
then
116 call cgi_error(
"esputr_cgi: all lists must have the same length")
119 write(unit,
'(A)') header
122 write(unit,
'(A)'),
"["
125 write(unit,
'(A)'),
","
127 call getpoints(files(i), types(i), reactions(i), arg1s(i), arg2s(i), xs, ys)
131 write(unit,
'(A)'),
"]"
139 subroutine getpoints(fileName, reactionType, reactionIndex, arg1s_str, arg2s_str, xs, ys)
141 character(*),
intent(in) :: fileName
143 character(*),
intent(in) :: reactionType
145 character(*),
intent(in) :: reactionIndex
147 character(*),
intent(in) :: arg1s_str
150 character(*),
intent(in) :: arg2s_str
152 real(kind=EIRAM_DP),
allocatable,
intent(out) :: xs(:)
154 real(kind=EIRAM_DP),
allocatable,
intent(out) :: ys(:)
155 real(kind=EIRAM_DP),
allocatable :: ys0(:)
156 real(kind=EIRAM_DP),
allocatable :: arg1s(:), arg2s(:)
157 logical,
allocatable :: filterMask(:)
158 integer :: err,n,i,lastITaken
170 if(
size(arg2s) == 0 .or.
size(arg1s) == 0)
call cgi_error(
"esputr_cgi: invalid input vectors")
172 if(arg2s(1) <= neg_inf)
then
173 allocate(ys0(
size(arg1s)), stat=err)
175 call eiram_matlab_calc1(ys0,arg1s,
size(arg1s), filename, reactiontype, reactionindex, err)
178 allocate(ys0(
size(arg2s)), stat=err)
180 call eiram_matlab_calc2(ys0, arg1s(1), arg2s, 1,
size(arg2s), filename, reactiontype, reactionindex, err)
185 allocate(filtermask(n),stat=err)
188 filtermask(1) = .true.
191 filtermask(i) = abs(ys0(i)-ys0(lastitaken)) > .5*epsfilter*(abs(ys0(i))+abs(ys0(lastitaken)))
192 if(filtermask(i)) lastitaken = i
194 filtermask(n) = .true.
197 if(
allocated(xs))
deallocate(xs)
198 if(
allocated(ys))
deallocate(ys)
199 allocate(xs(n),ys(n),stat=err)
201 if(arg2s(1) <= neg_inf)
then
202 xs=pack(arg1s,filtermask)
204 xs=pack(arg2s,filtermask)
206 ys=pack(ys0,filtermask)
208 deallocate(arg1s,arg2s,filtermask,ys0)
216 character(*),
intent(in) :: fileName
218 character(*),
intent(in) :: reactionType
220 character(*),
intent(in) :: reactionIndex
222 real(kind=EIRAM_DP),
dimension(:),
intent(in) :: xs
224 real(kind=EIRAM_DP),
dimension(:),
intent(in) :: ys
225 character(150+2*(14*size(xs)+2)) :: pointsToJsonString
227 pointstojsonstring(1:1) =
"{"
230 pointstojsonstring(c:c+3) =
'"x":'
235 pointstojsonstring(c:c+4) =
',"y":'
244 pointstojsonstring(c:c) =
"}"
249 subroutine getcsvparameter(dict, parameterName, errMsg, values, nValues)
251 type(dict_struct),
pointer,
intent(in) :: dict
253 character(*),
intent(in) :: parameterName
255 character(*),
intent(in) :: errMsg
257 character(MAX_PARAM_LENGTH),
dimension(:),
allocatable,
intent(inout) :: values
259 integer,
intent(out) :: nValues
260 character(DICT_VALUE_LENGTH) :: input =
""
261 call cgi_get(dict, parametername, input)
262 if(input ==
"")
call cgi_error(
"esputr_cgi: "//errmsg)
263 call split(input,
",", values)
264 nvalues =
size(values)
279 call cgi_error(
"esputr_cgi: cannot create the list of reactions")
284 write(unit,
'(A)') header
290 deallocate(reactions(i)%creac)
292 deallocate(reactions)
313 backspace(tmp_unit, iostat=err)
314 backspace(tmp_unit, iostat=err)
320 subroutine split(string, c, array)
322 character(*),
intent(in) :: string
324 character(1),
intent(in) :: c
325 character(MAX_PARAM_LENGTH),
dimension(:),
allocatable,
intent(out) :: array
327 character(DICT_VALUE_LENGTH) :: str
330 allocate(array(nseps + 1))
333 if(str(i:i) == c)
then
338 read(str, *) array(1:nseps+1)
345 character(*),
intent(in) :: strArr
346 real(kind=EIRAM_DP),
dimension(:),
allocatable,
intent(out) :: realArr
347 character(MAX_PARAM_LENGTH),
dimension(:),
allocatable :: strArrSplit
348 real(kind=EIRAM_DP) :: start, delta, ende
349 integer :: i, err, nValues
351 if(
allocated(realarr))
deallocate(realarr)
353 if(strarr ==
"-")
then
359 if(
allocated(strarrsplit))
deallocate(strarrsplit)
360 call split(strarr,
":", strarrsplit)
361 select case(
size(strarrsplit))
364 read(strarrsplit(1), *, iostat=err) realarr(1)
365 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(1))
368 read(strarrsplit(1), *, iostat=err) start
369 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(1))
370 read(strarrsplit(2), *, iostat=err) ende
371 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(2))
374 read(strarrsplit(1), *, iostat=err) start
375 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(1))
376 read(strarrsplit(2), *, iostat=err) delta
377 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(2))
378 read(strarrsplit(3), *, iostat=err) ende
379 if(err/=0)
call cgi_error(
"esputr_cgi: invalid real value "//strarrsplit(3))
381 call cgi_error(
"esputr_cgi: invalid vector format "//strarr)
383 nvalues = floor((ende-start)/delta) + 1
384 if(nvalues>max_points)
then
385 call cgi_error(
"eiram_cgi: too many data points are requested")
387 allocate(realarr(nvalues))
388 realarr = (/ ( start + i*delta, i = 0, nvalues-1 ) /)
395 character(1024*N) :: getReactionsAsJson
397 integer,
intent(in) :: N
398 character(EIRAM_FILE_NAME_LENGTH) :: lastFileName
399 character(EIRAM_TYPE_LENGTH) :: lastTypeName
400 integer,
intent(out) :: err
401 integer :: r, c, l, m
407 getreactionsasjson(1:10) =
'{"files":['
409 foreachreaction:
do r = 1,
size(reactions)
411 if(lastfilename /= reactions(r)%FILE)
then
412 if(lastfilename /=
"")
then
413 getreactionsasjson(c:c+4) =
"]}]},"
416 lastfilename = reactions(r)%FILE
418 getreactionsasjson(c:c+8) =
'{"name":"'
420 getreactionsasjson(c:) = trim(reactions(r)%FILE)
421 c = c+len_trim(reactions(r)%FILE)
422 getreactionsasjson(c:c+10) =
'","types":['
425 if(lasttypename /= reactions(r)%TYPE)
then
426 if(lasttypename /=
"")
then
427 getreactionsasjson(c:c+2) =
"]},"
430 lasttypename = reactions(r)%TYPE
431 getreactionsasjson(c:c+8) =
'{"name":"'
433 getreactionsasjson(c:) = trim(reactions(r)%TYPE)
434 c = c+len_trim(reactions(r)%TYPE)
435 getreactionsasjson(c:c) =
'"'
441 getreactionsasjson(c:c+11) =
',"xUnits":["'
443 getreactionsasjson(c:) = reactions(r)%X1UNITS
444 c = c+len_trim(reactions(r)%X1UNITS)
445 if(reactions(r)%M > 0)
then
446 getreactionsasjson(c:c+2) =
'","'
448 getreactionsasjson(c:) = reactions(r)%X2UNITS
449 c = c+len_trim(reactions(r)%X2UNITS)
451 getreactionsasjson(c:c+1) =
'"]'
454 getreactionsasjson(c:c+16) =
',"xQuantities":["'
456 getreactionsasjson(c:) = reactions(r)%X1QUANTITY
457 c = c+len_trim(reactions(r)%X1QUANTITY)
458 if(reactions(r)%M > 0)
then
459 getreactionsasjson(c:c+2) =
'","'
461 getreactionsasjson(c:) = reactions(r)%X2QUANTITY
462 c = c+len_trim(reactions(r)%X2QUANTITY)
464 getreactionsasjson(c:c+1) =
'"]'
467 getreactionsasjson(c:c+4) =
',"n":'
469 write(getreactionsasjson(c:c+1),
'(I2)') reactions(r)%N
472 getreactionsasjson(c:c+4) =
',"m":'
474 write(getreactionsasjson(c:c+2),
'(I2)') reactions(r)%M
477 getreactionsasjson(c:c+13) =
',"reactions":['
480 getreactionsasjson(c:c) =
","
483 getreactionsasjson(c:c) =
"{"
486 write(getreactionsasjson(c:c+7),
'(A)')
'"creac":'
488 if(
allocated(reactions(r)%CREAC))
then
489 if(reactions(r)%M == 0)
then
493 write(getreactionsasjson(c:),
'(A)')
'['
495 do m = 0, reactions(r)%M
497 getreactionsasjson(c:c) =
","
503 write(getreactionsasjson(c:),
'(A)')
']'
507 write(getreactionsasjson(c:c+3),
'(A)')
"null"
514 getreactionsasjson(c:c+1) =
"}"//char(10)
517 end do foreachreaction
519 getreactionsasjson(c:c+5) =
"]}]}]}"
522 if(debug) print *, c,
"/", len(getreactionsasjson),
"chars written"
subroutine cgi_error(msg, template)
integer, public eiram_unit
Unit to which messages are written.
integer, parameter output_no_header
subroutine, public eiram_load(filePath, fileName, err)
Initialization of the module from input files (data sets)
subroutine, public eiram_deallocate(err)
Deallocate dynamic arrays used by this module.
subroutine getcsvparameter(dict, parameterName, errMsg, values, nValues)
Parse values of a comma separated CGI parameter.
subroutine sendavailablereactions()
Send the list of all available reactions to the server.
subroutine getpoints(fileName, reactionType, reactionIndex, arg1s_str, arg2s_str, xs, ys)
Calculate the points for the given reaction and arguments.
subroutine cgi_begin(html, dict, luout)
subroutine initallfiles()
Initialize EIRAM with all available data.
subroutine eiram_matlab_calc2(Y, X1, X2, M, N, fileName, reactionType, reactionIndex, err)
Binding for eiram_calc2 which has to be called from Matlab/Octave interface.
subroutine split(string, c, array)
Split one line into individual strings for each comma separated substring.
subroutine, public eiram_json_writejsonstringproperty(name, value, jsonString, ind)
Write a pair of the JSON property-(string-)values into a string, including leading comma...
character(1024 *n) function getreactionsasjson(REACTIONS, N, err)
Transfer reactions stored in the arrays REACTIONS into a string which represents a JSON (JavaScript O...
subroutine parsevector(strArr, realArr)
Converts octave-like string vector representation into an array of reals.
subroutine, public eiram_create_image(data, err)
Create a copy (image) of the reactions array stored in the module.
character(dict_value_length *2) function getlastmessage()
Return two last lines printed into the temporary output unit.
subroutine eiram_matlab_calc1(Y, X, N, fileName, reactionType, reactionIndex, err)
Binding for eiram_calc1 which has to be called from Matlab/Octave interface.
integer, parameter dict_value_length
character(size(arr)*(itol+9)+2) function, public eiram_json_getarrayasjson(arr, length, itol)
Return a JSON array string (ie. "[…]") with the elements of the given array arr. ...
character(150+2 *(14 *size(xs)+2)) function pointstojsonstring(fileName, reactionType, reactionIndex, xs, ys)
Return a string which represents a JSON object suitable for plotting of the given reaction data...