include include include "identify.h" # ID_MAPLL -- Read the line list into memory. procedure id_mapll (id) pointer id # Identify structure int fd, nalloc, nlines pointer ll, lll, str double value bool streq() int open(), fscan(), nscan(), nowhite() errchk open, fscan, malloc, realloc begin call id_unmapll (id) if (nowhite (ID_COORDLIST(id), ID_COORDLIST(id), ID_LENSTRING) == 0) return iferr (fd = open (ID_COORDLIST(id), READ_ONLY, TEXT_FILE)) { call erract (EA_WARN) return } ID_COORDSPEC(id) = EOS call malloc (str, SZ_LINE, TY_CHAR) nalloc = 0 nlines = 0 while (fscan (fd) != EOF) { call gargwrd (Memc[str], SZ_LINE) if (nscan() != 1) next if (Memc[str] == '#') { call gargwrd (Memc[str], SZ_LINE) call strlwr (Memc[str]) if (streq (Memc[str], "spectrum")) call gargwrd (ID_COORDSPEC(id), ID_LENSTRING) next } call reset_scan () call gargd (value) if (nscan() != 1) next if (nalloc == 0) { nalloc = 100 call malloc (ll, nalloc, TY_DOUBLE) call calloc (lll, nalloc, TY_POINTER) } else if (nlines == nalloc) { nalloc = nalloc + 100 call realloc (ll, nalloc, TY_DOUBLE) call realloc (lll, nalloc, TY_POINTER) call aclri (Memi[lll+nalloc-100], 100) } Memd[ll+nlines] = value call gargstr (Memc[str], SZ_LINE) call id_label (Memc[str], Memi[lll+nlines]) nlines = nlines + 1 } call mfree (str, TY_CHAR) call close (fd) if (nlines == 0) return call realloc (ll, nlines + 1, TY_DOUBLE) call realloc (lll, nlines + 1, TY_POINTER) Memd[ll+nlines] = INDEFD ID_LL(id) = ll ID_LLL(id) = lll ID_NLL(id) = nlines end # ID_UNMAPLL -- Unmap the linelist. procedure id_unmapll (id) pointer id # Identify structure pointer lll begin if (ID_LL(id) == NULL) return do lll = ID_LLL(id), ID_LLL(id)+ID_NLL(id)-1 call mfree (Memi[lll], TY_CHAR) call mfree (ID_LL(id), TY_DOUBLE) call mfree (ID_LLL(id), TY_POINTER) end # ID_MATCH -- Match current feature against a line list. # # This is extremely inefficient. It can be greatly improved. procedure id_match (id, in, out, label, diff) pointer id # Identify structure double in # Coordinate to be matched double out # Matched coordinate pointer label # Pointer to label real diff # Maximum difference int i, j, nll double delta pointer ll int strlen() begin call mfree (label, TY_CHAR) if (ID_LL(id) == NULL) { out = in return } if (diff < 0.) delta = abs (diff * (FITDATA(id,1) - FITDATA(id,ID_NPTS(id))) / (ID_NPTS(id) - 1)) else delta = diff ll = ID_LL(id) nll = ID_NLL(id) j = max (1, nint (sqrt (real (nll)))) for (i = 0; i < nll && in > Memd[ll+i]; i = i + j) ; for (i = max (0, min (i-1, nll-1)); i > 0 && in < Memd[ll+i]; i = i - 1) ; ll = ll + i if (i < nll-1) { if (abs (in - Memd[ll]) > abs (in - Memd[ll+1])) { i = i + 1 ll = ll + 1 } } if (abs (in - Memd[ll]) <= delta) { out = Memd[ll] ll = Memi[ID_LLL(id)+i] if (ll != NULL) { call malloc (label, strlen (Memc[ll]), TY_CHAR) call strcpy (Memc[ll], Memc[label], ARB) } } end # ID_LINELIST -- Add features from a line list. procedure id_linelist (id) pointer id # Identify structure int i, nfound, nextpix, lastpix, cursave double cd, pix, fit, fit1, fit2, user, peak, minval, diff, diff1 pointer sp, pixes, fits, users, labels, ll, lll, label double id_center(), fit_to_pix(), id_fitpt(), id_peak() int ncandidate, nmatch1, nmatch2 common /llstat/ ncandidate, nmatch1, nmatch2 begin if (ID_LL(id) == NULL) return call smark (sp) call salloc (pixes, ID_MAXFEATURES(id), TY_DOUBLE) call salloc (fits, ID_MAXFEATURES(id), TY_DOUBLE) call salloc (users, ID_MAXFEATURES(id), TY_DOUBLE) call salloc (labels, ID_MAXFEATURES(id), TY_POINTER) ncandidate = 0 nmatch1 = 0 nmatch2 = 0 nfound = 0 lastpix = 0 minval = MAX_REAL if (ID_MATCH(id) < 0.) cd = (FITDATA(id,1) - FITDATA(id,ID_NPTS(id))) / (ID_NPTS(id) - 1) else cd = 1 fit1 = min (FITDATA(id,1), FITDATA(id,ID_NPTS(id))) fit2 = max (FITDATA(id,1), FITDATA(id,ID_NPTS(id))) ll = ID_LL(id) lll = ID_LLL(id) while (!IS_INDEFD(Memd[ll])) { user = Memd[ll] label = Memi[lll] ll = ll + 1 lll = lll + 1 if (user < fit1) next if (user > fit2) break ncandidate = ncandidate + 1 pix = id_center (id, fit_to_pix (id, user), ID_FWIDTH(id), ID_FTYPE(id)) if (!IS_INDEFD(pix)) { fit = id_fitpt (id, pix) diff = abs ((fit - user) / cd) if (diff > abs (ID_MATCH(id))) next nmatch1 = nmatch1 + 1 if (lastpix > 0) { if (abs (pix - Memd[pixes+lastpix-1]) < 0.01) { diff1 = abs (Memd[fits+lastpix-1]-Memd[users+lastpix-1]) if (diff < diff1) { Memd[pixes+lastpix-1] = pix Memd[fits+lastpix-1] = fit Memd[users+lastpix-1] = user Memi[labels+lastpix-1] = label } next } } nmatch2 = nmatch2 + 1 peak = abs (id_peak (id, pix)) if (nfound < ID_MAXFEATURES(id)) { nfound = nfound + 1 if (peak < minval) { nextpix = nfound minval = peak } Memd[pixes+nfound-1] = pix Memd[fits+nfound-1] = id_fitpt (id, pix) Memd[users+nfound-1] = user Memi[labels+nfound-1] = label lastpix = nfound } else if (peak > minval) { Memd[pixes+nextpix-1] = pix Memd[fits+nextpix-1] = id_fitpt (id, pix) Memd[users+nextpix-1] = user Memi[labels+nextpix-1] = label lastpix = nextpix minval = MAX_REAL do i = 1, nfound { pix = Memd[pixes+i-1] peak = abs (id_peak (id, pix)) if (peak < minval) { nextpix = i minval = peak } } } } } do i = 1, nfound { pix = Memd[pixes+i-1] fit = Memd[fits+i-1] user = Memd[users+i-1] label = Memi[labels+i-1] call id_newfeature (id, pix, fit, user, 1.0D0, ID_FWIDTH(id), ID_FTYPE(id), label) if (i == 1) cursave = ID_CURRENT(id) } ID_CURRENT(id) = cursave call sfree (sp) end