;================================================================================================= ;This file contains procedures necessary for generating jpeg2000 images using the procedure ;AIA_RFILTER. The code has been adapted from the jp2gen archive written by Jack Ireland at NASA ;for the Helioviewer project (helioviewer.org). Procedure names have been appended with _rfilter ;to avoid possible namespace conflicts with jp2gen in the future. See header of AIA_RFILTER for ;additional information. ;================================================================================================= ; ;================================================================================================= FUNCTION HV_WRITTENBY_RFILTER ; ; 7 April 09 ; ; Edit this file to reflect your local conditions. ; ; local: local contact details ; institute: your institute, e.g., NASA-GSFC, LMSAL, SAO, Royal Observatory of Belgium ; contact: the person responsible for the creation of the JP2 files at your institute ; kdu_lib_location: where your installation of the Kakadu library is, if you choose to use Kakadu instead of IDL to create JP2 files ; ; transfer: details on the transfer of JP2 files from their creation location to their storage location ; local: details required by JP2Gen about the local/creation computer and user ; group: the *nix group the jp2 files originally belong to ; tcmd_linux: the transfer command used by linux installations (should not need to change this) ; tcmd_osx: the transfer command used by Mac OS X installations (should not need to change this) ; remote: details required by JP2Gen about the remote/storage computer and user ; user: the remote user account ; machine: the name of the machine ; incoming: the incoming directory where the files will be stored ; group: the remote group name required by the rest of the Helioviewer Project ; ; webpage: the location of the JP2Gen monitoring webpage. ; This webpage will allow you to monitor file creation and transfer services of your JP2 installtion ; answer = {local:{institute:'Smithsonian Astrophysical Observatory (SAO)',$ contact:'SSXG (ssxgadmin@head.cfa.harvard.edu)',$ kdu_lib_location:'/home/jsattelb/JHelioviewer/Libs/',$ jp2gen_write:'/home/jsattelb/IDLWorkspace/hvs_sao_aia/jp2gen_write/',$ jp2gen:'/home/jsattelb/IDLWorkspace/hvs_sao_aia/jp2gen/'},$ transfer:{local:{group:'solar',$ tcmd_linux:'rsync',$ tcmd_osx:'/usr/bin/rsync'},$ remote:{user:'jsattelb',$ machine:'tardigrade.cfa.harvard.edu',$ incoming:'/home/jsattelb/incoming/',$ group:'solar'}},$ webpage:'/home/jsattelb/public_html/hvs_sao_aia/',$ manual_revision_number:'84 [2011/01/10, https://launchpad.net/jp2gen]'} return,answer END ;================================================================================================= ; ;================================================================================================= FUNCTION HVS_GEN_RFILTER ; ; ; Function which defines various parameters for GEN ; ; ; Details on how to transfer data from the production machine to the ; server ; ; As of 2010/03/24 the commands used are ; ; chown -R : ; rsync -Ravxz --exclude "*.DS_Store" -e ssh -l ; @ : ; ; Note that ; ; (1) local and remote computers MUST have the same group with the ; SAME group IDs and group names ; (2) the owner of the JP2 files MUST be member of that group on both ; the LOCAL machine and the REMOTE machine ; ; Linux gotcha: Ubuntu 9.10 (2010/03/24) requires that the JP2 ; creation machine be RESTARTED before the group assignment for a user ; is recognized by the system. For example, if you attempt to put ; a user into a group, then the change only "sticks" after a restart. ; This is important for the current application as you want the ; username on both the local and remote machines to be in the same groups. ; ; ; Everything below here should not be changed except by the JP2Gen source ; ----------------------------------------------------------------------- ; ; Get the source details ; wby = hv_writtenby_rfilter() loc = wby.local.jp2gen ; Jonathan Sattelberger (JPS) 2011/02/09 ; Hard-coded JP2GEN Branch Version in use at SAO/SSXG for J2000 genreation. ; This is a goal for SolarSoft as well. ;bzr_revno = HV_BZR_REVNO_HANDLER(loc) bzr_revno = wby.manual_revision_number ;; hv_writtenby_rfilter source = {institute:'NASA-GSFC',$ contact:'ESA/NASA Helioviewer Project [contact the Helioviewer Project at webmaster@helioviewer.org]',$ all_code:'https://launchpad.net/helioviewer',$ jp2gen_code:'https://launchpad.net/jp2gen',$ jp2gen_version:'0.8',$ jp2gen_branch_revision:bzr_revno} ; ; Set up default values for JP2 compression ; d = {measurement: "", n_levels: 8, n_layers: 8, idl_bitdepth: 8, bit_rate: [0.5,0.01]} a = replicate( d , 1 ) ; ; Not given flag ; notgiven = 'NotGiven' ; ; Construct the return value ; b = {details:a,$ observatory:notgiven,$ instrument:notgiven,$ detector:notgiven,$ web:'~/Desktop/',$ already_written:'already_written',$ na:'not_applicable',$ notgiven:notgiven,$ minusonestring:'-1',$ exact:'exact',$ range:'range',$ time:['ccsds'],$ source:source} ; ; Default values for compression ; b.details[0].measurement = 'NotGiven'; REQUIRED b.details[0].n_levels = 8 ; REQUIRED b.details[0].n_layers = 8 ; REQUIRED b.details[0].idl_bitdepth = 8 ; REQUIRED ;b.details[0].bit_rate = [0.5,0.01] ; REQUIRED b.details[0].bit_rate = [1.0,0.01] ; REQUIRED return,b end ;================================================================================================= ; ;================================================================================================= function hvs_default_aia_rfilter ;+ ; hvs_default_sao_aia.pro ; Version 4.0 ; 2010-09-01: Initial version ; 2010-10-30: Adjusted min. max. and scaling type by taking a sum of images over a flare event. ; 2010-10-31: Followed the DS9 for scaling (LOG10 and Power Law), added the constant A to the scaling structure. ; 2010-11-17: Added gamma to the scaling structures. They should be set to 1.0, but you never know. ; 2011-01-11: Jonathan Sattelberger (JS): Obtained the latest branch of jp2gen (date: 2010-01-10)/ ; Reworking the entire layout of the code, so it will be more streamlined. ; Added fixImageValue to the scaling structure, but it's not used in hvs_sao_aia_list2jp2.pro ;- on_error, 2 g = hvs_gen_rfilter() d = { measurement: "", $ n_levels: 8, $ n_layers: 8, $ idl_bitdepth: 8, $ bit_rate: [1.0,0.01], $ dataMin:0.0, $ dataMax:0.0, $ dataScalingType:0, $ dataExptime:0.0, $ gamma:1.0, $ a:100.0, $ fixedImageValue:[-1,-1] $ ; [0, 500000] } a = replicate(d,10) b = { details:a, $ ; REQUIRED observatory:'SDO', $ ; REQUIRED instrument:'AIA', $ ; REQUIRED detector:'AIA', $ ; REQUIRED nickname:'AIA', $ ; REQUIRED hvs_details_filename:'hvs_default_sao.pro', $ ; REQUIRED hvs_details_filename_version:'4.0' $ ; REQUIRED } ; ; 0094 ; b.details[0].measurement = '94'; REQUIRED b.details[0].n_levels = 8 ; REQUIRED b.details[0].n_layers = 8 ; REQUIRED b.details[0].idl_bitdepth = 8 ; REQUIRED b.details[0].bit_rate = [1.0,0.01] ; REQUIRED b.details[0].dataMin = 0.25 b.details[0].dataMax = 2080.0 b.details[0].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[0].dataExptime = 4.99803 b.details[0].gamma = 1.0 b.details[0].a = 1000.0 b.details[0].fixedImageValue = [-1,-1] ; ; 0131 ; b.details[1].measurement = '131'; REQUIRED b.details[1].n_levels = 8 ; REQUIRED b.details[1].n_layers = 8 ; REQUIRED b.details[1].idl_bitdepth = 8 ; REQUIRED b.details[1].bit_rate = [1.0,0.01] ; REQUIRED b.details[1].dataMin = 2.0 b.details[1].dataMax = 2800.0 b.details[1].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[1].dataExptime = 6.99685 b.details[1].gamma = 1.0 b.details[1].a = 100.0 b.details[1].fixedImageValue = [-1,-1] ; ; 0171 ; b.details[2].measurement = '171'; REQUIRED b.details[2].n_levels = 8 ; REQUIRED b.details[2].n_layers = 8 ; REQUIRED b.details[2].idl_bitdepth = 8 ; REQUIRED b.details[2].bit_rate = [1.0,0.01] ; REQUIRED b.details[2].dataMin = 15.0 b.details[2].dataMax = 25600.0 b.details[2].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[2].dataExptime = 4.99803 b.details[2].gamma = 1.0 b.details[2].a = 100.0 b.details[2].fixedImageValue = [-1,-1] ; ; 0193 ; b.details[3].measurement = '193'; REQUIRED b.details[3].n_levels = 8 ; REQUIRED b.details[3].n_layers = 8 ; REQUIRED b.details[3].idl_bitdepth = 8 ; REQUIRED b.details[3].bit_rate = [1.0,0.01] ; REQUIRED b.details[3].dataMin = 11.0 b.details[3].dataMax = 18000.0 b.details[3].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[3].dataExptime = 2.99950 b.details[3].gamma = 1.0 b.details[3].a = 100.0 b.details[3].fixedImageValue = [-1,-1] ; ; 0211 ; b.details[4].measurement = '211'; REQUIRED b.details[4].n_levels = 8 ; REQUIRED b.details[4].n_layers = 8 ; REQUIRED b.details[4].idl_bitdepth = 8 ; REQUIRED b.details[4].bit_rate = [1.0,0.01] ; REQUIRED b.details[4].dataMin = 8.0 b.details[4].dataMax = 16220.0 b.details[4].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[4].dataExptime = 4.99801 b.details[4].gamma = 1.0 b.details[4].a = 100.0 b.details[4].fixedImageValue = [-1,-1] ; ; 0304 ; b.details[5].measurement = '304'; REQUIRED b.details[5].n_levels = 8 ; REQUIRED b.details[5].n_layers = 8 ; REQUIRED b.details[5].idl_bitdepth = 8 ; REQUIRED b.details[5].bit_rate = [1.0,0.01] ; REQUIRED b.details[5].dataMin = 30.0 b.details[5].dataMax = 2000.0 b.details[5].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[5].dataExptime = 4.99441 b.details[5].gamma = 1.0 b.details[5].a = 100.0 b.details[5].fixedImageValue = [-1,-1] ; ; 0335 ; b.details[6].measurement = '335'; REQUIRED b.details[6].n_levels = 8 ; REQUIRED b.details[6].n_layers = 8 ; REQUIRED b.details[6].idl_bitdepth = 8 ; REQUIRED b.details[6].bit_rate = [1.0,0.01] ; REQUIRED b.details[6].dataMin = 2.0 b.details[6].dataMax = 1600.0 b.details[6].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[6].dataExptime = 6.99734 b.details[6].gamma = 1.0 b.details[6].a = 100.0 b.details[6].fixedImageValue = [-1,-1] ; ; 1600 ; b.details[7].measurement = '1600'; REQUIRED b.details[7].n_levels = 8 ; REQUIRED b.details[7].n_layers = 8 ; REQUIRED b.details[7].idl_bitdepth = 8 ; REQUIRED b.details[7].bit_rate = [1.0,0.01] ; REQUIRED b.details[7].dataMin = 5.0 b.details[7].dataMax = 8800.0 b.details[7].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[7].dataExptime = 2.99911 b.details[7].gamma = 1.0 b.details[7].a = 100.0 b.details[7].fixedImageValue = [-1,-1] ; ; 1700 ; b.details[8].measurement = '1700'; REQUIRED b.details[8].n_levels = 8 ; REQUIRED b.details[8].n_layers = 8 ; REQUIRED b.details[8].idl_bitdepth = 8 ; REQUIRED b.details[8].bit_rate = [1.0,0.01] ; REQUIRED b.details[8].dataMin = 100.0 b.details[8].dataMax = 32935.0 b.details[8].dataScalingType = 3 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[8].dataExptime = 1.00026 b.details[8].gamma = 1.0 b.details[8].a = 100.0 b.details[8].fixedImageValue = [-1,-1] ; ; 4500 ; b.details[9].measurement = '4500'; REQUIRED b.details[9].n_levels = 8 ; REQUIRED b.details[9].n_layers = 8 ; REQUIRED b.details[9].idl_bitdepth = 8 ; REQUIRED b.details[9].bit_rate = [1.0,0.01] ; REQUIRED b.details[9].dataMin = 0.25 b.details[9].dataMax = 26000.0 b.details[9].dataScalingType = 0 ; 0 - linear, 1 - sqrt, 3 - log10 b.details[9].dataExptime = 1.00026 b.details[9].gamma = 1.0 b.details[9].a = 100.0 b.details[9].fixedImageValue = [-1,-1] return, b end ;================================================================================================= ; ;================================================================================================= FUNCTION HV_PARSE_CCSDS_RFILTER,a ; ; Parse an input CCSDS time into its parts ; milli = strmid(a,20,3) ContainsZ = strpos(milli,'Z') if ContainsZ ne -1 then begin strput,milli,'5',ContainsZ endif b = {yy:strmid(a,0,4),$ mm:strmid(a,5,2),$ dd:strmid(a,8,2),$ hh:strmid(a,11,2),$ mmm:strmid(a,14,2),$ ss:strmid(a,17,2),$ milli:milli} return,b end ;================================================================================================= ; ;================================================================================================= FUNCTION HV_XML_COMPLIANCE_RFILTER,input ; ; Very simple check that the input is compliant with XML standards and ; escape it if need be ; answer = str_replace(input,'<','<') answer = str_replace(answer,'>','>') answer = str_replace(answer,'&','&') ; answer = str_replace(answer,'','&apos') answer = str_replace(answer,'"','"') return,answer end ;================================================================================================= ; ;================================================================================================= FUNCTION AIA_RFILTER_JP2GEN, hd, details_file=details_file ;Function to retreive information required to output jp2s, including the EIT encoding parameters ;and an xml version of the AIA header informaiton with some additional tags. lf = string(10b) g = hvs_gen_rfilter() wby = hv_writtenby_rfilter() wv = strtrim(hd.wavelnth,2) ;retrive the EIT JP2 encoding parameters if not (keyword_set(details_file)) then details_file = 'hvs_default_aia_rfilter' if lmgr(/RUNTIME) then info = hvs_default_aia_rfilter() else info = call_function(details_file) ;load supported measurements measurement_arr = info.details[*].measurement this_measurement = where(measurement_arr eq strtrim(hd.wavelnth,2), this_measurement_count) observation = 'SDO_AIA_AIA' + wv if lmgr(/RUNTIME) then hd.date_obs = hd.DATE_D$OBS tobs = hv_parse_ccsds_rfilter(hd.date_obs) ;Adds header info. hd = add_tag(hd,info.observatory,'hv_observatory') hd = add_tag(hd,info.instrument,'hv_instrument') hd = add_tag(hd,info.detector,'hv_detector') hd = add_tag(hd,wv,'hv_measurement') hd = add_tag(hd,0.0,'hv_rotation') hd = add_tag(hd,'aia_rfilter','hv_source_program') hv_comment = 'JP2 file created locally at ' + wby.local.institute + $ ' using '+ 'aia_rfilter' + ' at ' + systime() + '.' + lf + $ 'Contact ' + wby.local.contact + $ ' for more details/questions/comments regarding this JP2 file.'+lf hv_comment = hv_comment + 'HVS (Helioviewer setup) file used to create this JP2 file: ' + $ info.hvs_details_filename + ' (version ' + info.hvs_details_filename_version + ').'+lf hv_comment = HV_XML_COMPLIANCE_RFILTER(hv_comment + $ 'FITS to JP2 source code provided by ' + g.source.contact + $ '[' + g.source.institute + ']'+ $ ' and is available for download at ' + g.source.jp2gen_code + '.' + lf + $ 'Please contact the source code providers if you suspect an error in the source code.' + lf + $ 'Full source code for the entire Helioviewer Project can be found at ' + g.source.all_code + '.') if tag_exist(hd,'hv_comment') then begin hv_comment = HV_XML_COMPLIANCE_RFILTER(hd.hv_comment) + lf + hv_comment endif xh = '' ntags = n_tags(hd) tagnames = tag_names(hd) tagnames = HV_XML_COMPLIANCE_RFILTER(tagnames) jcomm = where(tagnames eq 'COMMENT') jhist = where(tagnames eq 'HISTORY') jhv = where(strupcase(strmid(tagnames[*],0,3)) eq 'HV_') jhva = where(strupcase(strmid(tagnames[*],0,4)) eq 'HVA_') indf1=where(tagnames eq 'TIME_D$OBS',ni1) if ni1 eq 1 then tagnames[indf1]='TIME-OBS' indf2=where(tagnames eq 'DATE_D$OBS',ni2) if ni2 eq 1 then tagnames[indf2]='DATE-OBS' xh=''+lf xh+=''+lf xh+=' '+lf for j=0,ntags-1 do begin if ((where(j eq jcomm) eq -1) and (where(j eq jhist) eq -1) $ and (where(j eq jhv) eq -1) and (where(j eq jhva) eq -1)) then begin value = HV_XML_COMPLIANCE_RFILTER(strtrim(string(hd.(j)),2)) xh+=' <'+tagnames[j]+'>'+value+''+lf endif endfor xh+=' '+lf j=jhist k=0 while (hd.(j))[k] ne '' do begin value = HV_XML_COMPLIANCE_RFILTER((hd.(j))[k]) xh+=value+lf k=k+1 endwhile xh+=' '+lf xh+=' '+lf j=jcomm k=0 while (hd.(j))[k] ne '' do begin value = HV_XML_COMPLIANCE_RFILTER((hd.(j))[k]) xh+=value+lf k=k+1 endwhile xh+=' '+lf xh+=' '+lf xh+=' '+lf xh+=' '+HV_XML_COMPLIANCE_RFILTER(strtrim(string(hd.hv_rotation),2))+''+lf xh+=' '+HV_XML_COMPLIANCE_RFILTER(trim(g.source.jp2gen_version))+''+lf xh+=' '+HV_XML_COMPLIANCE_RFILTER(trim(g.source.jp2gen_branch_revision))+''+lf xh+=' '+HV_XML_COMPLIANCE_RFILTER(trim(info.hvs_details_filename))+''+lf xh+=' '+HV_XML_COMPLIANCE_RFILTER(trim(info.hvs_details_filename_version))+''+lf xh+=' '+hv_comment+''+lf xh+=' TRUE'+lf xh+=' '+lf xh+=''+lf jp2gen_info = {bit_rate:info.details[this_measurement].bit_rate,n_layers:info.details[this_measurement].n_layers, $ n_levels:info.details[this_measurement].n_levels,bit_depth:info.details[this_measurement].idl_bitdepth, $ header:xh} return, jp2gen_info end ;=================================================================================================