/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "denplo.p" */ #include /* denplo: density plot in color Dr. Thomas D. Schneider National Institutes of Health National Cancer Institute Center for Cancer Research Nanobiology Program Molecular Information Theory Group Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.ccrnp.ncifcrf.gov/~toms/ */ /* end of program */ /* begin module version */ #define version 2.01 /* of denplo.p 2009 Apr 13 2009 Apr 13, 2.01: set BinMax in parameters 2009 Apr 11, 2.00: extend cutoff parameter too range 2009 Apr 02, 1.99: '('and')' in denploxyplop should NOT be protected with '\'! 2007 Jan 10, 1.98: fix putreal - taken from makelogo 2005 Dec 29, 1.97: spelling brightness 2005 Jun 1, 1.96: If the peak search starts outside the range of the data, just give a warning and then let it do the best it can. 2005 May 31, 1.95: more information when peak search fails 2005 May 29, 1.94: correct denplop upgrade to include SearchRange 2005 May 29, 1.93: make output file not wrap lines 2005 May 29, 1.92: make xyplop file not wrap lines 2005 Mar 30, 1.91: allow thelinewidth to be < 0 (no line around key boxes) 2004 Aug 2, 1.90: prepare xyin output for use by gnuplot: blanks, # 2004 Aug 1, 1.89: cleanup 2004 Aug 1, 1.88: cleanup 2004 Aug 1, 1.87: success! 2004 Aug 1, 1.86: SearchRange made into a parameter 2004 Aug 1, 1.85: peak finding algorithm is functional, black if exceeded! 2004 Aug 1, 1.84: core algorithm finds a near by peak! 2004 Aug 1, 1.83: test core algorithm! (stupid bug fixed) 2004 Aug 1, 1.82: test core algorithm! 2004 Aug 1, 1.81: Begin core algorithm! (report global max is ok) 2004 Aug 1, 1.80: allow switch to local max, set up initial Xbin,Ybin. 2004 Aug 1, 1.79: start to set up local maximum computation 2004 Jul 31, 1.78: set up local maxima variables 2004 Jul 31, 1.77: goal: find local maxima 2004 Feb 11, 1.76: cleanup 2004 Feb 11, 1.75: debugging ... 2004 Feb 11, 1.74: black strip bug: truncation problem in computing the bin 2004 Jan 20, 1.73: denplop.ri-example 2004 Jan 19, 1.72: complete keyintervals 2004 Jan 19, 1.71: make keyintervals logical 2004 Jan 19, 1.70: edge adjustment!! 2004 Jan 19, 1.69: fraction mode bug; using hue*0.84+0.16 2004 Jan 19, 1.68: brush up example documentation 2004 Jan 19, 1.67: clean up 2004 Jan 19, 1.66: implement reading color key parameters 2004 Jan 19, 1.65: color key parameters documented 2004 Jan 19, 1.64: color key matrix fully matches counts 2004 Jan 19, 1.63: color key max solved: must account for xyplo colors! 2004 Jan 19, 1.62: color key max is off, key numbers given. 2004 Jan 19, 1.61: color key max is off. 2004 Jan 19, 1.60: color key zero is correct. 2004 Jan 19, 1.59: color key partially functional 2004 Jan 19, 1.58: create color key in xyplom 2004 Jan 19, 1.57: change from rounding to truncating to drop into bins 2003 Aug 31, 1.56: Yintervals or Xintervals may be 1 2003 Aug 31, 1.53: MaxDisplayIntervals -> XDisplayIntervals YDisplayIntervals 2003 Aug 31, 1.52: greyscale or color parameter: cog 2003 Aug 31, 1.51: fix module structure at postscriptstring 2003 Aug 30, 1.50: need enough decimals in denploxyin to accurately plot! 2003 Aug 30, 1.49: link for movie 2003 Aug 30, 1.48: refine documentation - denplo.data example 2003 Aug 30, 1.47: catch unused variable 2003 Aug 30, 1.46: Upgrade documentation, rename xyin denploxyin 2003 Aug 30, 1.45: add denplo.gif 2003 Aug 28, 1.44: compiling ... 2003 Aug 28, 1.43: necessary prgmod functions in ... 2003 Aug 28, 1.42: begin to create \t and \b functions ... 2003 Aug 28, 1.41: cleanup 2003 Aug 28, 1.40: rearrange xyin columns (and denxyplop) 2003 Aug 28, 1.39: cutoff is either counts or fraction of max 2003 Aug 28, 1.38: controls for X and Y axis labels (import strings) 2003 Aug 28, 1.37: controls for X and Y axis labels (documentation) 2003 Aug 28, 1.36: cleanup 2003 Aug 28, 1.35: background coloring functions. 2003 Aug 28, 1.34: correct background coloring 2003 Aug 28, 1.33: tie up loose ends; bins not filled correctly 2003 Aug 28, 1.32: correct placement of shrunken squares! 2003 Aug 28, 1.31: fine adjusting xyplop and other parameters 2003 Aug 28, 1.30: make sure intervals is as requested 2003 Aug 28, 1.29: lovely!! clean up 2003 Aug 28, 1.28: positioning with shrinkfactorX and shrinkfactorY 2003 Aug 28, 1.27: shrinkfactorX and shrinkfactorY 2003 Aug 28, 1.26: bug: SymbolSizeX and SymbolSizeY is jumpX, jumpY ... 2003 Aug 28, 1.25: bug: SymbolSizeX and SymbolSizeY are negative! 2003 Aug 28, 1.24: bug: location of squares is off ... 2003 Aug 28, 1.23: smart crosshairs 2003 Aug 28, 1.22: xyplop output is now called denploxyplop, crosshairs 2003 Aug 27, 1.21: MaxIntervals renamed MaxDisplayIntervals 2003 Aug 27, 1.20: cleanup 2003 Aug 27, 1.19: document fillonedatum error condition situation better 2003 Aug 24, 1.18: cutoffvalue 2003 Aug 24, 1.17: control over background where there are no data. 2003 Aug 24, 1.16: bug: always squares: SymbolSizeY not set correctly 2003 Aug 24, 1.15: further testing, MaxDisplayIntervals reinstated, documented. 2003 Aug 24, 1.14: cleanup; MaxDisplayIntervals variable DROPPED from parmeters. 2003 Aug 24, 1.13: correct location of squares (continued). 2003 Aug 24, 1.12: correct location of squares (continued). 2003 Aug 24, 1.11: correct location of squares again. 2003 Aug 24, 1.10: extend outer edge of graph to cover requested field 2003 Aug 24, 1.09: graph grey over entire requested field 2003 Aug 24, 1.08: report original coordinates AND square corner for plotting 2003 Aug 24, 1.07: streamline the code, center the squares 2001 Aug 4, 1.06: documentation upgrade 2001 Aug 4, 1.05: graph symbolsize under proper control 2001 Aug 4, 1.04: size and corner control 2001 Aug 4, 1.03: the plot is beautiful! 2001 Aug 4, 1.02: beginning to plot ... 2001 Aug 4, 1.01: able to read data ... 2001 Aug 3, 1.00: origin from denri */ #define updateversion 2.00 /* defines lowest acceptable current parameter file */ /* old: updateversion = 1.66; (* defines lowest acceptable current parameter file *) */ /* end module version */ /* begin module describe.denplo */ /* name denplo: density plot in color synopsis denplo(data: in, denplop: in, denploxyin: out, denploxyplom: out, denploxyplop: out, output: out) files data: data pairs denplop: parameters to control the program. The file must contain the following parameters, one per line: 0. parameterversion: The version number of the program. This allows the user to be warned if an old parameter file is used. 1. numbertoprocess: number of data items to process (negative = all) This allows the user to explore a part of a large data set before committing to a long process time. I suppose it would also allow you to make a movie of the data building up! 2. XminValue, XmaxValue, Xintervals: (real, real, integer) range for x, and the number of intervals 3. YminValue, YmaxValue, Yintervals: (real, real, integer) range for Y, and the number of intervals 4. NuWi, NuDe: (integer) define the width and decimal places of output numbers. NuWi = 1, Pascal will give the number out anyway! This is a big space saver. 5. Xcolumn, Ycolumn: (integer) column numbers for X and Y data. They can be in any order. 6. Xsize, Ysize: (real) size of the plotting area, cm. 7. Xcorner, Ycorner: (real) lower left corner of the plotting area, cm. 8. XDisplayIntervals, YDisplayIntervals XDisplaySubIntervals, YDisplaySubIntervals : (integer) Number of numeric intervals for xyplo to display on the axis This keeps the number of numbers on the side of the graph reasonable but does not affect the graph itself. It allows one to have a highly dense plot without labeling every data interval. If one of the DisplayInterval values is less than or equal to zero, then the corresponding bin interval will be used. For example, if XDisplayIntervals = 0 then the display interval used will be given by the value of Xintervals. Sub intervals apply all the time. 9. xwidth, ywidth: (integer) axis number width 10. xdecimal, ydecimal: (integer) axis number decimals 11. background, grey (character, real) color to give when there are no data: b = black g = grey; the grey value is given (between 0.0 and 1.0) w = white c = colorful. For debugging: a complex formula is used to change the colors of squares over the background so one can debug the program. Data are plotted on top of this. So most of the time this option is not useful to people. For white no background square needs to be written, so it isn't. When there are sparse data above the cutoff, this option can be extremely efficient because very little data needs to be written to the denploxyin file. For black, grey or colorful every square is written all the time. 12. cutoffvalue (character, real, [real]): The first character on the line defines the kind of cutoff: 'c': use the number of counts in a bin (one value used) 'f': use the fraction of this bin to the fullest bin (one value used) 'C': range of counts to plot (two values needed) 'F': range of fractions to plot (two values needed) For 'c' and 'f', only one number is needed. The number is the cutoff value. Counts are reported for values higher than or equal to the cutoff. For example, in c mode a zero cutoff will have denplo display cases with 0 or more counts. For 'C' and 'F', two numbers are need, this is the range of counts or fractions to use. 2009 Apr 11: cutoff values are now inclusive, so if a count is 5 and the range is 5 to 10 it will be plotted. 13. shrinkfactorX, shrinkfactorY (real): numbers above zero A value of 1 will make the display be completely covered while one less than 1 will leave gaps that allow one to distinguish between the squares. 14. XaxisLabel: (string, entire line): the label for the x axis. 15. YaxisLabel: (string, entire line): the label for the y axis. 16. cog: (character): color or grey The first character on the line defines the value: 'c': use colors in the spectrum 'g': use grey scale COLOR KEY DISPLAY CONTROLS The color key is a set of rectangles surrounded by a black edge. To the right are numbers that report the density. The numbers can either report the number that the color corresponds to or the density relative to the highest density in the plot. The key is placed into the denploxyplom file where it can then be passed to xyplo as a xyplom file. 17. keyintervals: The number of boxes in the key will be keyintervals+1 (to allow for a zero). If keyintervals is zero, then no color key is shown. Example: To get boxes numbered 0.0, 0.0 ... 10.0, use 10 for keyintervals. 18. keytype (character): f: fraction of maximum, n: raw number. The way to display the key numbers. 19. keyX: X coordinate of the lower left corner of the key (cm) 20. keyY: Y coordinate of the lower left corner of the key (cm) 21. keyXsize: X size of key boxes (cm) 22. keyysize: Y size of key boxes (cm) 23. keyshrinkfactor: a number between 0 and 1 which defines how much the key boxes should shrink. 24. thelinewidth: the width of a line around each key box (cm) If thelinewidth is zero than the line is the default width. If less than zero, no line is drawn. 25. keydecimals: number of decimal places for the numbers placed to the right of each key box. 26. keyfontsize: the font size for the key numbers. 10 is a good place to stat. 27. edgecontrol edgeleft, edgeright, edgelow, edgehigh: edgecontrol is a single character that controls how the bounding box of the figure is handled. If it is 'n' then the bounding box will be the page parameters defined in constants inside the program (llx, lly, urx, ury AND changes as set by the previous parameter line). If the parameter is 'p', there are four real numbers that define the edges around the clist in cm. To allow a map to be imbedded into another figure, its size must be defined in PostScript (with %%BoundingBox). By setting these four numbers, the edges are defined. Negative values are allowed, so one may move the edges as desired. FINDING LOCAL PEAKS 28. findpeak, startX, startY, SearchRange: l: findpeak is a single character for which 'l' means to search for a local peak starting at coordinate (startX, startY) instead of using the global maximum. If the local peak found is not the global maximum, then positions that have more counts than the local peak are shown by black. The search is made in a series of squares, starting at (startX, startY). The side of each square is determined by SearchRange: side = 2*Searchrange+1. That is, if SearchRange = 0, the side is 1 and the peak is set at (startX, startY). When SearchRange = 3, the side is 3 and 9 positions are searched. The square is moved to the position that has the highest local density. This is repeated until no higher position is found. The algorithm is deterministic (no random numbers are used) and the result may depend on the order of scanning the square. maxpeak, BinMax: m: If the first character is 'm' then instead of finding the peak the second parameter is used for the maximum BinMax. This allows one to force the maximum color to be a particular value and so allows comparison of plots on the same scale. denploxyin: control file for xyplo: density of data pairs represented in color. Copy or link this file to xyin. denploxyplom: control file for xyplo: a postscript file that contains marks. It also contains the color key if that is being used. Copy or link this file to xyplom. denploxyplop: control file for xyplo: parameters Copy or link this file to xyplop. Documentation is in the xyplo.p program. output: messages to the user description Denplo takes a file containing pairs of numbers and (using the xyplo program) plots the density of the numbers in color. The user specifies a rectangular region on the X-Y plane. Then each axis is divided into the number of intervals requested by the user. These define a set of data bins onthe X-Y plane. The data are dropped into the bins and counted. The output of denplo consists of the three files that control the xyplo plotting program. For example, one output file is called a denploxypop = a denplo xyplop = density plot, x-y plotter parameter file. This is pronounced 'den-plo-zye-plop'! The denploxyin is 'den-plo-zin' and the denploxyplom is 'den-plo-zye-plom'. :-) Since these are not the names used by xyplo (so that xyplo files are not overwritten), you need to copy (Unix cp) or move (Unix mv) them into the names that xyplo uses: cp denploxyin xyin cp denploxyplom xyplom cp denploxyplop xyplop Then you can run xyplo to get the xyout (xy-out = 'zyout'), which is a eps PostScript file. examples example denplop file: 1.88 0. parameterversion: denplo version this parameter file is designed for -1 1. numbertoprocess: number of data items to process (negative = all) 0 10 10 2. XminValue,XmaxValue,Xintervals: (real,real,integer) X range,ints 0 10 10 3. YminValue,YmaxValue,Yintervals: (real,real,integer) Y range,ints 8 5 4. NumberWidth, NumberDecimals: (integer) 1 2 5. Xcolumn, Ycolumn: (integer) column numbers for X and Y data. 10 10 6. Xsize, Ysize: (real) plotting area, cm 3 7 7. Xcorner, Ycorner: (real) lower left corner of the plotting area, cm. 10 10 2 2 8. X/YDisplayIntervals X/YDisplaySubIntervals 8 8 9. xwidth, ywidth: (integer) axis number width 0 0 10. xdecimal, ydecimal: (integer) axis number decimals g 0.9 11. background: b = black, g = grey, w = white, c = colorful (debug), c 0 100 12. cutofftype [c,f,C,F] cutoffvalue(min and max) 0.8 0.8 13. shrinkfactorX, shrinkfactorY (real) X axis label Y axis label c 16. cog: color or grey plot 5 17. keyintervals: # of boxes in the key (not including the zero) n 18. keytype (character): f: fraction of maximum, n: raw number. 10.2 19. keyX: X coordinate of the lower left corner of the key (cm) 0.1 20. keyY: Y coordinate of the lower left corner of the key (cm) 0.5 21. keyXsize: X size of key boxes (cm) 1.0 22. keyYsize: Y size of key boxes (cm) 0.8 23. keyshrinkfactor: between 0 and 1: box shrink. 0.005 24. thelinewidth: the width of a line around each key box (cm) 1 25. keydecimals: number of decimal places for the key 12 26. keyfontsize: the font size for the key numbers p 1.50 2.50 1.50 1.50 edgecontrol, edgeleft, edgeright, edgelow, edgehigh cm - 0 0 28. findpeak(l), startX, startY, SearchRange | maxpeak(m), BinMax see also {Example data file (copy to 'data' to use):} denplo.data {Example Parameter file:} denplop {Given these two files, you can run denplo. To do this: cp denplo.data data denplo cp denploxyin xyin cp denploxyplom xyplom cp denploxyplop xyplop followed by running} xyplo.p {:} xyplo} {The final results use the general plotting program:} xyplo.p {The resulting example density plot is:} http://www.lecb.ncifcrf.gov/~toms/icons/denplo.gif {--------------------------------------} {a larger example, with large key scale:} denplop.ri-example {--------------------------------------} {Information about PostScript:} http://www.lecb.ncifcrf.gov/~toms/postscript.html {This describes how to convert from PostScript to PDF.} {Program that describes label controls:} makelogo.p {See bugs for further information on this partially implemented feature.} {How to make a movie:} http://www.lecb.ncifcrf.gov/~toms/paper/ev/movie/ {Related density program:} denri.p {Information about the color hue formula:} diana.p xyplo.p author Thomas Dana Schneider bugs Smarter crosshairs: xyplo needs an upgrade so that the crosshairs can be put in for x and y and independently the x and y axes. Then this program could control them. One could implement strings like '\c' within the axes labels to produce data counts into the labels. (A mechanism like that in makelogo could be used.) \t total counts \b maximum bin count \i start italics and end italics The function in makelogo is putreal, inside module makelogo.postscriptstring in makelogo.p. This routine is now in the program but not fully integrated so \t and \b are not available yet. You can, however, do italics and special symbols; instructions are in the makelogo.p program. technical notes Constants set in the program: maxValue is the largest number of allowed bins allowed on each axis. Postscript hue colors range from red (at 0) to red (at 1). To avoid this ambiguity, only part of the hue range is used. I have found that this formula is useful for 0 <= r <= 1: hue := 0.84*r + 0.16. See diana.p and xyplo.p module pic.setcolor. The denploxyplom has this correction built in since the xyplom is not color corrected. For this reason, the values in the color scale in denploxyplom will not match those in the denploxyin. However, when plotted with xyplo they are identical. The edge control method is from xyplo.p. */ /* end module describe.denplo */ /* begin module denplo.const */ #define minValue 0 /* lowest Value allowed (range of data storage) */ #define maxValue 1000 /* highest Value allowed (range of data storage) */ /* The following bounding box is for the Canon Color Laser Copier 1150. */ #define defaultllx 7.10999 /* default for llx, lower left x */ #define defaultlly 7.01995 /* default for lly, lower left y */ #define defaulturx 588.15 /* default for urx, upper right x */ #define defaultury 784.98 /* default for ury, upper right y */ #define komment '#' /* the first character of comments in denploxyin */ /* end module denplo.const */ /* begin module xyplo.interact.const */ #define maxstring 300 /* the maximum string */ /* end module xyplo.interact.const */ /* begin module pic.const */ #define pi 3.14159265354 /* circumference divided by diameter of circle */ #define picwidth 8 /* width of numbers printed to the file */ #define picdecim 5 /* number of decimal places for numbers */ #define charwidth 0.15875 /* the width of characters in cm (ie, cm/char) this allows centering of strings. */ /* note: for the Times-Roman font, 0.0625 is a good value. for the Courier-Bold font, 0.08 is a good value. */ #define dotfactor 0.015875 /* the size of dots */ /* defscale = 72; (* default scale factor. coordinate units per in *) */ #define defscale 28.35 /* default scale factor. coordinate units per cm */ /* making this change would be a big shock to all the programs that use it, unfortunately. A major user is xyplo. */ /* end module pic.const version = 2.73; (@ of dops.p 2003 Aug 28 */ /* begin module interact.type */ /* begin module string.type */ /* pointer to a string */ typedef struct string { /* a string of characters */ Char letters[maxstring]; /* the letters in the string */ long length; /* the number of characters in the string */ long current; /* the letter we are working on */ Char *next; /* the next string in a series */ } string; /* end module string.type version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* end module interact.type version = 7.67; {of delmod.p 2004 Sep 8} */ Static _TEXT data; /* file used by this program */ Static _TEXT denplop; /* file used by this program */ Static _TEXT denploxyin; /* file used by this program */ Static _TEXT denploxyplom; /* file used by this program */ Static _TEXT denploxyplop; /* file used by this program */ Static jmp_buf _JL1; /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ /* begin module halt */ Static Void halt() { /* stop the program. the procedure performs a goto to the end of the program. you must have a label: label 1; declared, and also the end of the program must have this label: 1: end. examples are in the module libraries. this is the only goto in the delila system. */ printf(" program halt.\n"); longjmp(_JL1, 1); } /* end module halt version = 7.67; {of delmod.p 2004 Sep 8} */ /* begin module copyaline */ /* for transfering header info */ Static Void copyaline(fin, fout) _TEXT *fin, *fout; { /* copy a line from file fin to file fout */ while (!P_eoln(fin->f)) { putc(P_peek(fin->f), fout->f); getc(fin->f); } fscanf(fin->f, "%*[^\n]"); getc(fin->f); putc('\n', fout->f); } /* copyaline */ /* end module copyaline version = 7.67; {of delmod.p 2004 Sep 8} */ /* begin module skipblanks */ /* 2003 July 31: tab is considered a blank character */ Static boolean isblank(c) Char c; { /* is the character c blank or tab? */ return (c == ' ' || c == '\t'); } Static Void skipblanks(thefile) _TEXT *thefile; { /* skip over blanks until a non-blank, or end of line, is found */ while (isblank(P_peek(thefile->f)) & (!P_eoln(thefile->f))) getc(thefile->f); } Static Void skipnonblanks(thefile) _TEXT *thefile; { /* skip over nonblanks until a blank, or end of line, is found */ while ((!isblank(P_peek(thefile->f))) & (!P_eoln(thefile->f))) getc(thefile->f); } Static Void skipcolumn(thefile) _TEXT *thefile; { /* skip over a data column */ skipblanks(thefile); skipnonblanks(thefile); } /* end module skipblanks version = 7.67; {of delmod.p 2004 Sep 8} */ /* begin module clearstring */ Static Void clearstring(ribbon) string *ribbon; { /* empty the string */ long index; /* to the ribbon */ for (index = 0; index < maxstring; index++) ribbon->letters[index] = ' '; ribbon->length = 0; ribbon->current = 0; } /* clearstring */ Static Void initializestring(ribbon) string *ribbon; { /* start the string with a nil pointer. This routine should be called before doing linked list work. This allows the standard string routines to clear the string without killing the pointer. */ clearstring(ribbon); ribbon->next = NULL; } /* initializestring */ /* end module clearstring version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module interact.getstring */ Static Void getstring(afile, buffer, gotten) _TEXT *afile; string *buffer; boolean *gotten; { /* get a line (as a string) from a file not using string calls. this lets one obtain lines from a file without interactive prompts */ long index = 0; /* of buffer */ clearstring(buffer); if (BUFEOF(afile->f)) { *gotten = false; return; } while (!P_eoln(afile->f) && index < maxstring) { index++; buffer->letters[index-1] = getc(afile->f); if (buffer->letters[index-1] == '\n') buffer->letters[index-1] = ' '; } if (!P_eoln(afile->f)) { printf(" getstring: a line exceeds maximum string size (%ld)\n", (long)maxstring); halt(); } buffer->length = index; buffer->current = 1; fscanf(afile->f, "%*[^\n]"); getc(afile->f); *gotten = true; } /* getstring */ /* end module interact.getstring version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module interact.writestring */ /* begin module writestring */ Static Void writestring(tofile, s) _TEXT *tofile; string *s; { /* write the string s to file tofile, no writeln */ long i; /* index to s */ long FORLIM; FORLIM = s->length; for (i = 0; i < FORLIM; i++) putc(s->letters[i], tofile->f); } /* writestring */ /* end module writestring version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* end module interact.writestring version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module copystring */ Static Void copystring(a, b) string a, *b; { /* copy string a to b */ long l; /* index to the string */ b->length = a.length; for (l = 0; l < a.length; l++) b->letters[l] = a.letters[l]; } /* end module copystring version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module makelogo.protectcharacter */ Static Void protectcharacter(c, protectioncharacter, needed) Char c, *protectioncharacter; boolean *needed; { /* In PostScript, special characters must be protected against. This routine looks at a character c and returns a protection character if it is needed. The parenthesis is used in PostScript to indicate the bounds of a string, while the percent is the comment character. The backslash also needs protection, since it is the escape to indicate that the next character is part of the string. */ if (c == '\\' || c == '%' || c == ')' || c == '(') { *protectioncharacter = '\\'; *needed = true; } else { *protectioncharacter = ' '; *needed = false; } } /* Local variables for numberdigit: */ struct LOC_numberdigit { long number, place; /* the exponent of logplace */ long myabsolute; /* the absolute value of number */ Char acharacter; /* the character to be returned */ } ; Local Void digit(LINK) struct LOC_numberdigit *LINK; { /* extract a digit at the place position */ long tenplace; /* ten times place */ long z; /* an intermediate value */ long d; /* the digit extracted */ tenplace = LINK->place * 10; z = LINK->myabsolute - LINK->myabsolute / tenplace * tenplace; if (LINK->place == 1) d = z; else d = z / LINK->place; switch (d) { case 0: LINK->acharacter = '0'; break; case 1: LINK->acharacter = '1'; break; case 2: LINK->acharacter = '2'; break; case 3: LINK->acharacter = '3'; break; case 4: LINK->acharacter = '4'; break; case 5: LINK->acharacter = '5'; break; case 6: LINK->acharacter = '6'; break; case 7: LINK->acharacter = '7'; break; case 8: LINK->acharacter = '8'; break; case 9: LINK->acharacter = '9'; break; } } /* digit */ Local Void sign(LINK) struct LOC_numberdigit *LINK; { /* put a negative sign out or a positive sign */ if (LINK->number < 0) LINK->acharacter = '-'; else LINK->acharacter = '+'; } /* sign */ /* end module makelogo.protectcharacter version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module numberdigit */ Static Char numberdigit(number_, logplace) long number_, logplace; { /* return the digit at the place value ('logplace') position of number. example: numberdigit(13625, 3) = 3 numberdigit(13625, 4) = 1 2000 July 30 'myabsolute' replaced 'absolute', which is apparently a keyword for GPC. The name is kept to keep the code looking similar to its origin. */ struct LOC_numberdigit V; long count; /* used to make place */ V.number = number_; V.place = 1; for (count = 1; count <= logplace; count++) V.place *= 10; if (V.number == 0) { if (V.place == 1) V.acharacter = '0'; else V.acharacter = ' '; return V.acharacter; } V.myabsolute = labs(V.number); if (V.myabsolute < V.place / 10) { V.acharacter = ' '; return V.acharacter; } if (V.myabsolute >= V.place) digit(&V); else sign(&V); return V.acharacter; } /* numberdigit */ #define ln10 2.30259 /* natural log of 10 - for conversion to log base 10 */ #define epsilon 0.00001 /* a small number to correct log base 10 errors */ /* end module numberdigit version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module numbersize */ Static long numbersize(n) long n; { /* calculate amount of space to be reserved for the integer n */ long size; /* intermediate result */ if (n == 0) return 1; else { /* account for minus sign */ size = (long)(log((double)labs(n)) / ln10 + epsilon) + 1; /* the 1 is for the last digit */ /* the epsilon assures that we do not lose a place due to roundoff. eg, sometimes log base 10 of 10 would be 0.9999 instead of 1, and we would not do it right... note: this will fail for very large numbers on the order of 1/epsilon. */ if (n < 0) size++; return size; } } /* numbersize */ #undef ln10 #undef epsilon #define escape '\\' /* the escape character is backslash */ #define infofield 8 /* size of field for printing information in bits */ #define infodecim 5 /* number of decimal places for printing information */ #define protecting true #define debug false /* set true to debug */ /* Local variables for postscriptstring: */ struct LOC_postscriptstring { string *instring, *outstring, *rawstring; double rs, sd; long n; /* protect the user against PostScript requirements in user defined strings. */ Char curr; /* the current character on the line */ long decimals; /* number of decimal places for next real number */ long i; /* index to s */ boolean italic; /* if true, do italics */ boolean insidestring; /* are we inside a postscript string? */ Char prev; /* the previous character on the line */ } ; Local Void getchar_(LINK) struct LOC_postscriptstring *LINK; { /* step forward one character */ LINK->i++; LINK->prev = LINK->curr; LINK->curr = LINK->instring->letters[LINK->i-1]; } /* getchar */ Local Void putchar_(c, LINK) Char c; struct LOC_postscriptstring *LINK; { /* put the character c onto the end of outstring */ LINK->outstring->length++; if (LINK->outstring->length > maxstring) { printf("postscriptstring: label too long, increase maxstring\n"); halt(); } LINK->outstring->letters[LINK->outstring->length - 1] = c; /* Count characters that are inside unprotected postscript parens. That is, count the characters that will really be printed */ if (LINK->insidestring) { LINK->rawstring->length++; LINK->rawstring->letters[LINK->rawstring->length - 1] = c; /* writeln(output,'length = ',length:2, ' char = "',letters[length],'"', insidestring); */ } } /* putchar */ Local Void badstring(LINK) struct LOC_postscriptstring *LINK; { _TEXT TEMP; printf("This string:\n"); TEMP.f = stdout; *TEMP.name = '\0'; writestring(&TEMP, LINK->instring); printf("\nis bad because parenthesis must be paired like this:\n"); printf("\"\\)\" stuff \"\\(\"\n"); /* writeln(output,'I am emptying the logo file.'); rewrite(logo); */ halt(); } /* badstring */ Local Void doitalics(LINK) struct LOC_postscriptstring *LINK; { /* generate: 38\) \( E. coli \) IT \(LexA binding sites 38) (E. coli ) IT (LexA binding sites */ LINK->insidestring = false; if (LINK->italic) { /* complete italics */ putchar_(')', LINK); putchar_(' ', LINK); putchar_('I', LINK); putchar_('T', LINK); putchar_(' ', LINK); putchar_('(', LINK); } else { putchar_(')', LINK); putchar_(' ', LINK); putchar_('(', LINK); } /* start italics */ LINK->insidestring = true; LINK->italic = !LINK->italic; } /* doitalics */ Local Void dosymbol(LINK) struct LOC_postscriptstring *LINK; { /* from: 38 \160 SY LexA binding sites generate: 38) (160) SY (LexA binding sites */ LINK->insidestring = false; putchar_(')', LINK); /* the symbol counts as a single space inside the string */ LINK->insidestring = true; putchar_(' ', LINK); LINK->insidestring = false; putchar_('(', LINK); putchar_('\\', LINK); putchar_(LINK->curr, LINK); /*get two and put them */ getchar_(LINK); putchar_(LINK->curr, LINK); getchar_(LINK); putchar_(LINK->curr, LINK); putchar_(')', LINK); putchar_(' ', LINK); putchar_('S', LINK); putchar_('Y', LINK); putchar_(' ', LINK); putchar_('(', LINK); LINK->insidestring = true; } /* dosymbol */ Local Void getnum(num, LINK) long *num; struct LOC_postscriptstring *LINK; { /* pick up a number from the string */ boolean done = false; /* done finding number */ boolean numberstarted = false; /* have we started reading the number? */ long sign = 1; /* -1 or +1 */ long firsti; /* start point for reading */ _TEXT TEMP; /* writeln(output,'This string:'); writestring(output,instring); writeln(output); */ firsti = LINK->i; *num = 0; while (!done) { LINK->i++; if (LINK->i > LINK->instring->length) { done = true; /* number defaults to zero */ break; } LINK->curr = LINK->instring->letters[LINK->i-1]; /* writeln(output,'curr="',curr,'"'); */ if (LINK->curr == '-') { if (sign == -1) { printf("strings can have only one \"-\" in \\n numbers\n"); halt(); } sign = -1; numberstarted = true; continue; } if (LINK->curr == '+') { if (sign == -1) { printf("you cannot have both + and - signs in \\n numbers\n"); halt(); } continue; } if (LINK->curr == '9' || LINK->curr == '8' || LINK->curr == '7' || LINK->curr == '6' || LINK->curr == '5' || LINK->curr == '4' || LINK->curr == '3' || LINK->curr == '2' || LINK->curr == '1' || LINK->curr == '0') { *num = *num * 10 + LINK->curr - '0'; /* writeln(output,' current num:',num:1); */ numberstarted = true; } else if (LINK->curr != ' ' || numberstarted) { /* allow leading blanks */ done = true; } } *num *= sign; /* writeln(output,'num=',num:1); */ /* set string reading variable for further analysis */ LINK->i--; LINK->prev = ' '; LINK->curr = LINK->instring->letters[LINK->i-1]; if (numberstarted) return; printf("WARNING: a number was not found in this string:\n"); TEMP.f = stdout; *TEMP.name = '\0'; writestring(&TEMP, LINK->instring); printf("\nzero is being used\n"); *num = 0; LINK->i = firsti; } Local Void don(LINK) struct LOC_postscriptstring *LINK; { /* insert the number of sequences into the string */ Char c; /* a character perhaps to be part of the output number */ /* coo: integer; (* current coordinate in symvec *) */ long num; /* current number in symvec */ long maxcoo = -LONG_MAX; /* maximum coordinate in symvec */ long maxnum = -LONG_MAX; /* maximum number in symvec */ /* sd: real; (* current sd in symvec *) rs: real; (* current rs in symvec *) */ long desiredcoo; /* the coordinate to get the number of sequences */ /* symbols: integer; (* number of symbols *) */ long s; /* index to symbols */ getnum(&desiredcoo, LINK); /* locate the coordinate in the symvec */ /* (* skip header *) reset(symvec); if not eof(symvec) then begin processsymvec(symvec); readln(symvec, symbols); end; coo := -maxint; while (not eof(symvec)) and (coo <> desiredcoo) do begin processsymvec(symvec); readln(symvec,coo,num,rs,sd); if num >= maxnum then begin maxnum := num; maxcoo := coo; end; for s := 1 to symbols do readln(symvec); end; if eof(symvec) then begin (* we could be eof(symvec) for two reasons. One is that we read to the end of the file. The other is that the file is empty. *) reset(symvec); if eof(symvec) then begin (* symvec is empty *) coo := 0; num := 0; writeln(output,'* The symvec is empty.'); writeln(output,' Using ',coo:1,' for the coordinate and ', num:1,' for the number.'); end else begin (* we read to the end *) writeln(output,'* Coordinate ',desiredcoo:1, ' is not in the symvec:'); writeln(output,' the maximum value (',maxnum:1, ') at coordinate ',maxcoo:1, ' will be used instead.'); coo := maxcoo; num := maxnum; end end; */ num = LINK->n; /* now put the number into the output strings */ for (s = numbersize(num); s >= 0; s--) { c = numberdigit(num, s); if (c != ' ' && c != '+') putchar_(c, LINK); } LINK->n = num; /* writeln(output,'* ',n:1,' sequences found at coordinate ',coo:1); */ printf("* %ld sequences found at coordinate ,coo:1\n", LINK->n); } /* don */ /* procedure getrssd; (* get Rsequence and its sd *) var b: integer; (* index to a symbol *) nl: integer; (* number of symbols at position l *) position: integer; (* a location in the aligned sequence (true coordinate) *) rsl: real; (* information at position l *) rsvar: real; (* variance of information at position l *) rstotal: real; (* sum of the rsl for the whole logo *) symbols: integer; (* number of symbols possible *) varhnb: real; (* variance of rstotal for the whole logo *) begin reset(symvec); if eof(symvec) then begin (* symvec is empty *) writeln(output, 'symvec is empty: can''t do \r'); halt end; processsymvec(symvec); readln(symvec, symbols); rstotal := 0.0; varhnb := 0.0; position := lowest; while (not eof(symvec) and (position <= highest)) do begin processsymvec(symvec); readln(symvec,position,nl,rsl,rsvar); if (position >= lowest) and (position <= highest) then begin rstotal := rstotal + rsl; varhnb := varhnb + rsvar; end; (* skip the symbols *) for b := 1 to symbols do begin processsymvec(symvec); readln(symvec); (* skip *) end; end; rs := rstotal; if varhnb >= 0 then sd := sqrt(varhnb) else sd := 0.0; havers := true; havesd := true; end; */ Local Void putreal(r, dec, LINK) double r; long dec; struct LOC_postscriptstring *LINK; { /*wid,*/ /* put a real number r into the string with dec decimal places. The total width of the number is not controlled; there are no leading blanks. If here are no decimal places, the number is rounded. If there are decimal places, the number is rounded at the end. (This is as one expects, but the code is interesting.) */ Char c; /* part of the real number as a character */ long m; /* multiplier index */ long num; /* part of the real number */ long s; /* position in part of the number */ if (r < 0) { /* handle negative values */ c = '-'; putchar_(c, LINK); r = fabs(r); /* set it positive for later work */ } if (dec > 0) { /* 2007 Jan 10: BUG! */ /* (* move part below decimal above it: *) for m := 1 to dec do r := r * 10; (* round at that point only! *) r := round(r); (* put r back as it was, but rounded: *) for m := 1 to dec do r := r / 10; (* get part above decimal: *) num := trunc(r) */ if (debug) printf("BB r initial = %10.5f\n", r); /* move part below decimal above it: */ for (m = 1; m <= dec; m++) r *= 10; /* round at that point only! */ r = (long)floor(r + 0.5); if (debug) printf("BB r rounded = %10.5f\n", r); /* put r back as it was, but rounded: */ for (m = 1; m <= dec; m++) r /= 10; if (debug) printf("BB r divided = %10.5f\n", r); /* get part above decimal: */ num = (long)r; if (debug) printf("BB r final = %10.5f\n", r); if (debug) printf("BB num = %ld\n", num); } else num = (long)floor(r + 0.5); /* do part above decimal: */ for (s = numbersize(num); s >= 0; s--) { c = numberdigit(num, s); if (c != ' ' && c != '+') putchar_(c, LINK); } /* do part below decimal: */ if (dec <= 0) return; /* decimal point */ c = '.'; putchar_(c, LINK); /* digits after decimal point */ r -= num; /* remove part above decimal point */ if (debug) printf("BL r rm num = %10.5f\n", r); /* move part below decimal above it: */ for (m = 1; m <= dec; m++) r = 10 * r; if (debug) printf("BL r above = %10.5f\n", r); num = (long)floor(r + 0.5); /* round gives same result as Pascal */ if (debug) printf("BL num = %10ld\n", num); /* (* 2007 Jan 10 bug here! - should be dec not numbersize! *) for s := numbersize(num) downto 0 do begin */ if (debug) printf("BL numbersize(num) = %10ld\n", numbersize(num)); if (debug) printf("BL dec = %10ld\n", dec); for (s = dec; s >= 0; s--) { c = numberdigit(num, s); /* 2007 Jan 10: original code dropped spaces that should be zeros: if (c <> ' ') and (c <> '+') then putchar(c); */ /* 2007 Jan 10 Bug solution: spaces are zeros below the decimal! */ if (c == ' ') c = '0'; if (c != '+') putchar_(c, LINK); } } #undef debug Local Void dors(LINK) struct LOC_postscriptstring *LINK; { /*infofield,*/ /* insert Rsequence into the string */ /* if not havers then getrssd; */ putreal(LINK->rs, LINK->decimals, LINK); printf("* Rsequence for logo:%*.*f\n", infofield, (int)LINK->decimals, LINK->rs); } Local Void dosd(LINK) struct LOC_postscriptstring *LINK; { /*infofield,*/ /* insert standard deviation of Rsequence into the string */ /* if not havesd then getrssd; */ putreal(LINK->sd, LINK->decimals, LINK); printf("* SD of Rsequence for logo:%*.*f\n", infofield, (int)LINK->decimals, LINK->sd); } Local Void dodecimal(LINK) struct LOC_postscriptstring *LINK; { /* determine number of decimal places */ getnum(&LINK->decimals, LINK); printf("* decimal places set to: %ld\n", LINK->decimals); } /* end module numbersize version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ /* begin module postscriptstring */ Static Void postscriptstring(instring_, outstring_, rawstring_, rs_, sd_, n_) string *instring_, *outstring_, *rawstring_; double rs_, sd_; long n_; { /* var symvec: text; lowest, highest: integer; */ /*; havers, havesd: boolean*/ /* version = 2.00 of postscriptstring 2003 Aug 29 2003 Aug 29, 2.00: origin from makelogo.postscriptstring Copy the instring to the outstring while protecting the string by blocking postscript specific characters. Example: If the user typed the result should be so they get ( \( ( \) ) \) (ie real postscript) In the first case the user just said "I want a '('. To do this, we have to put protection on it. In the second case the user said "I want a '(' as a postscript command. To do this, we have to remove the protection! So this procedure reverses the protection. How curious. The variable outlength reports the output length of the string not counting real postscript commands so that the string can be centered. Of course since the user gives postscript commands, they could do anything and that could mess up the centering. C'est la vie. The rawstring is the string as the user would see it, without control stuff or fancy postscript. New commands: \i toggle italics on and off \n 5 produce number of sequences at coordinate 5 \160 produce the Greek letter pi New commands implemented 1999 Feb 20: \r produce Rsequence for the current range \s produce standard deviation for the current range The symvec file is used to find the number of sequences for the \n, \r and \d commands. The lowest and highest values are the range of the logo to use to compute Rs and sd. This procedure requires these modules from prgmod.p: interact.const string.type interact.clearstring clearstring interact.getstring interact.writestring writestring copystring makelogo.protectcharacter numberdigit numbersize */ struct LOC_postscriptstring V; boolean needed; /* is protection needed? */ Char protectionchar; /* is protection needed? */ _TEXT TEMP; /* ; write(output,' instring = "'); writestring(output,instring); writeln(output,'"'); write(output,'outstring = "'); writestring(output,outstring); writeln(output,'"'); write(output,'rawstring = "'); writestring(output,rawstring); writeln(output,'"'); */ V.instring = instring_; V.outstring = outstring_; V.rawstring = rawstring_; V.rs = rs_; V.sd = sd_; V.n = n_; if (!protecting) { copystring(*V.instring, V.outstring); copystring(*V.instring, V.rawstring); return; } clearstring(V.outstring); clearstring(V.rawstring); V.curr = ' '; V.decimals = infodecim; /* default value */ V.italic = false; /*in makelogo: insidestring := false; (* we start outside the string *) EXCEPTION: here we STAY insidestring: insidestring := true; (* we start outside the string *) putchar('('); */ V.insidestring = true; /* we are now inside the string */ V.i = 0; while (V.i < V.instring->length) { getchar_(&V); /* since we just got to a \) we are no longer inside the string */ if (V.prev == escape && V.curr == ')') { if (!V.insidestring) badstring(&V); V.insidestring = false; } /* \\ gives \\ */ if (V.curr == escape) { if (V.prev == escape) { putchar_(V.prev, &V); putchar_(V.curr, &V); } } else { if (V.prev != escape) { protectcharacter(V.curr, &protectionchar, &needed); if (needed) putchar_(protectionchar, &V); } if (V.prev == escape && V.curr == 'i') doitalics(&V); else if (V.prev == escape && V.curr == 'n') { don(&V); } else if (V.prev == escape && (V.curr == '7' || V.curr == '6' || V.curr == '5' || V.curr == '4' || V.curr == '3' || V.curr == '2' || V.curr == '1' || V.curr == '0')) { dosymbol(&V); } else if (V.prev == escape && V.curr == 'r') { dors(&V); } else if (V.prev == escape && V.curr == 's') { dosd(&V); } else if (V.prev == escape && V.curr == 'd') { dodecimal(&V); } else putchar_(V.curr, &V); } /* now that we are past the \( we are truely inside the string */ if (V.prev == escape && V.curr == '(') { if (V.insidestring) badstring(&V); V.insidestring = true; } } if (V.insidestring) V.insidestring = false; else { printf("This string:\n"); TEMP.f = stdout; *TEMP.name = '\0'; writestring(&TEMP, V.instring); printf("\nis bad because it needs a final \"\\(\".\n"); /* writeln(output,'I am emptying the logo file.'); rewrite(logo); */ halt(); } /* close italics if necessary */ if (V.italic) doitalics(&V); /* DO NOT CLOSE STRING putchar(')'); */ } /* postscriptstring */ #undef escape #undef infofield #undef infodecim #undef protecting /* Local variables for checknumber: */ struct LOC_checknumber { _TEXT *afile; boolean ok; /* result of this check */ } ; Local Void conclude(LINK) struct LOC_checknumber *LINK; { _TEXT TEMP; printf("Including this character, the rest of the data line is:\n"); TEMP.f = stdout; *TEMP.name = '\0'; copyaline(LINK->afile, &TEMP); LINK->ok = false; } /* end module postscriptstring */ /******************************************************************************/ /******************************************************************************/ /******************************************************************************/ /* begin module checknumber */ Static boolean checknumber(afile_) _TEXT *afile_; { /* check that there is a number next in the file. If not, return false. This is useful for protection when reading a parameter file. */ struct LOC_checknumber V; V.afile = afile_; V.ok = true; /* be optimistic */ if (BUFEOF(V.afile->f)) { V.ok = false; printf("A number was expected on a data line, but"); printf(" the end of the file was found instead.\n"); return false; } skipblanks(V.afile); if (P_eoln(V.afile->f)) { printf("A number was expected on a data line, but"); printf(" the end of the line was found instead.\n"); conclude(&V); } if (P_peek(V.afile->f) == '+' || P_peek(V.afile->f) == '-' || P_peek(V.afile->f) == '.' || P_peek(V.afile->f) == '9' || P_peek(V.afile->f) == '8' || P_peek(V.afile->f) == '7' || P_peek(V.afile->f) == '6' || P_peek(V.afile->f) == '5' || P_peek(V.afile->f) == '4' || P_peek(V.afile->f) == '3' || P_peek(V.afile->f) == '2' || P_peek(V.afile->f) == '1' || P_peek(V.afile->f) == '0') return V.ok; printf("A number was expected on a data line, but"); printf(" the character \"%c\" was found instead.\n", P_peek(V.afile->f)); conclude(&V); return V.ok; } /* end module checknumber version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module copyfile */ Static Void copyfile(fin, fout) _TEXT *fin, *fout; { /* copy the rest of file fin to fout */ while (!BUFEOF(fin->f)) copyaline(fin, fout); } #define copylines 27 /* the number of copied lines */ /* debugging = false; (* whether to report debugging information *) */ #define debugging true /* whether to report debugging information */ #define debugging_ false /* set to true to debug the peak finding algorithm */ /* Local variables for themain: */ struct LOC_themain { _TEXT *data; Char background; /* control the background color */ double grey; /* definition of grey */ Char cutofftype; /* the type of cutoff count to use, c for counts or f for fraction. */ double cutoffvaluemin; /* lowest value to report */ double cutoffvaluemax; /* highest value to report */ long bins[maxValue - minValue + 1][maxValue - minValue + 1]; /* bins to store the data */ long numbertoprocess; /* number of data items to process */ double parameterversion; /* parameter version number */ long NuWi; /* width of output numbers */ long NuDe; /* decimals of output numbers */ double XminValue, XmaxValue; /* range of the X values */ double Xrange; /* Xrange := XmaxValue - XminValue; */ long Xintervals; /* number of intervals for bins of X values */ double YminValue, YmaxValue; /* range of the Y values */ double Yrange; /* Yrange := YmaxValue - YminValue; */ long Yintervals; /* number of intervals for bins of Y values */ long Xcolumn, Ycolumn; /* column numbers for X and Y data. */ boolean xlessthany; /* Xcolumn is less than Ycolumn */ double Xsize, Ysize; /* size of the plotting area, cm. */ double Xcorner, Ycorner; /* lower left corner of the plotting area, cm. */ long XDisplayIntervals, YDisplayIntervals; /* maximum number of numeric intervals for xyplo to display */ long XDisplaySubIntervals, YDisplaySubIntervals; /* maximum number of numeric sub intervals for xyplo to display */ long xwidth, ywidth; /* axis number width */ long xdecimal, ydecimal; /* axis number decimals */ double Xvalue, Yvalue; /* a pair of data items */ long dataCount; /* total data count */ long inCount; /* number of pairs in the X and Y range */ long outCount; /* number of pairs in the X and Y range */ long XinCount; /* number of pairs in the X range */ long XoutCount; /* number of pairs in the X range */ long YinCount; /* number of pairs in the Y range */ long YoutCount; /* number of pairs in the Y range */ boolean Xin; /* the X value is inside */ boolean Yin; /* the Y value is inside */ long Xbin, Ybin; /* current bin location for the data */ long Xlo; /* the lowest value of Xbin */ long Ylo; /* the lowest value of Ybin */ long Xhi; /* the highest value of Xbin */ long Yhi; /* the highest value of Ybin */ double SymbolSizeX, SymbolSizeY; /* size of X and Y symbols */ double shrinkfactorX, shrinkfactorY; /* shrink of Symbols relative to jumps */ double jumpX; /* jump between X values */ double jumpY; /* jump between Y values */ double shiftX, shiftY; /* amount to shift the square X and Y so that so that the it is centered on the REGION of the bin */ string XaxisLabel; /* a the X axis label */ string YaxisLabel; /* a the Y axis label */ Char cog; /* color or grey plot */ long BinMax; /* the maximumly filled bin */ /* controls for the color key */ Char keytype; /* the type of number to report: fraction or number */ double keyX, keyY; /* The coordinate to place the key, in cm. */ double keyXsize, keyYsize; /* the size of the key in cm. */ long keydecimals; /* number of decimal places in the key */ long keyintervals; /* intervals on the color key */ double keyshrinkfactor; /* factor by which to shrink the key boxes */ double keyfontsize; /* the font size for the key numbers */ double thelinewidth; /* the line width around the key boxes */ /* Definitions for the BoundingBox of the encapsulated PostScript (eps): */ double llx, lly; /* lower left x and y */ double urx, ury; /* upper right x and y */ Char edgecontrol; /* if 'p' then use page instead of edges */ double edgeleft; /* left edge margin */ double edgelow; /* lower edge margin */ double edgeright; /* right edge margin */ double edgehigh; /* high edge margin */ Char findpeak; /* if 'l' then find peak starting at startX, startY */ double startX; /* x coordinate of local peak finding */ double startY; /* Y coordinate of local peak finding */ long SearchRange; } ; /* 2*SearchRange+1 is the size of the side of a square within which the search for the maximum is done. */ /*ppp*/ /*zzz*/ /* begin module denplo.upgradefrom166to188 */ Local Void upgradefrom166to188(denplop, LINK) _TEXT *denplop; struct LOC_themain *LINK; { /* upgrade the denplop file from 1.66 to version 1.88. Introduce artmode variable. */ _TEXT internal; /* a place to hold the old denplop */ long line; /* a line to be worked with */ double parameterversion = 1.88; /* parameter version number */ internal.f = NULL; *internal.name = '\0'; printf("upgrading to version %4.2f ...\n", parameterversion); /* copy alist to internal */ if (*denplop->name != '\0') { if (denplop->f != NULL) denplop->f = freopen(denplop->name, "r", denplop->f); else denplop->f = fopen(denplop->name, "r"); } else rewind(denplop->f); if (denplop->f == NULL) _EscIO2(FileNotFound, denplop->name); RESETBUF(denplop->f, Char); fscanf(denplop->f, "%*[^\n]"); getc(denplop->f); /* skip old parameter version line */ if (*internal.name != '\0') { if (internal.f != NULL) internal.f = freopen(internal.name, "w", internal.f); else internal.f = fopen(internal.name, "w"); } else { if (internal.f != NULL) rewind(internal.f); else internal.f = tmpfile(); } if (internal.f == NULL) _EscIO2(FileNotFound, internal.name); SETUPBUF(internal.f, Char); for (line = 1; line <= copylines; line++) copyaline(denplop, &internal); /* write the NEW PARAMETER LINE */ fprintf(internal.f, "- 0 0 1 28. findpeak(l), startX, startY, SearchRange\n"); /*ppp*/ /* finish the copy of alist to internal */ copyfile(denplop, &internal); /* copy internal to alist */ if (*internal.name != '\0') { if (internal.f != NULL) internal.f = freopen(internal.name, "r", internal.f); else internal.f = fopen(internal.name, "r"); } else rewind(internal.f); if (internal.f == NULL) _EscIO2(FileNotFound, internal.name); RESETBUF(internal.f, Char); if (*denplop->name != '\0') { if (denplop->f != NULL) denplop->f = freopen(denplop->name, "w", denplop->f); else denplop->f = fopen(denplop->name, "w"); } else { if (denplop->f != NULL) rewind(denplop->f); else denplop->f = tmpfile(); } if (denplop->f == NULL) _EscIO2(FileNotFound, denplop->name); SETUPBUF(denplop->f, Char); fprintf(denplop->f, "%4.2f version of denplop that this parameter file is designed for.\n", parameterversion); copyfile(&internal, denplop); /* add the new material at the end: */ /* none to add */ if (*denplop->name != '\0') { if (denplop->f != NULL) denplop->f = freopen(denplop->name, "r", denplop->f); else denplop->f = fopen(denplop->name, "r"); } else rewind(denplop->f); if (denplop->f == NULL) _EscIO2(FileNotFound, denplop->name); RESETBUF(denplop->f, Char); /* ready to start reading again */ if (internal.f != NULL) fclose(internal.f); } #undef copylines /* Since parameters are real numbers, there can be round off errors in the 15th decimal place that prevent comparisons. However, I only use parameters to 2 decimal places, so we can multipy by 100 and round to do reliable comparisons. */ Local long r100(a) double a; { /* simple multiply and round function */ return ((long)floor(100 * a + 0.5)); } Local boolean equalversion(a, b) double a, b; { /* Are versions a and b equal? */ if (r100(a) == r100(b)) return true; else return false; } /* equalversion */ Local boolean lessthan(a, b) double a, b; { /* Is version a less than b? */ if (r100(a) < r100(b)) return true; else return false; } /* lessthan */ Local boolean greaterthan(a, b) double a, b; { /* Is version a greater than b? */ if (r100(a) > r100(b)) return true; else return false; } /* greaterthan */ /* end module denplo.upgradefrom166to188 */ /* begin module denplo.upgradeparameters */ Local Void upgradeparameters(denplop, LINK) _TEXT *denplop; struct LOC_themain *LINK; { /* make sure that the parameters are the latest spiffy version */ double parameterversion; /* parameter version number */ fscanf(denplop->f, "%lg%*[^\n]", ¶meterversion); getc(denplop->f); if (!lessthan(parameterversion, updateversion)) /*or*/ return; /* greaterthan(parameterversion, versionupperbound) */ printf("^GYou have an old parameter file!, version %4.2f!\n", parameterversion); printf(" version = %4.2f\n", version); printf(" updateversion = %4.2f\n", updateversion); printf(" parameterversion = %4.2f\n", parameterversion); /* writeln(output, 'versionupperbound = ',versionupperbound:4:2); */ if (equalversion(parameterversion, 1.66)) upgradefrom166to188(denplop, LINK); /*ppp*/ if (*denplop->name != '\0') { if (denplop->f != NULL) denplop->f = freopen(denplop->name, "r", denplop->f); else denplop->f = fopen(denplop->name, "r"); } else rewind(denplop->f); if (denplop->f == NULL) _EscIO2(FileNotFound, denplop->name); RESETBUF(denplop->f, Char); fscanf(denplop->f, "%lg%*[^\n]", ¶meterversion); getc(denplop->f); if (lessthan(parameterversion, updateversion)) { printf("Sorry! I am unable to fully upgrade your parameter file\n"); printf("from version %4.2f to version %4.2f!\n", parameterversion, updateversion); printf("Start from a fresh copy or edit this one.\n"); halt(); } else printf("... upgrade successful!\n"); printf("See this page for the new documentation:\n"); printf("http://www.lecb.ncifcrf.gov/~toms/delila/denplo.html\n"); } /* Local variables for readparameters: */ struct LOC_readparameters { struct LOC_themain *LINK; _TEXT *denplop; boolean checkout; /* if true, all variable values are ok */ } ; Local Void cn(LINK) struct LOC_readparameters *LINK; { /* short version of call to check number */ LINK->checkout = checknumber(LINK->denplop); if (LINK->checkout) return; printf("denplo readparameters: halt to avoid snoballing\n"); printf("A number was expected but not found.\n"); if (BUFEOF(LINK->denplop->f)) printf("Unexpected End of File\n"); else if (P_eoln(LINK->denplop->f)) printf("Unexpected End Of Line\n"); else printf("The bad character in denplop is: \"%c\"\n", P_peek(LINK->denplop->f)); halt(); /* avoid snowballing */ } /* end module denplo.upgradeparameters */ Local Void readparameters(denplop_, LINK) _TEXT *denplop_; struct LOC_themain *LINK; { /* read user defined parameters */ struct LOC_readparameters V; boolean gotten; /* did we get the buffer? */ V.LINK = LINK; V.denplop = denplop_; if (*V.denplop->name != '\0') { if (V.denplop->f != NULL) V.denplop->f = freopen(V.denplop->name, "r", V.denplop->f); else V.denplop->f = fopen(V.denplop->name, "r"); } else rewind(V.denplop->f); if (V.denplop->f == NULL) _EscIO2(FileNotFound, V.denplop->name); RESETBUF(V.denplop->f, Char); /* readln(denplop, parameterversion); (* 0 *) if round(100*parameterversion) < round(100*updateversion) then begin writeln(output, 'You have an old parameter file!'); end; */ cn(&V); upgradeparameters(V.denplop, LINK); cn(&V); fscanf(V.denplop->f, "%ld%*[^\n]", &LINK->numbertoprocess); getc(V.denplop->f); /* 1 */ cn(&V); fscanf(V.denplop->f, "%lg%lg%ld%*[^\n]", &LINK->XminValue, &LINK->XmaxValue, &LINK->Xintervals); getc(V.denplop->f); /* 2 */ cn(&V); fscanf(V.denplop->f, "%lg%lg%ld%*[^\n]", &LINK->YminValue, &LINK->YmaxValue, &LINK->Yintervals); getc(V.denplop->f); /* 3 */ cn(&V); fscanf(V.denplop->f, "%ld%ld%*[^\n]", &LINK->NuWi, &LINK->NuDe); getc(V.denplop->f); /* 4 */ cn(&V); fscanf(V.denplop->f, "%ld%ld%*[^\n]", &LINK->Xcolumn, &LINK->Ycolumn); getc(V.denplop->f); /* 5 */ cn(&V); fscanf(V.denplop->f, "%lg%lg%*[^\n]", &LINK->Xsize, &LINK->Ysize); getc(V.denplop->f); /* 6 */ cn(&V); fscanf(V.denplop->f, "%lg%lg%*[^\n]", &LINK->Xcorner, &LINK->Ycorner); getc(V.denplop->f); /* 7 */ cn(&V); fscanf(V.denplop->f, "%ld%ld%ld%ld%*[^\n]", &LINK->XDisplayIntervals, &LINK->YDisplayIntervals, &LINK->XDisplaySubIntervals, &LINK->YDisplaySubIntervals); getc(V.denplop->f); /* 8 */ cn(&V); fscanf(V.denplop->f, "%ld%ld%*[^\n]", &LINK->xwidth, &LINK->ywidth); getc(V.denplop->f); /* 9 */ cn(&V); fscanf(V.denplop->f, "%ld%ld%*[^\n]", &LINK->xdecimal, &LINK->ydecimal); getc(V.denplop->f); /* 10 */ LINK->background = getc(V.denplop->f); if (LINK->background == '\n') LINK->background = ' '; if (LINK->background == 'g') fscanf(V.denplop->f, "%lg", &LINK->grey); else LINK->grey = 0.9; fscanf(V.denplop->f, "%*[^\n]"); getc(V.denplop->f); /* 11 */ fscanf(V.denplop->f, "%c%lg", &LINK->cutofftype, &LINK->cutoffvaluemin); /* 12 */ if (LINK->cutofftype == '\n') LINK->cutofftype = ' '; if (LINK->cutofftype == 'C' || LINK->cutofftype == 'F') fscanf(V.denplop->f, "%lg", &LINK->cutoffvaluemax); else LINK->cutoffvaluemax = LONG_MAX; fscanf(V.denplop->f, "%*[^\n]"); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%lg%*[^\n]", &LINK->shrinkfactorX, &LINK->shrinkfactorY); getc(V.denplop->f); /* 13 */ getstring(V.denplop, &LINK->XaxisLabel, &gotten); if (!gotten) { printf("end of file found when reading X axis label\n"); halt(); } getstring(V.denplop, &LINK->YaxisLabel, &gotten); if (!gotten) { printf("end of file found when reading X axis label\n"); halt(); } fscanf(V.denplop->f, "%c%*[^\n]", &LINK->cog); getc(V.denplop->f); if (LINK->cog == '\n') LINK->cog = ' '; cn(&V); fscanf(V.denplop->f, "%ld%*[^\n]", &LINK->keyintervals); getc(V.denplop->f); fscanf(V.denplop->f, "%c%*[^\n]", &LINK->keytype); getc(V.denplop->f); if (LINK->keytype == '\n') LINK->keytype = ' '; cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyX); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyY); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyXsize); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyYsize); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyshrinkfactor); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->thelinewidth); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%ld%*[^\n]", &LINK->keydecimals); getc(V.denplop->f); cn(&V); fscanf(V.denplop->f, "%lg%*[^\n]", &LINK->keyfontsize); getc(V.denplop->f); /* first, set defaults */ LINK->llx = defaultllx; LINK->ury = defaultury; LINK->urx = defaulturx; LINK->lly = defaultlly; LINK->edgecontrol = getc(V.denplop->f); if (LINK->edgecontrol == '\n') LINK->edgecontrol = ' '; if (LINK->edgecontrol == 'p') { cn(&V); fscanf(V.denplop->f, "%lg", &LINK->edgeleft); cn(&V); fscanf(V.denplop->f, "%lg", &LINK->edgeright); cn(&V); fscanf(V.denplop->f, "%lg", &LINK->edgelow); cn(&V); fscanf(V.denplop->f, "%lg", &LINK->edgehigh); /*note: cn comes from xyplo.p*/ /* writeln(output,'xsize',xsize:11:5); writeln(output,'ysize',ysize:11:5); writeln(output,'defscale',defscale:11:5); */ /* in xyplo.p xzero -> Xcorner; yzero -> Ycorner; */ LINK->llx = (long)floor((LINK->Xcorner - LINK->edgeleft) * defscale + 0.5); LINK->lly = (long)floor((LINK->Ycorner - LINK->edgelow) * defscale + 0.5); LINK->urx = (long)floor( (LINK->Xcorner + LINK->Xsize + LINK->edgeright) * defscale + 0.5); LINK->ury = (long)floor( (LINK->Ycorner + LINK->Xsize + LINK->edgehigh) * defscale + 0.5); } fscanf(V.denplop->f, "%*[^\n]"); getc(V.denplop->f); /* read the start point for local search */ LINK->findpeak = getc(V.denplop->f); if (LINK->findpeak == '\n') LINK->findpeak = ' '; if (LINK->findpeak == 'l') { cn(&V); fscanf(V.denplop->f, "%lg", &LINK->startX); cn(&V); fscanf(V.denplop->f, "%lg", &LINK->startY); cn(&V); fscanf(V.denplop->f, "%ld", &LINK->SearchRange); } else if (LINK->findpeak == 'm') { cn(&V); fscanf(V.denplop->f, "%ld", &LINK->BinMax); LINK->startX = 0.0; LINK->startY = 0.0; LINK->SearchRange = 0; } else { LINK->startX = 0.0; LINK->startY = 0.0; LINK->SearchRange = 0; } fscanf(V.denplop->f, "%*[^\n]"); getc(V.denplop->f); /*ppp*/ /* check the input parameters ************************* */ if (LINK->XmaxValue <= LINK->XminValue) { printf("XmaxValue (%*.*f) cannot be less than XminValue (%*.*f)\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->XmaxValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->XminValue); halt(); } if (LINK->YmaxValue <= LINK->YminValue) { printf("YmaxValue (%*.*f) cannot be less than YminValue (%*.*f)\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->YmaxValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->YminValue); halt(); } if (LINK->Xintervals < 1) { printf("Xintervals (=%ld) cannot be less than 2\n", LINK->Xintervals); halt(); } if (LINK->Yintervals < 1) { printf("Yintervals (=%ld) cannot be less than 2\n", LINK->Yintervals); halt(); } if (LINK->NuWi < 1) { printf("NuWi must be positive\n"); halt(); } if (LINK->NuDe < 1) { printf("NuDe must be positive\n"); halt(); } /***** No! If NuDe = 1, Pascal will fill the number out anyway! This is a big space saver. 2004 July 31. if NuDe > NuWi then begin writeln(output,'NuDe must be less than NuWi'); halt; end; *******/ if (LINK->NuDe < 5) { printf("NuDe must be at least 5 decimal places\n"); halt(); } if (LINK->Xcolumn < 1) { printf("Xcolumn must be positive\n"); halt(); } if (LINK->Ycolumn < 1) { printf("Ycolumn must be positive\n"); halt(); } if (LINK->Xcolumn == LINK->Ycolumn) { printf("X column cannot equal Ycolumn\n"); halt(); } if (LINK->Xsize <= 0.0) { printf("Xsize must be positive\n"); halt(); } if (LINK->Ysize <= 0.0) { printf("Ysize must be positive\n"); halt(); } if (LINK->XDisplayIntervals < 0) { printf("XDisplayIntervals must be zero or positive it is %ld\n", LINK->XDisplayIntervals); halt(); } if (LINK->YDisplayIntervals < 0) { printf("YDisplayIntervals must be zero or positive it is %ld\n", LINK->YDisplayIntervals); halt(); } if (LINK->XDisplaySubIntervals <= 0) { printf("XDisplaySubIntervals must be positive\n"); halt(); } if (LINK->YDisplaySubIntervals <= 0) { printf("YDisplaySubIntervals must be positive\n"); halt(); } if (LINK->xwidth <= 1) { printf("xwidth must be positive\n"); halt(); } if (LINK->ywidth <= 1) { printf("ywidth must be positive\n"); halt(); } if (LINK->xdecimal < 0) { printf("xdecimal must be positive or zero\n"); halt(); } if (LINK->ydecimal < 0) { printf("ydecimal must be positive or zero\n"); halt(); } if (LINK->background != 'c' && LINK->background != 'w' && LINK->background != 'g' && LINK->background != 'b') { printf("background must be one of bgwc\n"); halt(); } if ((unsigned)LINK->grey > 1.0) { printf("grey must be between 0 and 1\n"); halt(); } if (LINK->cutofftype != 'F' && LINK->cutofftype != 'C' && LINK->cutofftype != 'f' && LINK->cutofftype != 'c') { printf("cutofftype must be one of \"cfCF\"\n"); halt(); } if (LINK->cutoffvaluemin < 0) { printf("cutoffvaluemin (%1.1f) must be positive or zero\n", LINK->cutoffvaluemin); halt(); } if (LINK->cutoffvaluemax < 0) { printf("cutoffvaluemax (%1.1f) must be positive or zero\n", LINK->cutoffvaluemax); halt(); } if (LINK->cutofftype == 'f' || LINK->cutofftype == 'F') { if ((unsigned)LINK->cutoffvaluemin > 1.00) { printf("for cutofftype = \"f\", cutoffvaluemin must be between 0 and 1\n"); halt(); } } if (LINK->cutofftype == 'f' || LINK->cutofftype == 'F') { if ((unsigned)LINK->cutoffvaluemax > 1.00) { printf("for cutofftype = \"f\", cutoffvaluemax must be between 0 and 1\n"); halt(); } } if (LINK->cutofftype == 'C' || LINK->cutofftype == 'F') { if (LINK->cutoffvaluemin > LINK->cutoffvaluemax) { printf("for cutoffvaluemin must be less than or equal to cutoffvaluemax \n"); halt(); } } if (LINK->shrinkfactorX <= 0 || LINK->shrinkfactorX > 1.0) { printf("shrinkfactorX must be positive, < 1.0\n"); halt(); } if (LINK->shrinkfactorY <= 0 || LINK->shrinkfactorY > 1.0) { printf("shrinkfactorY must be positive, < 1.0\n"); halt(); } if (LINK->cog != 'g' && LINK->cog != 'c') { printf("cog (color or grey) must be one of \"cg\"\n"); halt(); } if (LINK->keyintervals < 0) printf("No color key will be displayed\n"); if (LINK->keytype != 'n' && LINK->keytype != 'f') { printf("keytype must be one of \"fn\"\n"); halt(); } /* if keyX then begin halt; end; if KeyY then begin halt; end; */ if (LINK->keyXsize <= 0.0) { printf("keyXsize must be positive, it was % .1E\n", LINK->keyXsize); halt(); } if (LINK->keyYsize <= 0.0) { printf("keyYsize must be positive, it was % .1E\n", LINK->keyYsize); halt(); } /* 2005 Mar 30: linewidth can now be negative - ie no line. if thelinewidth <= 0.0 then begin writeln(output,'thelinewidth must be positive, it was ', thelinewidth :1); halt; end; */ if (LINK->keytype == 'f' && LINK->keydecimals < 1) printf("keydecimals must be positive for fractions. It was %ld\n", LINK->keydecimals); /* not needed: else begin keydecimals := 0; (* Force zero decimal places for counts! *) end; */ /*yyy stupid, no decimals needed for counts!: if (keytype <> 'f') and (keydecimals < 0) then begin writeln(output,'keydecimals must be positive or zero for counts.', ' It was ', keydecimals:1); end; */ } Local Void writeparameters(out, k, LINK) _TEXT *out; Char k; struct LOC_themain *LINK; { /* write the parameters to file out with character k at the start of the line */ fprintf(out->f, "%c denplo %4.2f\n", k, version); fprintf(out->f, "%c %9.2f parameterversion for denplo\n", k, LINK->parameterversion); fprintf(out->f, "%c %9ld numbertoprocess\n", k, LINK->numbertoprocess); fprintf(out->f, "%c %*.*f %*.*f %*ld Xminvalue, XmaxValue, Xintervals\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->XminValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->XmaxValue, (int)LINK->NuWi, LINK->Xintervals); fprintf(out->f, "%c %*.*f %*.*f %*ld Yminvalue, YmaxValue, Yintervals\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->YminValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->YmaxValue, (int)LINK->NuWi, LINK->Yintervals); fprintf(out->f, "%c %ld %ld NuWi, NuDe\n", k, LINK->NuWi, LINK->NuDe); fprintf(out->f, "%c %ld %ld Xcolumn, Ycolumn\n", k, LINK->Xcolumn, LINK->Ycolumn); fprintf(out->f, "%c %*.*f %*.*f Xsize, Ysize (cm)\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xsize, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Ysize); fprintf(out->f, "%c %*.*f %*.*f Xcorner, Ycorner (cm)\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xcorner, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Ycorner); /* writeln(out,k,' ', XDisplayIntervals:1, ' ', XDisplayIntervals:1, ' ', XDisplaySubIntervals:1, ' ', YDisplaySubIntervals:1, ' XDisplayIntervals, YDisplayIntervals,', ' XDisplaySubIntervals, YDisplaySubIntervals'); */ fprintf(out->f, "%c %ld %ld %ld %ld (X,Y)DisplayIntervals, (X,Y)DisplaySubIntervals\n", k, LINK->XDisplayIntervals, LINK->XDisplayIntervals, LINK->XDisplaySubIntervals, LINK->YDisplaySubIntervals); fprintf(out->f, "%c %ld %ld xwidth, ywidth\n", k, LINK->xwidth, LINK->ywidth); fprintf(out->f, "%c %ld %ld xdecimal, ydecimal\n", k, LINK->xdecimal, LINK->ydecimal); fprintf(out->f, "%c %c %*.*f background\n", k, LINK->background, (int)LINK->NuWi, (int)LINK->NuDe, LINK->grey); fprintf(out->f, "%c %c %*.*f %*.*f cutofftype cutoffvaluemin cutoffvaluemax\n", k, LINK->cutofftype, (int)LINK->NuWi, (int)LINK->NuDe, LINK->cutoffvaluemin, (int)LINK->NuWi, (int)LINK->NuDe, LINK->cutoffvaluemax); fprintf(out->f, "%c %*.*f %*.*f shrinkfactorX, shrinkfactorY\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->shrinkfactorX, (int)LINK->NuWi, (int)LINK->NuDe, LINK->shrinkfactorY); fprintf(out->f, "%c ", k); writestring(out, &LINK->XaxisLabel); fprintf(out->f, "\n%c ", k); writestring(out, &LINK->YaxisLabel); fprintf(out->f, "\n%c %c cog: color or grey plotting\n", k, LINK->cog); fprintf(out->f, "%c %ld keyintervals\n", k, LINK->keyintervals); fprintf(out->f, "%c %c keytype\n", k, LINK->keytype); fprintf(out->f, "%c %*.*f keyX\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyX); fprintf(out->f, "%c %*.*f keyY\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyY); fprintf(out->f, "%c %*.*f keyXsize\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyXsize); fprintf(out->f, "%c %*.*f keyYsize\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyYsize); fprintf(out->f, "%c %*.*f keyshrinkfactor\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyshrinkfactor); fprintf(out->f, "%c %*.*f thelinewidth\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->thelinewidth); fprintf(out->f, "%c %*ld keydecimals\n", k, (int)LINK->NuWi, LINK->keydecimals); fprintf(out->f, "%c %*.*f keyfontsize\n", k, (int)LINK->NuWi, (int)LINK->NuDe, LINK->keyfontsize); fprintf(out->f, "%c %c", k, LINK->edgecontrol); fprintf(out->f, " %1.2f", LINK->edgeleft); fprintf(out->f, " %1.2f", LINK->edgeright); fprintf(out->f, " %1.2f", LINK->edgelow); fprintf(out->f, " %1.2f", LINK->edgehigh); fprintf(out->f, " edgecontrol, edge(left, right, low, high)\n"); fprintf(out->f, "%c %c", k, LINK->findpeak); fprintf(out->f, " %1.*f", (int)LINK->NuDe, LINK->startX); fprintf(out->f, " %1.*f", (int)LINK->NuDe, LINK->startY); fprintf(out->f, " %*ld", (int)LINK->NuWi, LINK->SearchRange); fprintf(out->f, " findpeak, startX, startY, SearchRange\n\n"); } /* writeparameters */ Local Void buildxyplom(l, LINK) _TEXT *l; struct LOC_themain *LINK; { /* build the xyplom into file l */ if (*l->name != '\0') { if (l->f != NULL) l->f = freopen(l->name, "w", l->f); else l->f = fopen(l->name, "w"); } else { if (l->f != NULL) rewind(l->f); else l->f = tmpfile(); } if (l->f == NULL) _EscIO2(FileNotFound, l->name); SETUPBUF(l->f, Char); fprintf(l->f, "\n/charwidth 12 def\n"); fprintf(l->f, "/fontsize charwidth def\n\n"); fprintf(l->f, "%% define fonts\n"); fprintf(l->f, "/ffss {findfont fontsize scalefont setfont} def\n"); fprintf(l->f, "/FontForStringRegular {/Times-Bold ffss} def\n"); fprintf(l->f, "/FontForStringItalic {/Times-BoldItalic ffss} def\n"); fprintf(l->f, "/FontForLogo {/Helvetica-Bold ffss} def\n"); fprintf(l->f, "/FontForPrime {/Symbol ffss} def\n"); fprintf(l->f, "/FontForSymbol {/Symbol ffss} def\n\n"); fprintf(l->f, "%% make italics possible in titles\n"); fprintf(l->f, "/IT {%% TRstring ITstring IT -\n"); fprintf(l->f, " exch show\n"); fprintf(l->f, " FontForStringItalic\n"); fprintf(l->f, " show\n"); fprintf(l->f, " FontForStringRegular\n"); fprintf(l->f, "} def\n\n\n"); fprintf(l->f, "%% make symbols possible in titles\n"); fprintf(l->f, "/SY {%% TRstring SYstring SY -\n"); fprintf(l->f, " exch show\n"); fprintf(l->f, " FontForSymbol\n"); fprintf(l->f, " show\n"); fprintf(l->f, " FontForStringRegular\n"); fprintf(l->f, "} def\n\n"); } /*ccc*/ /* begin module colormodule */ Local Void makecolor(cog, r, hue, saturation, brightness, LINK) Char cog; double r, *hue, *saturation, *brightness; struct LOC_themain *LINK; { /* determine the color (hue, saturation, brightness) based on cog (c, color; g, grey) and r for which 0 <= r <= 1. */ switch (cog) { case 'c': /* do color graphics */ /* the formula avoids red at hue = 0 being the same as the red at hue = 1. see diana.p */ /* hue := 0.84*r + 0.16; */ *hue = r; /* no correction, done by xyplo */ /*hhh*/ *saturation = 1.0; *brightness = 1.0; break; case 'g': /* do grey scale graphics */ *hue = 0.0; *saturation = 0.0; *brightness = 1 - r; /* white is low density */ break; } } Local Void dobackground(background, Xbin, Ybin, r, hue, saturation, brightness, LINK) Char background; long Xbin, Ybin; double *r, *hue, *saturation, *brightness; struct LOC_themain *LINK; { /* background definition */ /* bin location */ /* b/BinMax if used */ /* color definition */ /* set up the background coloring */ /* 11. background: c = colorful (debug), g = grey, b = black, w = white */ *r = 0.0; switch (background) { case 'b': /* black */ *hue = 0.0; *brightness = 0.0; /* 0 = black */ *saturation = 0.0; break; case 'g': /* grey */ *hue = 0.0; *brightness = LINK->grey; /* 0.9 = grey */ *saturation = 0.0; break; case 'w': /* white */ *hue = 0.0; *brightness = 1.0; /* 1.0 = white */ *saturation = 0.0; break; case 'c': /* start with something */ /* just a function to distinguish various squares */ *r = ((double)Xbin / LINK->Xintervals + (double)Ybin / LINK->Yintervals) / 2; if (Xbin > Ybin) *r = 1 - *r; /*hhh*/ /* hue := 0.84*r + 0.16; */ *hue = *r; /* no correction, done by xyplo */ *saturation = 0.5; /* checkerboard for further distinction: */ if (Xbin + (Ybin & 1) == 0) *brightness = 1.0; else { *brightness = 0.9; } break; } } /* Local variables for determinecolors: */ struct LOC_determinecolors { struct LOC_themain *LINK; Char cog; long b, BinMax; double *r; Char cutofftype; double cutoffvaluemin, cutoffvaluemax; long Xbin, Ybin; double *hue, *saturation, *brightness; } ; Local Void normal(LINK) struct LOC_determinecolors *LINK; { /* proceed with normal color determination */ if ((LINK->cutofftype == 'f' || LINK->cutofftype == 'F') && ((double)LINK->b / LINK->BinMax < LINK->cutoffvaluemin || (double)LINK->b / LINK->BinMax > LINK->cutoffvaluemax)) dobackground(LINK->LINK->background, LINK->Xbin, LINK->Ybin, LINK->r, LINK->hue, LINK->saturation, LINK->brightness, LINK->LINK); else makecolor(LINK->cog, *LINK->r, LINK->hue, LINK->saturation, LINK->brightness, LINK->LINK); } /* normal */ Local Void determinecolors(cog_, b_, BinMax_, r_, cutofftype_, cutoffvaluemin_, cutoffvaluemax_, Xbin_, Ybin_, hue_, saturation_, brightness_, LINK) Char cog_; long b_, BinMax_; double *r_; Char cutofftype_; double cutoffvaluemin_, cutoffvaluemax_; long Xbin_, Ybin_; double *hue_, *saturation_, *brightness_; struct LOC_themain *LINK; { /* color or grey */ /* number of data points */ /* BinMax number of data points */ /* b/BinMax if used */ /* cutoff type */ /* cutoff value */ /* cutoff value */ /* bin location */ /* color definition */ /* determine the colors and return them as hue, saturation, brightness. If the number of data points in the bin at (Xbin,Ybin) exceeds BinMax, it means that a local peak was found that was not the global peak; this point is higher than the recorded local peak. So display this point as black. 2009 Apr 11: Note that the cutoff range changed (from => to >) and (from =< to <) so that background is NOT included when there is equality to the cutoff value. Cutoffs are inclusive. */ struct LOC_determinecolors V; V.LINK = LINK; /* White can be done faster by skipping the denploxyin printing: If it is a white background and b=0, don't plot. */ V.cog = cog_; V.b = b_; V.BinMax = BinMax_; V.r = r_; V.cutofftype = cutofftype_; V.cutoffvaluemin = cutoffvaluemin_; V.cutoffvaluemax = cutoffvaluemax_; V.Xbin = Xbin_; V.Ybin = Ybin_; V.hue = hue_; V.saturation = saturation_; V.brightness = brightness_; if (V.b == 0) { /* there are no data */ dobackground(LINK->background, V.Xbin, V.Ybin, V.r, V.hue, V.saturation, V.brightness, LINK); return; } if ((V.cutofftype == 'c' || V.cutofftype == 'C') && (V.b < V.cutoffvaluemin || V.b > V.cutoffvaluemax)) { dobackground(LINK->background, V.Xbin, V.Ybin, V.r, V.hue, V.saturation, V.brightness, LINK); return; } *V.r = (double)V.b / V.BinMax; /* density in this bin */ if (LINK->findpeak != 'l') { normal(&V); return; } if (*V.r <= 1.0) { /* exceeded local peak, make black! */ normal(&V); return; } /* writeln(output,' r = ',r:1:8); writeln(output,' b = ',b:8); writeln(output,'BinMax = ',BinMax:8); */ *V.hue = 0.0; *V.brightness = 0.0; *V.saturation = 0.0; } /* determinecolors */ Local Void colorkey(l, keytype, BinMax, cog, keyX, keyY, keyXsize, keyYsize, keydecimals, keyintervals, keyshrinkfactor, keyfontsize, cutofftype, cutoffvaluemin, cutoffvaluemax, thelinewidth, LINK) _TEXT *l; Char keytype; long BinMax; Char cog; double keyX, keyY, keyXsize, keyYsize; long keydecimals, keyintervals; double keyshrinkfactor, keyfontsize; Char cutofftype; double cutoffvaluemin, cutoffvaluemax, thelinewidth; struct LOC_themain *LINK; { /* Make a color key in postscript to the l file. BinMax: maximum data counts cog: color or grey to plot. keyX, keyY: The coordinate to place the key, in cm. keyXsize, keyYsize: the size of the key in cm. keydecimals: the number of decimal places to report in the key keyintervals: number of intervals to show on the key. keyshrinkfactor: factor by which to shrink the key boxes. thelinewidth: width of lines around key boxes */ double hue; /* conversion of r to a color */ double saturation; /* conversion of r to a color */ double brightness; /* conversion of r to a color */ long i; /* integer counter for r */ double r; /* a saturation to plot */ long Xbin = 0, Ybin = 0; /* bin location */ long BinValue; /* bin value to report */ long keywidth; /* width of numbers based on BinMax */ fprintf(l->f, "%% Color Key\n\n"); /*zzz*/ fprintf(l->f, "/cmfactor 72 2.54 div def %% defines points -> centimeters\n"); fprintf(l->f, "/cm { cmfactor mul} def %% defines centimeters\n"); fprintf(l->f, "/keyX %*.*f cm def\n", (int)LINK->NuWi, (int)LINK->NuDe, keyX); fprintf(l->f, "/keyY %*.*f cm def\n", (int)LINK->NuWi, (int)LINK->NuDe, keyY); fprintf(l->f, "/keyXsize %*.*f cm def\n", (int)LINK->NuWi, (int)LINK->NuDe, keyXsize); fprintf(l->f, "/keyYsize %*.*f cm def\n", (int)LINK->NuWi, (int)LINK->NuDe, keyYsize); fprintf(l->f, "/keyshrinkfactor %*.*f def\n", (int)LINK->NuWi, (int)LINK->NuDe, keyshrinkfactor); fprintf(l->f, "/keyfontsize % .*E def\n", P_max((int)LINK->NuWi - 7, 1), keyfontsize); fprintf(l->f, "/thelinewidth %*.*f cm def\n", (int)LINK->NuWi, (int)LINK->NuDe, thelinewidth); fprintf(l->f, "/Courier-Bold findfont keyfontsize scalefont setfont\n"); fprintf(l->f, "gsave\n"); fprintf(l->f, "keyX keyY translate\n"); fprintf(l->f, "/keybox { %% make the key box \n"); fprintf(l->f, "sethsbcolor\n"); fprintf(l->f, "gsave\n"); fprintf(l->f, "keyXsize keyYsize scale\n"); fprintf(l->f, "/s keyshrinkfactor def\n"); fprintf(l->f, "0 0 moveto\n"); fprintf(l->f, "0 s lineto\n"); fprintf(l->f, "s s lineto\n"); fprintf(l->f, "s 0 lineto\n"); fprintf(l->f, "closepath\n"); fprintf(l->f, "thelinewidth 0 ge {\n"); fprintf(l->f, " gsave\n"); fprintf(l->f, " thelinewidth setlinewidth\n"); fprintf(l->f, " 0 setgray\n"); fprintf(l->f, " stroke\n"); fprintf(l->f, " grestore\n"); fprintf(l->f, "} if\n"); fprintf(l->f, "fill\n"); fprintf(l->f, "grestore\n"); fprintf(l->f, "} def\n"); fprintf(l->f, "%% columns: hue saturation brightness sethsbcolor %% r\n"); if (BinMax <= 0) keywidth = 1; else { /* add space for the decimals */ keywidth = (long)(log((double)BinMax) / log(10.0) + 1 + 0.2); /* The 1 makes 9 be 1 decimal and 10 be two. The 0.2 insures no rounding effects. */ if (keytype == 'f') { keywidth += keydecimals + 1; /* The 1 is for the decimal place. */ } } /*yyy*/ if (keyintervals > BinMax) keyintervals = BinMax; for (i = 0; i <= keyintervals; i++) { BinValue = (long)(BinMax * ((double)i / keyintervals)); determinecolors(cog, BinValue, BinMax, &r, cutofftype, cutoffvaluemin, cutoffvaluemax, Xbin, Ybin, &hue, &saturation, &brightness, LINK); /* xyplo color conversion is NOT applied to colors in xyplom, of course! So it must be done NOW! See: xyplo.p module pic.setcolor. */ hue = 0.84 * hue + 0.16; /*zzz*/ fprintf(l->f, " %*.*f %*.*f %*.*f keybox %% %ld\n", (int)LINK->NuWi, (int)LINK->NuDe, hue, (int)LINK->NuWi, (int)LINK->NuDe, saturation, (int)LINK->NuWi, (int)LINK->NuDe, brightness, i); fprintf(l->f, "gsave"); fprintf(l->f, " keyXsize 0 moveto"); fprintf(l->f, " 0 setgray"); switch (keytype) { case 'n': fprintf(l->f, " (%*ld) show", (int)keywidth, BinValue); break; /* original: 'n': write (l, ' (',BinValue:1,') show'); */ /*yyy*/ /* 'n': if keydecimals = 0 then write (l, ' (', BinValue:keywidth,') show') else write (l, ' (', (BinMax*(i/(keyintervals))) :keywidth:keydecimals,') show'); */ case 'f': fprintf(l->f, " (%*.*f) show", (int)keywidth, (int)keydecimals, (double)i / keyintervals); break; } fprintf(l->f, " grestore\n"); fprintf(l->f, "0 keyYsize translate\n"); /* shift up */ } fprintf(l->f, "grestore\n"); } /* end module colormodule */ /*ccc*/ Local Void setvariables(LINK) struct LOC_themain *LINK; { /* clear the variables and set up some general values */ long X, Y; /* indicies to the bin */ printf("clearing bins ...\n"); for (X = minValue; X <= maxValue; X++) { for (Y = minValue; Y <= maxValue; Y++) LINK->bins[X - minValue][Y - minValue] = 0; } printf("cleared\n"); LINK->dataCount = 0; LINK->inCount = 0; LINK->outCount = 0; LINK->XinCount = 0; LINK->XoutCount = 0; LINK->YinCount = 0; LINK->YoutCount = 0; LINK->Xlo = LONG_MAX; LINK->Xhi = -LONG_MAX; LINK->Ylo = LONG_MAX; LINK->Yhi = -LONG_MAX; /* set variables */ LINK->xlessthany = (LINK->Xcolumn < LINK->Ycolumn); LINK->Xrange = LINK->XmaxValue - LINK->XminValue; LINK->Yrange = LINK->YmaxValue - LINK->YminValue; LINK->jumpX = LINK->Xrange / LINK->Xintervals; LINK->jumpY = LINK->Yrange / LINK->Yintervals; LINK->SymbolSizeX = LINK->shrinkfactorX * (LINK->Xrange / LINK->Xintervals); LINK->SymbolSizeY = LINK->shrinkfactorY * (LINK->Yrange / LINK->Yintervals); LINK->shiftX = (1 - LINK->shrinkfactorX) * LINK->jumpX / 2; LINK->shiftY = (1 - LINK->shrinkfactorY) * LINK->jumpY / 2; if (debugging) { printf("==================================================\n"); printf(" XminValue: %10.5f \n", LINK->XminValue); printf(" XmaxValue: %10.5f \n", LINK->XmaxValue); printf(" Xrange: %10.5f \n", LINK->Xrange); printf(" YminValue: %10.5f \n", LINK->YminValue); printf(" YmaxValue: %10.5f \n", LINK->YmaxValue); printf(" Yrange: %10.5f \n", LINK->Yrange); printf(" Xintervals: %10ld \n", LINK->Xintervals); printf(" Yintervals: %10ld \n", LINK->Yintervals); printf(" jumpX: %10.5f \n", LINK->jumpX); printf(" jumpY: %10.5f \n", LINK->jumpY); printf("SymbolSizeX: %10.5f \n", LINK->SymbolSizeX); printf("SymbolSizeY: %10.5f \n", LINK->SymbolSizeY); printf("shiftX: %10.5f \n", LINK->shiftX); printf("shiftY: %10.5f \n", LINK->shiftY); printf("==================================================\n"); } if (LINK->SymbolSizeX <= 0) { printf("SymbolSizeX: %10.5f is negative!\n", LINK->SymbolSizeX); printf("Program error!\n"); halt(); } if (LINK->SymbolSizeY > 0) return; /* writeln(output, '=================================================='); */ printf("SymbolSizeY: %10.5f is negative!\n", LINK->SymbolSizeY); printf("Program error!\n"); halt(); } #undef debugging Local Void grab(Xvalue, Xcolumn, Yvalue, Ycolumn, LINK) double *Xvalue; long Xcolumn; double *Yvalue; long Ycolumn; struct LOC_themain *LINK; { /* grab the X value from column X and the Y value from column Y */ long column = 1; /* count of column number */ /* copyaline(data,output); halt; */ while (column < Xcolumn) { /* writeln(output,'skip x'); */ skipcolumn(LINK->data); column++; } fscanf(LINK->data->f, "%lg", Xvalue); /* write (output,'Xvalue: ',Xvalue:10:5); writeln(output,' column: ',column:5); */ column++; while (column < Ycolumn) { skipcolumn(LINK->data); column++; } fscanf(LINK->data->f, "%lg", Yvalue); fscanf(LINK->data->f, "%*[^\n]"); getc(LINK->data->f); /* write (output,'Yvalue: ',Yvalue:10:5); writeln(output,' column: ',column:5); halt; */ } Local Void fail() { /* explain the failure */ printf("PROGRAM ERROR: This datum is outside the acceptable range.\n"); halt(); } /* fail */ Local Void fillonedatum(LINK) struct LOC_themain *LINK; { /* read and store one data item */ /* writeln(output,'fillonedatum'); */ if ((P_peek(LINK->data->f) == '*') | (P_peek(LINK->data->f) == '#') | P_eoln(LINK->data->f)) { fscanf(LINK->data->f, "%*[^\n]"); getc(LINK->data->f); return; } LINK->dataCount++; /* writeln(output,'fillonedatum: I see data, ',dataCount:1); */ /* obtain data in either order ... */ if (LINK->xlessthany) grab(&LINK->Xvalue, LINK->Xcolumn, &LINK->Yvalue, LINK->Ycolumn, LINK); else grab(&LINK->Yvalue, LINK->Ycolumn, &LINK->Xvalue, LINK->Xcolumn, LINK); /* write (output,'dataCount: ',dataCount:NuWi); write (output,', Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,', Yvalue: ',Yvalue:NuWi:NuDe); writeln(output,'fillonedatum: past grab'); */ /*PROPOSED BUG FIX: if (Xvalue <= XmaxValue) and (Xvalue >= XminValue) the upper bound should NOT be included */ if (LINK->XminValue <= LINK->Xvalue && LINK->Xvalue < LINK->XmaxValue) { /* 2004 Feb 11: the original computation was: Xbin := trunc( Xintervals * ((Xvalue - XminValue)/ Xrange)); This computation would give 14.9999 that would trunc to 14, when the EXACT value was 15. To solve (?) this problem The integer computations are now done first: */ LINK->Xbin = (long)(LINK->Xintervals * (LINK->Xvalue - LINK->XminValue) / LINK->Xrange); /*ttt*/ /* if (Xvalue >= -4) and (Xvalue < -3) and (Yvalue >= -4) and (Yvalue < -3) then begin write (output,'dataCount: ',dataCount:NuWi); write (output,', Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,', Yvalue: ',Yvalue:NuWi:NuDe); writeln(output,'fillonedatum: past grab'); writeln(output,' minValue: ',minValue:NuWi); writeln(output,' maxValue: ',maxValue:NuWi); writeln(output,' Xbin: ', Xbin:NuWi); writeln(output,' Xintervals: ',Xintervals:NuWi); writeln(output,' Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,' XminValue: ',XminValue:NuWi:NuDe); writeln(output,' Xrange: ',Xrange:NuWi:NuDe); writeln(output,' (Xvalue - XminValue): ',(Xvalue - XminValue):NuWi:NuDe); writeln(output,' (Xvalue - XminValue)/Xrange: ', ((Xvalue - XminValue)/Xrange):NuWi:NuDe); writeln(output,' Xintervals *(Xvalue - XminValue)/Xrange: ', (Xintervals *(Xvalue - XminValue)/Xrange):NuWi:NuDe); writeln(output,' Xintervals *(Xvalue - XminValue)/Xrange: ', (Xintervals *(Xvalue - XminValue)/Xrange):50:45); writeln(output,' trunc(Xintervals *(Xvalue - XminValue)/Xrange): ', trunc(Xintervals *(Xvalue - XminValue)/Xrange):5); writeln(output,'---'); writeln(output,'trunc( Xintervals * ((Xvalue - XminValue)/ Xrange))', trunc( Xintervals * ((Xvalue - XminValue)/ Xrange)):5); writeln(output,'===2'); bubba := ((Xvalue - XminValue)/ Xrange); writeln(output,'bubba:', yvalue:NuWi:NuDe); bubba := Xintervals*((Xvalue - XminValue)/ Xrange); writeln(output,'bubba:', yvalue:NuWi:NuDe); bubba := trunc(Xintervals*((Xvalue - XminValue)/ Xrange)); writeln(output,'bubba:', yvalue:NuWi:NuDe); writeln(output,'===2'); writeln(output,'===3'); bubba := ((Xvalue - XminValue)/ Xrange); writeln(output,'bubba:', yvalue:50:45); bubba := Xintervals*((Xvalue - XminValue)/ Xrange); writeln(output,'bubba:', yvalue:50:45); bubba := trunc(Xintervals*((Xvalue - XminValue)/ Xrange)); writeln(output,'bubba:', yvalue:50:45); writeln(output,'xbin:', xbin:NuWi); writeln(output,'===3'); writeln(output,' BIG Xvalue: ',Xvalue:50:45); (* halt; *) end; */ /* write (output,', Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,', Xbin: ',Xbin:NuWi); */ /* protect the program */ if (LINK->Xbin < minValue) { printf("fillonedatum: X < minValue = %ld\n", (long)minValue); /* writeln(output,', Xbin: ', Xbin:NuWi); writeln(output,', minValue: ',minValue:NuWi); writeln(output,', maxValue: ',maxValue:NuWi); writeln(output,', Xintervals: ',Xintervals:NuWi); writeln(output,', Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,', XminValue: ',XminValue:NuWi:NuDe); writeln(output,', Xrange: ',Xrange:NuWi:NuDe); */ fail(); } if (LINK->Xbin > maxValue) { printf("fillonedatum: Xbin > maxValue = %ld\n", (long)maxValue); fail(); } LINK->XinCount++; LINK->Xin = true; if (LINK->Xbin < LINK->Xlo) LINK->Xlo = LINK->Xbin; if (LINK->Xbin > LINK->Xhi) LINK->Xhi = LINK->Xbin; } else { LINK->Xbin = LONG_MAX; LINK->XoutCount++; LINK->Xin = false; } /*PROPOSED BUG FIX: if (Yvalue <= YmaxValue) and (Yvalue >= YminValue) */ if (LINK->YminValue <= LINK->Yvalue && LINK->Yvalue < LINK->YmaxValue) { /* Original: Ybin := trunc( Yintervals * ((Yvalue - YminValue)/ Yrange)); see notes for Xbin above */ LINK->Ybin = (long)(LINK->Yintervals * (LINK->Yvalue - LINK->YminValue) / LINK->Yrange); /* protect the program */ if (LINK->Ybin < minValue) { printf("fillonedatum: Y < minValue = %ld\n", (long)minValue); fail(); } if (LINK->Ybin > maxValue) { printf("fillonedatum: Ybin > maxValue = %ld\n", (long)maxValue); fail(); } LINK->YinCount++; LINK->Yin = true; if (LINK->Ybin < LINK->Ylo) LINK->Ylo = LINK->Ybin; if (LINK->Ybin > LINK->Yhi) LINK->Yhi = LINK->Ybin; } else { LINK->Ybin = LONG_MAX; LINK->YoutCount++; LINK->Yin = false; } /* if Xbin = 15 then begin writeln(output,'good ol'' Bubba pre in test'); (* ttt halt *) end; */ if (LINK->Yin && LINK->Xin) { LINK->bins[LINK->Xbin - minValue][LINK->Ybin - minValue]++; LINK->inCount++; /* if (Xvalue >= -4.0) and (Xvalue < -3.0) then begin (*tttt *) writeln(output, 'Xvalue = ', Xvalue:1); write (output,' Xbin: ',Xbin:2); write (output,' Ybin: ',Ybin:2); writeln(output,' bins[',Xbin:1,',',Ybin:1,']: ',bins[Xbin,Ybin]:1); end; if Xbin = 15 then begin writeln(output,'good ol'' Bubba'); (* halt *) end; */ /* writeln(output,' incount: ',incount:NuWi); writeln(output,' Xvalue: ',Xvalue:NuWi:NuDe); writeln(output,' Yvalue: ',Yvalue:NuWi:NuDe); */ } else LINK->outCount++; } Local Void fillbins(LINK) struct LOC_themain *LINK; { /* fill the bins with data */ printf("filling bins ...\n"); if (*LINK->data->name != '\0') { if (LINK->data->f != NULL) LINK->data->f = freopen(LINK->data->name, "r", LINK->data->f); else LINK->data->f = fopen(LINK->data->name, "r"); } else rewind(LINK->data->f); if (LINK->data->f == NULL) _EscIO2(FileNotFound, LINK->data->name); RESETBUF(LINK->data->f, Char); if (LINK->numbertoprocess < 0) { while (!BUFEOF(LINK->data->f)) fillonedatum(LINK); } else { while (!BUFEOF(LINK->data->f) && LINK->dataCount < LINK->numbertoprocess) fillonedatum(LINK); } printf("filled, dataCount = %ld\n", LINK->dataCount); } /* Local variables for findbinmax: */ struct LOC_findbinmax { struct LOC_themain *LINK; long b; /* bin value */ long Xbin, Ybin; /* current bin location for the data */ } ; Local Void showlocation(X, Y, LINK) long X, Y; struct LOC_findbinmax *LINK; { /* show the location at (X, Y) in user coordinates */ LINK->LINK->Xvalue = LINK->LINK->Xrange * ((double)X / LINK->LINK->Xintervals) + LINK->LINK->XminValue; LINK->LINK->Yvalue = LINK->LINK->Yrange * ((double)Y / LINK->LINK->Yintervals) + LINK->LINK->YminValue; /* show internal coordinates only if debugging */ if (debugging_) printf("[%ld, %*ld]=>", X, (int)LINK->LINK->NuWi, Y); printf("at (%1.*f, %1.*f)\n", (int)LINK->LINK->NuWi, LINK->LINK->Xvalue, (int)LINK->LINK->NuWi, LINK->LINK->Yvalue); /* writeln(output, 'at (',Xvalue:1:NuWi,', ',Yvalue:1:NuWi,') ', bins[X,Y]:1); */ } /* showlocation */ Local boolean IsOutsideData(X, Y, LINK) long X, Y; struct LOC_findbinmax *LINK; { /* Is the point (X, Y) outside the plot range? */ if (X < LINK->LINK->Xlo || X > LINK->LINK->Xhi || Y < LINK->LINK->Ylo || Y > LINK->LINK->Yhi) return true; else return false; } /* IsOutsideData */ Local Void around(SearchRange, LINK) long SearchRange; struct LOC_findbinmax *LINK; { /* debug routine, show the stuff around (Xbin, Ybin) */ long tryX, tryY; /* a possible location to try */ long loops = 0; /* count of number of loops */ long FORLIM, FORLIM1; FORLIM = LINK->Ybin - SearchRange; /* for tryX := Xbin - SearchRange to Xbin + SearchRange do begin for tryY := Ybin - SearchRange to Ybin + SearchRange do begin */ /* make the loop go so it prints x horizontal and y vertical: */ for (tryY = LINK->Ybin + SearchRange; tryY >= FORLIM; tryY--) { FORLIM1 = LINK->Xbin + SearchRange; for (tryX = LINK->Xbin - SearchRange; tryX <= FORLIM1; tryX++) { if (IsOutsideData(tryX, tryY, LINK)) printf(" +"); else { LINK->b = LINK->LINK->bins[tryX - minValue][tryY - minValue]; if (tryX == LINK->Xbin && tryY == LINK->Ybin) putchar('('); else if (tryX - 1 == LINK->Xbin && tryY == LINK->Ybin) putchar(')'); else putchar(' '); printf("%ld", LINK->b); } loops++; } printf(" %2ld\n", tryY); /* writeln(output,' ',loops:1); */ } } /* range */ Local Void findbinmax(denploxyin, BinMax, LINK) _TEXT *denploxyin; long *BinMax; struct LOC_themain *LINK; { /* Find the bin with the maximum number in it. BinMax is the maximumly filled bin. If findpeak is 'l' then a local maximum starting from (startX, startY) is searched for with the given SearchRange. */ struct LOC_findbinmax V; boolean done; /* done with local search algorithm */ long nextX, nextY; /* a possible next location */ long newBinMax; /* a possible new value for BinMax */ long tryX, tryY; /* a possible location to try */ long step; /* count of number of steps */ long loops; /* count of number of loops */ long FORLIM, FORLIM1; /* findpeak := ' '; (* debug *) findpeak := 'l'; (* debug *) */ V.LINK = LINK; if (LINK->findpeak != 'l') { printf("Finding GLOBAL MAXIMUM for the entire plot\n"); *BinMax = 0; FORLIM = LINK->Xhi; for (V.Xbin = LINK->Xlo; V.Xbin <= FORLIM; V.Xbin++) { FORLIM1 = LINK->Yhi; for (V.Ybin = LINK->Ylo; V.Ybin <= FORLIM1; V.Ybin++) { V.b = LINK->bins[V.Xbin - minValue][V.Ybin - minValue]; if (V.b > *BinMax) { *BinMax = V.b; nextX = V.Xbin; nextY = V.Ybin; } } } V.Xbin = nextX; V.Ybin = nextY; if (debugging_) around(2L, &V); if (debugging_) showlocation(V.Xbin, V.Ybin, &V); } else { printf("Finding LOCAL MAXIMUM starting from"); printf(" (%1.*f, %1.*f)\n", (int)LINK->NuWi, LINK->startX, (int)LINK->NuWi, LINK->startY); printf("with a SearchRange of %ld\n", LINK->SearchRange); /* (* see notes in writedenploxyin on the packing function *) Xbin := trunc( Xintervals * ((startX - XminValue)/ Xrange)); Ybin := trunc( Yintervals * ((startY - YminValue)/ Yrange)); */ /* 2005 May 31: I had to add the 0.5 to make sure these matched the start point: */ V.Xbin = (long)(0.5 + LINK->Xintervals * ((LINK->startX - LINK->XminValue) / LINK->Xrange)); V.Ybin = (long)(0.5 + LINK->Yintervals * ((LINK->startY - LINK->YminValue) / LINK->Yrange)); /* halt; */ if (debugging_) showlocation(V.Xbin, V.Ybin, &V); /* This should match the user startX and startY. */ if (IsOutsideData(V.Xbin, V.Ybin, &V)) { printf("WARNING: Point (%1.*f, %1.*f) is outside the data!\n", (int)LINK->NuWi, LINK->startX, (int)LINK->NuWi, LINK->startY); showlocation(V.Xbin, V.Ybin, &V); } else printf("Good, that point is inside the graph!\n"); /* Core local maximum algorithm */ /* Let's start with something very simple */ /* yes, it looks at its old spot stupidly */ if (debugging_) LINK->SearchRange = 3; if (debugging_) around(LINK->SearchRange, &V); /* SearchRange := 1; */ *BinMax = 0; newBinMax = 0; step = 0; loops = 0; done = false; nextX = V.Xbin; nextY = V.Ybin; showlocation(V.Xbin, V.Ybin, &V); /* show the start again */ while (!done) { /* look at the 8 positions around the current (Xbin,Ybin) stupidly including (Xbin,Ybin) to find a better one */ if (debugging_) printf("BinMax=%ld\n", *BinMax); FORLIM = V.Xbin + LINK->SearchRange; for (tryX = V.Xbin - LINK->SearchRange; tryX <= FORLIM; tryX++) { FORLIM1 = V.Ybin + LINK->SearchRange; for (tryY = V.Ybin - LINK->SearchRange; tryY <= FORLIM1; tryY++) { if (!IsOutsideData(tryX, tryY, &V)) { V.b = LINK->bins[tryX - minValue][tryY - minValue]; if (debugging_) printf("b=%ld ", V.b); if (debugging_) showlocation(tryX, tryY, &V); if (V.b > newBinMax) { newBinMax = V.b; if (debugging_) printf("grab newBinMax=%ld\n", newBinMax); nextX = tryX; nextY = tryY; step++; } } else { if (debugging_) printf("outside of data\n"); if (debugging_) halt(); } } } if (debugging_) printf("after square: newBinMax=%ld\n", newBinMax); if (debugging_) printf("after square: BinMax=%ld\n", *BinMax); if (newBinMax == *BinMax) { if (debugging_) printf("NO MOVE\n"); /* there was no better one! */ done = true; } else { if (debugging_) printf("MOVE\n"); /* move to the new location */ V.Xbin = nextX; V.Ybin = nextY; *BinMax = newBinMax; if (debugging_) printf("NEW location: \n"); printf("%ld ", LINK->bins[V.Xbin - minValue][V.Ybin - minValue]); showlocation(V.Xbin, V.Ybin, &V); } if (debugging_) around(LINK->SearchRange, &V); loops++; if (debugging_) printf("loops: %ld------------------------------------\n", loops); if (debugging_) { if (loops > 4) halt(); } } } printf("The highest number of points in a bin is: %ld ", *BinMax); showlocation(V.Xbin, V.Ybin, &V); } /* findbinmax */ #undef debugging_ Local Void writedenplopxyin(denploxyin, BinMax, k, LINK) _TEXT *denploxyin; long BinMax; Char k; struct LOC_themain *LINK; { /* writedenplopxyin and output results. BinMax is the maximumly filled bin. k is the first character to write on the line. */ long b; /* bin value */ double r; /* bin ratio = b/sum */ double hue; /* conversion of r to a color */ double saturation; /* conversion of r to a color */ double brightness; /* conversion of r to a color */ long Xbin, Ybin; /* current bin location for the data */ long FORLIM, FORLIM1; printf("writing denplopxyin ...\n"); fprintf(denploxyin->f, "\n%c definition of data columns:\n", k); fprintf(denploxyin->f, "%c 1: X coordinate\n", k); fprintf(denploxyin->f, "%c 2: Y coordinate\n", k); fprintf(denploxyin->f, "%c 3: total counts at this position\n", k); fprintf(denploxyin->f, "%c 4: (counts at this bit-position) / (maximum bin count)\n", k); fprintf(denploxyin->f, "%c 5: X plotting coordinate\n", k); fprintf(denploxyin->f, "%c 6: Y plotting coordinate\n", k); fprintf(denploxyin->f, "%c 7: SymbolSizeX: X column size control\n", k); fprintf(denploxyin->f, "%c 8: SymbolSizeY: Y column size control\n", k); fprintf(denploxyin->f, "%c 9: hue\n", k); fprintf(denploxyin->f, "%c 10: saturation\n", k); fprintf(denploxyin->f, "%c 11: brightness\n\n", k); fprintf(denploxyin->f, "%c maximum bin count, Binmax: %ld\n\n", k, BinMax); FORLIM = LINK->Xintervals; /* the packing function is: Xbin := trunc( Xintervals * ((Xvalue - XminValue)/ Xrange)); So for min values, it goes to zero. Xbinmax := trunc( Xintervals * ((XmaxValue - XminValue)/ Xrange)); Ybinmax := trunc( Yintervals * ((YmaxValue - YminValue)/ Yrange)); but XmaxValue - XminValue is the Xrange, so this all drops out! Xbinmin := 0; Ybinmin := 0; Xbinmax := Xintervals; Ybinmax := Xintervals; */ for (Xbin = 0; Xbin < FORLIM; Xbin++) { putc('\n', denploxyin->f); FORLIM1 = LINK->Yintervals; /* separate y lines for gnuplot. see gnuplot> help contour */ for (Ybin = 0; Ybin < FORLIM1; Ybin++) { b = LINK->bins[Xbin - minValue][Ybin - minValue]; /* write (output,' Xbin: ',Xbin:2); write (output,' Ybin: ',Ybin:2); write (output,' b: ',b:NuWi); writeln(output,' background: ',background:NuWi); */ determinecolors(LINK->cog, b, BinMax, &r, LINK->cutofftype, LINK->cutoffvaluemin, LINK->cutoffvaluemax, Xbin, Ybin, &hue, &saturation, &brightness, LINK); /*zzz*/ if (LINK->background != 'w' || b != 0) { /* write (output,' Xbin: ',Xbin:2); write (output,' Ybin: ',Ybin:2); write (output,' b: ',b:NuWi); writeln(output,' background: ',background:NuWi); */ /* the packing function is: Xbin := trunc( Xintervals * ((Xvalue - XminValue)/ Xrange)); so unpacking should be the inverse: */ LINK->Xvalue = LINK->Xrange * ((double)Xbin / LINK->Xintervals) + LINK->XminValue; LINK->Yvalue = LINK->Yrange * ((double)Ybin / LINK->Yintervals) + LINK->YminValue; /*ttt*/ /* if Xvalue > -5 then begin writeln(output, 'Xvalue = ', Xvalue:1); write (output,' Xbin: ',Xbin:2); write (output,' Ybin: ',Ybin:2); write (output,' b: ',b:NuWi); writeln(output,' background: ',background:NuWi); end; */ /* halt */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* 10 */ fprintf(denploxyin->f, "%*.*f %*.*f %*ld %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f %*.*f\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xvalue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Yvalue, (int)LINK->NuWi, b, (int)LINK->NuWi, (int)LINK->NuDe, r, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xvalue + LINK->shiftX, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Yvalue + LINK->shiftY, (int)LINK->NuWi, (int)LINK->NuDe, LINK->SymbolSizeX, (int)LINK->NuWi, (int)LINK->NuDe, LINK->SymbolSizeY, (int)LINK->NuWi, (int)LINK->NuDe, hue, (int)LINK->NuWi, (int)LINK->NuDe, saturation, (int)LINK->NuWi, (int)LINK->NuDe, brightness); /* p2c: denplo.p, line 3427: * Note: Line breaker spent 0.0 seconds, 5000 tries on line 3737 [251] */ /* 11 */ } } } putc('\n', denploxyin->f); printf("finished writing denplopxyin\n"); } /* writedenplopxyin */ /***********************************************************************/ Local Void mkdenploxyplop(denploxyplop, LINK) _TEXT *denploxyplop; struct LOC_themain *LINK; { /* make the denploxyplop file */ long graphXintervals; /* the X intervals for the graph */ long graphYintervals; /* the Y intervals for the graph */ Char crosshairsymbol; /* the symbol that defines the crosshair to use */ /* if true then cross hairs put on zero of x and y */ /* strings for calling postscriptstring: */ string instring; /* from xyplo 9.01: zc if zc='c' then a crosshairs put on zero of x and y 'x' then only X axis is plotted 'X' then only X axis and crosshairs 'y' then only Y axis is plotted 'Y' then only Y axis and crosshairs 'n' then neither axis nor crosshairs 'N' then neither axis with crosshairs 'i' then numbering and tic marks but no line (invisible) */ /* smart crosshairs: determine crosshairs automatically */ if (LINK->XminValue <= 0.0 && LINK->XmaxValue >= 0.0 || LINK->YminValue <= 0.0 && LINK->YmaxValue >= 0.0) { /* p2c: denplo.p: Note: Eliminated unused assignment statement [338] */ crosshairsymbol = 'c'; } else { /* p2c: denplo.p: Note: Eliminated unused assignment statement [338] */ crosshairsymbol = 'a'; } /* graphXintervals := Xintervals; graphYintervals := Yintervals; ddd if graphXintervals > MaxDisplayIntervals then graphXintervals := MaxDisplayIntervals; if graphYintervals > MaxDisplayIntervals then graphYintervals := MaxDisplayIntervals; */ if (LINK->XDisplayIntervals > 0) graphXintervals = LINK->XDisplayIntervals; else graphXintervals = LINK->Xintervals; if (LINK->YDisplayIntervals > 0) graphYintervals = LINK->YDisplayIntervals; else graphYintervals = LINK->Yintervals; if (*denploxyplop->name != '\0') { if (denploxyplop->f != NULL) denploxyplop->f = freopen(denploxyplop->name, "w", denploxyplop->f); else denploxyplop->f = fopen(denploxyplop->name, "w"); } else { if (denploxyplop->f != NULL) { rewind(denploxyplop->f); } else denploxyplop->f = tmpfile(); } if (denploxyplop->f == NULL) _EscIO2(FileNotFound, denploxyplop->name); SETUPBUF(denploxyplop->f, Char); fprintf(denploxyplop->f, "%*.*f %*.*f zerox zeroy\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xcorner, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Ycorner); fprintf(denploxyplop->f, "x %*.*f %*.*f zx min max\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->XminValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->XmaxValue); fprintf(denploxyplop->f, "y %*.*f %*.*f zy min max\n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->YminValue, (int)LINK->NuWi, (int)LINK->NuDe, LINK->YmaxValue); fprintf(denploxyplop->f, "%ld %ld %ld %ld Display Intervals (X,Y) Display SubIntervals (X,Y)\n", graphXintervals, graphYintervals, LINK->XDisplaySubIntervals, LINK->YDisplaySubIntervals); /* 2005 May 29: remove the word 'Display' so that these lines are not wraping: ' XDisplayIntervals YDisplayIntervals', ' XDisplaySubIntervals YDisplaySubIntervals '); */ fprintf(denploxyplop->f, "%ld %ld xwidth ywidth \n", LINK->xwidth, LINK->ywidth); fprintf(denploxyplop->f, "%ld %ld xdecimal ydecimal \n", LINK->xdecimal, LINK->ydecimal); fprintf(denploxyplop->f, "%*.*f %*.*f xsize ysize \n", (int)LINK->NuWi, (int)LINK->NuDe, LINK->Xsize, (int)LINK->NuWi, (int)LINK->NuDe, LINK->Ysize); /* writeln(denploxyplop,', data counts: ',inCount:1); */ /* maybe implement \c to produce data counts into the strings someday ... */ /* */ writestring(denploxyplop, &LINK->XaxisLabel); putc('\n', denploxyplop->f); writestring(denploxyplop, &LINK->YaxisLabel); fprintf(denploxyplop->f, "\n%c zc \n", crosshairsymbol); /* Do NOT use postscriptstring! That takes ( and ) and puts \ infront! 2009 Apr 02 copystring(XaxisLabel, instring); postscriptstring(instring, outstring, rawstring, 0.0, 0.0, 52); writestring(denploxyplop, outstring); writeln(denploxyplop); copystring(YaxisLabel, instring); postscriptstring(instring, outstring, rawstring, 0.0, 0.0, 58); writestring(denploxyplop, outstring); writeln(denploxyplop); */ /* postscriptstring(var instring, outstring, rawstring: string; NOT USED var symvec: text; NOT USED lowest, highest: integer; rs, sd: real; n: integer; NOT USED havers, havesd: boolean ); */ fprintf(denploxyplop->f, "n 2 zxl base \n"); fprintf(denploxyplop->f, "n 2 zyl base \n"); fprintf(denploxyplop->f, " *******"); fprintf(denploxyplop->f, " This xyplop was produced by denplo %4.2f\n", version); fprintf(denploxyplop->f, "5 6 xcolumn ycolumn \n"); fprintf(denploxyplop->f, "0 symbol column \n"); fprintf(denploxyplop->f, "7 8 xscolumn yscolumn \n"); fprintf(denploxyplop->f, "9 10 11 hue saturation brightness\n"); fprintf(denploxyplop->f, " ********************\n"); fprintf(denploxyplop->f, "R symbol-to-plot \n"); fprintf(denploxyplop->f, "i symbol-flag \n"); fprintf(denploxyplop->f, "-1.0 symbol sizex \n"); fprintf(denploxyplop->f, "-1.0 symbol sizey \n"); fprintf(denploxyplop->f, "n connection size \n"); fprintf(denploxyplop->f, "n 0.125 linetype size \n"); fprintf(denploxyplop->f, " ********************\n"); fprintf(denploxyplop->f, ".\n"); fprintf(denploxyplop->f, " ********************\n"); /* writeln(denploxyplop,'l 0 0 0.125 User defined line'); */ fprintf(denploxyplop->f, " **** more parameters\n"); fprintf(denploxyplop->f, "%c %4.2f %4.2f %4.2f %4.2f edgecontrol (p=page), edge: left,right,low,high in cm\n", LINK->edgecontrol, LINK->edgeleft, LINK->edgeright, LINK->edgelow, LINK->edgehigh); /* writeln(denploxyplop,'p 1.50 1.50 1.50 1.50 edgecontrol (p=page),', ' edgeleft, edgeright, edgelow, edgehigh in cm'); */ /* this is nice, but it is not part of xyplo!! writeln(denploxyplop, findpeak, ' ',startX:4:2, ' ',startY:4:2, ' findpeak (l=find locally),', ' start at (startX, startY)'); */ /*ppp*/ fprintf(denploxyplop->f, "8.91 version of xyplo that this parameter file is designed for.\n"); } /* mkdenploxyplop */ /***********************************************************************/ Local Void report(f, k, LINK) _TEXT *f; Char k; struct LOC_themain *LINK; { /* report values to file f, with k as the first character */ fprintf(f->f, "%c %*ld data points were INSIDE the plot\n", k, (int)LINK->NuWi, LINK->inCount); fprintf(f->f, "%c %*ld data points were OUTSIDE the plot\n", k, (int)LINK->NuWi, LINK->outCount); fprintf(f->f, "%c %*ld total data points\n", k, (int)LINK->NuWi, LINK->outCount + LINK->inCount); /* writeln(f,k,' Xlo: ',Xlo:NuWi); writeln(f,k,' Xhi: ',Xhi:NuWi); writeln(f,k,' Ylo: ',Ylo:NuWi); writeln(f,k,' Yhi: ',Yhi:NuWi); */ } /* end module copyfile version = 4.86; (@ of prgmod.p 2004 Sep 8 */ /* begin module denplo.themain */ Static Void themain(data_, denplop, denploxyin, denploxyplom, denploxyplop) _TEXT *data_, *denplop, *denploxyin, *denploxyplom, *denploxyplop; { /* the main procedure of the program */ struct LOC_themain V; _TEXT TEMP; V.data = data_; printf("denplo %4.2f\n", version); readparameters(denplop, &V); TEMP.f = stdout; *TEMP.name = '\0'; writeparameters(&TEMP, ' ', &V); buildxyplom(denploxyplom, &V); setvariables(&V); if (*V.data->name != '\0') { if (V.data->f != NULL) V.data->f = freopen(V.data->name, "r", V.data->f); else V.data->f = fopen(V.data->name, "r"); } else rewind(V.data->f); if (V.data->f == NULL) _EscIO2(FileNotFound, V.data->name); RESETBUF(V.data->f, Char); fillbins(&V); if (*denploxyin->name != '\0') { if (denploxyin->f != NULL) denploxyin->f = freopen(denploxyin->name, "w", denploxyin->f); else denploxyin->f = fopen(denploxyin->name, "w"); } else { if (denploxyin->f != NULL) rewind(denploxyin->f); else denploxyin->f = tmpfile(); } if (denploxyin->f == NULL) _EscIO2(FileNotFound, denploxyin->name); SETUPBUF(denploxyin->f, Char); writeparameters(denploxyin, komment, &V); /*yyy*/ /* when findpeak is 'b', BinMax is given by the user */ if (V.findpeak != 'm') findbinmax(denploxyin, &V.BinMax, &V); writedenplopxyin(denploxyin, V.BinMax, komment, &V); mkdenploxyplop(denploxyplop, &V); TEMP.f = stdout; *TEMP.name = '\0'; report(&TEMP, ' ', &V); report(denploxyin, komment, &V); /* (* for testing: *) keyintervals := 5; keytype := 'f'; keytype := 'n'; keyX := 1.5; keyY := 0.0; keyXsize := 2.0; keyysize := 1.0; keydecimals := 1; keyshrinkfactor := 0.8; thelinewidth := 0.005; */ if (V.keyintervals > 0) colorkey(denploxyplom, V.keytype, V.BinMax, V.cog, V.keyX + V.Xcorner, V.keyY + V.Ycorner, V.keyXsize, V.keyYsize, V.keydecimals, V.keyintervals, V.keyshrinkfactor, V.keyfontsize, V.cutofftype, V.cutoffvaluemin, V.cutoffvaluemax, V.thelinewidth, &V); printf("denplo %4.2f is DONE\n", version); } /* end module denplo.themain */ main(argc, argv) int argc; Char *argv[]; { PASCAL_MAIN(argc, argv); if (setjmp(_JL1)) goto _L1; denploxyplop.f = NULL; strcpy(denploxyplop.name, "denploxyplop"); denploxyplom.f = NULL; strcpy(denploxyplom.name, "denploxyplom"); denploxyin.f = NULL; strcpy(denploxyin.name, "denploxyin"); denplop.f = NULL; strcpy(denplop.name, "denplop"); data.f = NULL; strcpy(data.name, "data"); themain(&data, &denplop, &denploxyin, &denploxyplom, &denploxyplop); _L1: if (data.f != NULL) fclose(data.f); if (denplop.f != NULL) fclose(denplop.f); if (denploxyin.f != NULL) fclose(denploxyin.f); if (denploxyplom.f != NULL) fclose(denploxyplom.f); if (denploxyplop.f != NULL) fclose(denploxyplop.f); exit(EXIT_SUCCESS); } /* End. */