function create_index,a,nrec,update=update,outfile=outfile ; These constants should be changed in coordination with ARCHIVE nbytperentry = 38 ; NB: This list should be of even number. If it is not, add a zero to the end. template_codes = [!SEGM.GPARM, !SEGM.TPCAL,!SEGM.AMPCAL,$ !SEGM.PHZCAL,!SEGM.EPHEM,!SEGM.TPUPD] n_templ = n_elements(template_codes) ; As a precaution, check that there is not already an INDEX segment rec = (find_index(a,nrec) - 1)[0] indrec = nrec if (keyword_set(update) and rec ne -2) then begin indrec = rec ; INDEX segment exists, but we want to update it endif else begin if (rec ne -2) then return,rec+1 ; INDEX segment already exists, so return its rec # endelse ; It did not already exist, so try to create one ; First open file for update and try to append an empty record, to see if it is ; possible to write to the file (it may be on read-only media). ; Get the file name associated with ASSOC variable A (note it is dangerous ; to parse the HELP command output like this...) help,a,output=afile afile = afile[0] bra = strpos(afile,'<')+1 ket = strpos(afile,'>') filename = strmid(afile,bra,ket-bra) ; If the OUTVAR is not set, then we are writing the INDEX record to the existing ; file, so take care of some things for this case. if (not keyword_set(outfile)) then begin ; Check if this is a readonly file, in which case we cannot add or ; update the INDEX records. if (is_rd_only(filename)) then goto,skip if (indrec eq nrec) then begin ; Check if the last record of the file is an EOF record (a few were written ; with EOF = 100, now EOF = 17). If so, decrement NREC so that the EOF will ; be overwritten. tls = tl_decode(a(nrec-1)) if (tls.segmentcode eq !SEGM.EOF or tls.segmentcode eq 100) then nrec = nrec-1 indrec = nrec endif ; Seems to have worked, so it is worthwhile to create the index record ; Index record number will be just NREC+1 openu,lun,/get_lun,filename b = assoc(lun,intarr(1024)) ; Associate a second variable B to the file endif else begin ; OUTFILE is set, so we are writing to a new file. openw,olun,/get_lun,outfile b = assoc(olun,intarr(1024)) indrec = 0 endelse ; Generate the T/L field and the template for the scan entries data = a(0) tls = tl_decode(data) tls.segmentcode = 16 ; INDEX segment tls.scancode = 1 ; TEST scan (scan number is not defined for INDEX) tls.nrc = indrec+1 ; Current record number tls.nro = 0 ; Original record number (not defined) tls.nrs = 1 ; Which record of the segment this is (1st) ; Encode changed T/L field back to binary data tlsdat = tl_encode(tls) ; Create blank record and start filling it in data = intarr(1024) data[0:11] = tlsdat data[12] = uint(ishft(n_templ,8) + nbytperentry) ; Fill in template bytes for i = 0, n_templ-1, 2 do begin data[13+i/2] = uint(ishft(template_codes[i+1],8) + template_codes[i]) endfor ; Pointer to start of next INDEX entry inext = 13+n_templ/2 ; Save "boiler plate" info that gets written to each record bplate = data[12:inext-1] ; Get the list of scan headers and segments not in a scan seglist = get_segments(a,nrec) ntot = findsegentries(seglist,ihed,iseg) nhed = n_elements(ihed) nseg = n_elements(iseg) recs = intarr(n_templ) ; Template record numbers id = progmeter(/init) ; Loop over scan headers for i = 0, nhed-1 do begin res = progmeter(id,i*1.0/ntot) if (ihed[i] ne -1) then begin ; Get info from each scan for index entries ; Get start and end record numbers reads,seglist[ihed[i]],srec,erec,format='(13X,I5,1X,I5)' ; Get start and end date and time tdata = a(srec-1) scansegcodes = tdata[2] tlsnew = tl_decode(tdata) syr = tlsnew.year sday = tlsnew.day smsec = tlsnew.msec tdata = a(erec-1) tlsnew = tl_decode(tdata) eyr = tlsnew.year eday = tlsnew.day emsec = tlsnew.msec ; Get TRAJECTORY segment for source name and pointing offsets trec = findseg(a,srec,nrec,!SEGM.TRAJ) if (trec eq -1) then begin ; No TRAJECTORY structure, so fill in with nominal. bytsrcnam = byte('<UNKNOWN> ') srcnamdat = uintarr(6) ; Pack 2-byte data with byte-character data from sourcename for j = 0, 5 do begin srcnamdat[j] = ishft(uint(bytsrcnam[j*2+1]),8) + uint(bytsrcnam[j*2]) endfor hao = 0 deco = 0 endif else begin tdata = a(trec-1) srcnamdat = tdata[12:17] traj = decode(tdata,!SEGM.TRAJ) hao = uint((*traj.pha)[ 0]) ; HA offset [mdeg] deco = uint((*traj.pdec)[0]) ; Dec offset [mdeg] endelse ; Get the start records of the appropriate segments from the template. ; If no appropriate record is found within the scan, FINDSEG returns ; -1, in which case the next earlier relevant record number is used. for j = 0, n_templ-1 do recs[j] = recs[j] > findseg(a,srec,nrec,template_codes[j]) ; Finally have all of the info, so create the INDEX entry for this scan data[inext] = scansegcodes data[inext+1] = srec data[inext+2] = erec data[inext+3] = syr data[inext+4] = sday data[inext+5:inext+6] = [uint(smsec),ishft(smsec,-16)] data[inext+7] = eyr data[inext+8] = eday data[inext+9:inext+10] = [uint(emsec),ishft(emsec,-16)] data[inext+11:inext+16] = srcnamdat data[inext+17] = hao data[inext+18] = deco for j = 0, n_templ-1 do data[inext+19+j] = recs[j] ; That INDEX entry is complete. Advance the pointer for the next ; INDEX entry and check that it has not filled the current record inext = inext+nbytperentry/2+n_templ if (inext + nbytperentry/2 + n_templ gt 1024) then begin ; The next entry is not going to fit into this record, so ; write it to the file and prepare a new one b(indrec) = data ; Write out current record indrec = indrec + 1 ; Increment total number of records tls.nrc = indrec+1 ; Current record number tls.nro = 0 ; Original record number (not defined) tls.nrs = tls.nrs+1 ; Which record of the segment this is ; Encode changed T/L field back to binary data tlsdat = tl_encode(tls) data = intarr(1024) ; Zero the next record data[0:11] = tlsdat ; Entry T/L Field inext = 13+n_templ/2 ; Starting pointer for this record data[12:inext-1] = bplate ; Insert "boiler plate" info endif endif endfor res = progmeter(id,nhed*1.0/ntot) nstarted = tls.nrs ; Scans are all done. Write out blank records to a total of 9 for i = 0, 9-nstarted do begin b(indrec) = data ; Write out current (partially filled) record indrec = indrec + 1 ; Increment total number of records tls.nrc = indrec+1 ; Current record number tls.nro = 0 ; Original record number (not defined) tls.nrs = tls.nrs+1 ; Which record of the segment this is ; Encode changed T/L field back to binary data tlsdat = tl_encode(tls) data = intarr(1024) ; Zero the next record data[0:11] = tlsdat ; Entry T/L Field inext = 13+n_templ/2 ; Starting pointer for this record data[12:inext-1] = bplate ; Insert "boiler plate" info endfor ; Now at the last (10th) INDEX segment record. Enter info for special segments for i = 0, nseg-1 do begin res = progmeter(id,(i+nhed)*1.0/ntot) if (iseg[i] ne -1) then begin ; Get info from each scan for index entries ; Get start record number reads,seglist[iseg[i]],srec,format='(13X,I5)' ; Get start date and time tdata = a(srec-1) tlsnew = tl_decode(tdata) segcode = tlsnew.segmentcode syr = tlsnew.year sday = tlsnew.day smsec = tlsnew.msec ; Finally have all of the info, so create the INDEX entry for this segment data[inext] = segcode data[inext+1] = srec data[inext+2] = syr data[inext+3] = sday data[inext+4:inext+5] = [uint(smsec),ishft(smsec,-16)] ; That INDEX entry is complete. Advance the pointer for the next ; INDEX entry and check that it has not filled the current record inext = inext+6 endif endfor b(indrec) = data indrec = indrec+1 if (n_elements(lun) ne 0) then free_lun,lun if (n_elements(olun) ne 0) then free_lun,olun res = progmeter(id,/destroy) return,indrec skip: ; There was an error opening or writing the file ON_IOERROR,NULL if (n_elements(lun) ne 0) then free_lun,lun if (n_elements(olun) ne 0) then free_lun,olun ans = dialog_message(['CREATE_INDEX: An error occurred in trying to write the',$ 'INDEX segment. The file may be on read-only media.'],/error) return,-1 en