1 /* @source ajhist *************************************************************
2 **
3 ** AJAX GRAPH (ajax histogram) functions
4 **
5 ** These functions control all aspects of AJAX histogram.
6 **
7 ** @author Copyright (C) 1998 Peter Rice
8 ** @version $Revision: 1.32 $
9 ** @modified 1988-11-12 pmr First version
10 ** @modified 1999 ajb ANSIfication
11 ** @modified $Date: 2011/11/08 15:12:19 $ by $Author: rice $
12 ** @@
13 **
14 ** This library is free software; you can redistribute it and/or
15 ** modify it under the terms of the GNU Lesser General Public
16 ** License as published by the Free Software Foundation; either
17 ** version 2.1 of the License, or (at your option) any later version.
18 **
19 ** This library is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22 ** Lesser General Public License for more details.
23 **
24 ** You should have received a copy of the GNU Lesser General Public
25 ** License along with this library; if not, write to the Free Software
26 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 ** MA  02110-1301,  USA.
28 **
29 ******************************************************************************/
30 
31 
32 #include "ajlib.h"
33 
34 #include "ajhist.h"
35 #include "ajgraph.h"
36 
37 #include <limits.h>
38 #include <float.h>
39 
40 
41 ajint aj_hist_mark=GRAPH_HIST;
42 
43 
44 
45 
46 /* @filesection ajhist *******************************************************
47 **
48 ** @nam1rule aj Function belongs to the AJAX library.
49 **
50 */
51 
52 
53 
54 
55 /* @datasection [none] Histogram internals ************************************
56 **
57 ** Function is for controlling the histogram internals without using
58 ** an AjPGraph object
59 **
60 ** @nam2rule Histogram
61 */
62 
63 
64 
65 
66 /* @section modifiers **********************************************************
67 **
68 ** Controlling the internals
69 **
70 ** @fdata [none]
71 ** @fcategory modify
72 **
73 ** @nam3rule Close Close a histogram plot
74 ** @nam3rule Set Set internal state
75 ** @nam4rule Mark Set the histogram mark internal value
76 **
77 ** @argrule Mark mark [ajint] Mark value
78 **
79 ** @valrule * [void]
80 **
81 ******************************************************************************/
82 
83 
84 
85 
86 /* @func ajHistogramClose *****************************************************
87 **
88 ** Closes the histograms window.
89 **
90 ** @return [void]
91 **
92 **
93 ** @release 6.2.0
94 ** @@
95 ******************************************************************************/
96 
ajHistogramClose(void)97 void ajHistogramClose(void)
98 {
99     ajGraphicsCloseWin();
100 
101     return;
102 }
103 
104 
105 
106 
107 /* @func ajHistogramSetMark ***************************************************
108 **
109 ** Set the histogram mark internal value
110 **
111 ** @param [r] mark [ajint] Mark value
112 ** @return [void]
113 **
114 ** @release 6.2.0
115 ******************************************************************************/
116 
ajHistogramSetMark(ajint mark)117 void ajHistogramSetMark(ajint mark)
118 {
119   aj_hist_mark = mark;
120   return;
121 }
122 
123 
124 
125 
126 /* @datasection [AjPHist] Histogram object *************************************
127 **
128 ** Function is for manipulating an AjPHist histogram object
129 **
130 ** @nam2rule Hist
131 **
132 ******************************************************************************/
133 
134 
135 
136 
137 /* @section Constructors ******************************************************
138 **
139 ** Construct a new histogram object to be populated by other functions
140 **
141 ** @fdata [AjPHist]
142 ** @fcategory new
143 **
144 ** @nam3rule New
145 ** @suffix G New with multiple graphdata
146 **
147 ** @argrule New numofsets [ajuint] Number of sets of data.
148 ** @argrule New numofpoints [ajuint] Number of data points per set.
149 ** @argrule G graph [AjPGraph] Graph object, device, multi and name are set
150 **
151 ** @valrule * [AjPHist] New histogram object
152 **
153 ******************************************************************************/
154 
155 
156 
157 
158 /* @func ajHistNew ************************************************************
159 **
160 ** Create a histogram Object. Which can hold "numofsets" set of data of which
161 ** all must have "numofpoints" data points in them.
162 **
163 ** @param [r] numofsets [ajuint] Number of sets of data.
164 ** @param [r] numofpoints [ajuint] Number of data points per set.
165 ** @return [AjPHist] histogram structure.
166 **
167 ** @release 1.0.0
168 ** @@
169 ******************************************************************************/
170 
ajHistNew(ajuint numofsets,ajuint numofpoints)171 AjPHist ajHistNew(ajuint numofsets, ajuint numofpoints)
172 {
173     static AjPHist hist = NULL;
174     ajuint i;
175 
176     AJNEW0(hist);
177 
178     hist->numofsets = 0;
179     hist->numofsetsmax    = numofsets;
180     hist->numofdatapoints = numofpoints;
181     hist->xmin = 0;
182     hist->xmax = 0;
183     hist->displaytype = HIST_SIDEBYSIDE; /* default draw
184 					    multiple histograms
185 					    side by side */
186     hist->bins = 0;
187     hist->BaW  = AJFALSE;
188     ajStrAssignEmptyC(&hist->title,"");
189     ajStrAssignEmptyC(&hist->xaxis,"");
190     ajStrAssignEmptyC(&hist->yaxisleft,"");
191     ajStrAssignEmptyC(&hist->yaxisright,"");
192 
193     AJCNEW0(hist->hists,numofsets);
194 
195     for(i=0;i<numofsets; i++)
196     {
197 	AJNEW0((hist->hists[i]));
198 	(hist->hists)[i]->data       = NULL;
199 	(hist->hists)[i]->deletedata = AJFALSE;
200 	(hist->hists)[i]->colour  = i+2;
201 	(hist->hists)[i]->pattern = 0;
202 	(hist->hists)[i]->title = NULL;
203 	(hist->hists)[i]->xaxis = NULL;
204 	(hist->hists)[i]->yaxis = NULL;
205     }
206 
207     return hist;
208 }
209 
210 
211 
212 
213 /* @func ajHistNewG ***********************************************************
214 **
215 ** Create a histogram Object which has the histogram data and graph data
216 ** storage capacity.
217 **
218 ** @param [r] numofsets [ajuint] Number of sets of data.
219 ** @param [r] numofpoints [ajuint] Number of data points per set.
220 ** @param [u] graph [AjPGraph] Graph object, device, multi and name are set.
221 **                             The original AjPGraph object will be used
222 **                             by the AjPHist
223 ** @return [AjPHist] histogram structure.
224 **
225 ** @release 1.0.0
226 ** @@
227 ******************************************************************************/
228 
ajHistNewG(ajuint numofsets,ajuint numofpoints,AjPGraph graph)229 AjPHist ajHistNewG(ajuint numofsets, ajuint numofpoints, AjPGraph graph)
230 {
231     AjPHist hist = ajHistNew(numofsets, numofpoints);
232 
233     hist->graph = graph;
234     ajGraphicsSetDevice(graph);
235     ajGraphSetMulti(graph, numofsets);
236     ajGraphicsSetFilename(graph);
237 
238     return hist;
239 }
240 
241 
242 
243 
244 /* @section Destructors *******************************************************
245 **
246 ** Destructors for histogram objects
247 **
248 ** @fdata [AjPHist]
249 ** @fcategory delete
250 **
251 ** @nam3rule Del
252 **
253 ** @argrule Del phist [AjPHist*] Histogram to be deleted.
254 **
255 ** @valrule * [void]
256 **
257 ******************************************************************************/
258 
259 
260 
261 
262 /* @func ajHistDel ************************************************************
263 **
264 ** Delete and free all memory associated with the histogram.
265 ** Does not delete the graph.
266 **
267 ** @param [d] phist [AjPHist*] Histogram to be deleted.
268 ** @return [void]
269 **
270 **
271 ** @release 6.2.0
272 ** @@
273 ******************************************************************************/
274 
ajHistDel(AjPHist * phist)275 void ajHistDel(AjPHist* phist)
276 {
277     ajuint i;
278     AjPHist hist;
279 
280     if(!phist) return;
281 
282     hist = *phist;
283 
284     if (!hist)
285 	return;
286 
287     for(i=0;i<hist->numofsets; i++)
288     {
289 	if(hist->hists[i]->deletedata)
290 	{
291 	    ajStrDel(&hist->hists[i]->title);
292 	    ajStrDel(&hist->hists[i]->xaxis);
293 	    ajStrDel(&hist->hists[i]->yaxis);
294 	    AJFREE(hist->hists[i]->data);
295 	}
296 	AJFREE((hist->hists[i]));
297     }
298 
299     AJFREE(hist->hists);
300 
301     ajStrDel(&hist->title);
302     ajStrDel(&hist->xaxis);
303     ajStrDel(&hist->yaxisleft);
304     ajStrDel(&hist->yaxisright);
305 
306     AJFREE(*phist);
307     return;
308 }
309 
310 
311 
312 
313 /* @section Display ***********************************************************
314 **
315 ** Functions to display or write the histogram
316 **
317 ** @fdata [AjPHist]
318 ** @fcategory use
319 **
320 ** @nam3rule Display Display the histogram
321 **
322 ** @argrule Display thys [const AjPHist] Histogram object
323 **
324 ** @valrule * [void]
325 **
326 ******************************************************************************/
327 
328 
329 
330 
331 /* @func ajHistDisplay ********************************************************
332 **
333 ** Display the histogram.
334 **
335 ** @param [r] thys [const AjPHist] Histogram Structure.
336 ** @return [void]
337 **
338 ** @release 1.0.0
339 ** @@
340 ******************************************************************************/
341 
ajHistDisplay(const AjPHist thys)342 void ajHistDisplay(const AjPHist thys)
343 {
344     PLFLT *data    = NULL;		/* points to data in hist */
345     PLFLT *totals  = NULL;
346     PLFLT *totals2 = NULL;
347     float ptsperbin;
348     float max = FLT_MIN;
349     float min = 0.0;
350     ajuint i;
351     ajuint j;
352     ajint ratioint;
353     ajint num;
354     ajint old;
355     float bin_range;
356     float bar_width;
357     float offset;
358     float start;
359     float tot;
360     float percent5;
361 
362     /* Sanity check */
363     if(thys->numofdatapoints < 1 || thys->numofsets < 1 || thys->bins < 1)
364     {
365 	ajErr("points =%d, sets = %d, bins = %d !!! "
366 	      "Must all be Greater than 1 ",
367 	      thys->numofdatapoints,thys->numofsets,thys->bins);
368 
369 	return;
370     }
371 
372     /* what multiple is the bins to numofdatasets */
373     /* as i may have to take an average if not identical */
374     ptsperbin = (float)thys->numofdatapoints/(float)thys->bins;
375 
376     if(ptsperbin < 1.0)
377     {
378 	ajErr("You cannot more have bins than datapoints!!");
379 
380 	return;
381     }
382     /* is the ratio a whole number? */
383 
384     ratioint = (ajint)ptsperbin;
385 
386     if((ptsperbin - (float)ratioint) != 0.0)
387     {
388 	ajErr("number of data points needs to be a multiple of bins");
389 
390 	return;
391     }
392     /* end Sanity check */
393 
394     /* Add spacing either side */
395     percent5 = (thys->xmax - thys->xmin)*(float)0.025;
396 
397 
398     /* calculate max and min for each set */
399     if(thys->numofsets != 1)
400     {
401 	/* if NOT side by side max and min as the sets added together */
402 	if(thys->displaytype == HIST_SIDEBYSIDE)
403 	{
404 	    /* find the max value */
405 	    max = INT_MIN;
406 	    min = 0;
407 
408 	    for(j=0; j < thys->numofsets; j++)
409 	    {
410 		data = thys->hists[j]->data;
411 
412 		for(i=0;i<thys->numofdatapoints;i++)
413 		{
414 		    if(data[i] > max)
415 			max = data[i];
416 
417 		    if(data[i] < min)
418 			min = data[i];
419 		}
420 	    }
421 	}
422 	else if(thys->displaytype == HIST_ONTOP)
423 	{
424 	    totals = AJALLOC(thys->numofdatapoints*(sizeof(PLFLT)));
425 
426 	    /* set all memory to 0.0 */
427 	    for(i=0;i<thys->numofdatapoints;i++)
428 	    {
429 		totals[i] = 0.0;
430 	    }
431 
432 	    min = 0;
433 	    max = 0;
434 
435 	    for(j=0; j < thys->numofsets; j++)
436 	    {
437 		data = thys->hists[j]->data;
438 		for(i=0;i<thys->numofdatapoints;i++)
439 		{
440 		    totals[i] += data[i];
441 		    if(totals[i] > max)
442 			max = totals[i];
443 
444 		    if(totals[i] < min)
445 			min = totals[i];
446 		    /*	  ajDebug("%d %d\t%f",j,i,totals[i]);*/
447 		}
448 	    }
449 	}
450 	else if(thys->displaytype == HIST_SEPARATE)
451 	{
452 	    totals = AJALLOC(thys->numofsets*(sizeof(PLFLT)));
453 	    totals2 = AJALLOC(thys->numofsets*(sizeof(PLFLT)));
454 
455 	    for(j=0; j < thys->numofsets; j++)
456 	    {
457 		data = thys->hists[j]->data;
458 		totals[j] = 0;
459 		totals2[j] = 0;
460 
461 		for(i=0;i<thys->numofdatapoints;i++)
462 		{
463 		    if(totals[j] < data[i])
464 			totals[j] = data[i];
465 
466 		    if(totals2[j] > data[i])
467 			totals2[j] = data[i];
468 		}
469 	    }
470 	}
471     }
472     else
473     {
474 	data = thys->hists[0]->data;
475 	max = data[0];
476 	min = 0;
477 
478 	for(i=1; i < thys->numofdatapoints; i++)
479 	{
480 	    if(data[i] > max)
481 		max = data[i];
482 
483 	    if(data[i] < min)
484 		min = data[i];
485 	}
486 
487 	if(thys->displaytype == HIST_ONTOP /*!thys->sidebyside*/)
488 	{
489 	    totals = AJALLOC(thys->numofdatapoints*(sizeof(PLFLT)));
490 
491 	    /* set all memory to 0.0 */
492 	    for(i=0; i < thys->numofdatapoints; i++)
493 		totals[i] = 0.0;
494 	}
495 	else if(thys->displaytype == HIST_SEPARATE)
496 	{
497 	    totals = AJALLOC((sizeof(PLFLT)));
498 	    totals[0]= max;
499 	    totals2 = AJALLOC((sizeof(PLFLT)));
500 	    totals2[0]= min;
501 	}
502     }
503 
504     bin_range = (thys->xmax - thys->xmin)/(float)thys->bins;
505 
506     if(thys->displaytype != HIST_SEPARATE)
507     {
508 	if(max <= 0.01)
509 	{
510 	    if(max < 0.0)
511 		max = 0.0;
512 	    else
513 		max = 1.0;
514 	}
515 
516 	ajGraphOpenPlotset(thys->graph, 1);
517 	ajGraphicsPlenv(thys->xmin-percent5, thys->xmax+percent5, min,
518 		     max*((float)1.025), aj_hist_mark);
519 	ajGraphicsSetLabelsS(thys->xaxis ,
520                              thys->yaxisleft ,
521                              thys->title,
522                              thys->subtitle);
523 
524 	ajGraphicsSetRlabelS(thys->yaxisright);
525     }
526     else
527 	ajGraphOpenPlotset(thys->graph, thys->numofsets);
528 
529     if(thys->displaytype == HIST_SIDEBYSIDE)
530     {
531 	bar_width = bin_range/thys->numofsets;
532 
533 	for(i=0; i < thys->numofsets; i++)
534 	{
535 	    offset = i*bar_width;
536 	    start = thys->xmin;
537 	    num = 0;
538 	    tot=0.0;
539 	    data = thys->hists[i]->data;
540 
541 	    for(j=0; j < thys->numofdatapoints; j++)
542 	    {
543 		tot += data[j];
544 		num++;
545 
546 		if(num >= ptsperbin)
547 		{
548 		    tot = tot / (float)num;
549 
550 		    if(thys->BaW)
551 			old = ajGraphicsSetFillpat(thys->hists[i]->pattern);
552 		    else
553 			old = ajGraphicsSetFgcolour(thys->hists[i]->colour);
554 		    ajGraphicsDrawposRectFill(start+offset,0.0,
555                                               start+offset+bar_width,tot);
556 
557 		    if(thys->BaW)
558 			ajGraphicsSetFillpat(old);
559 		    else
560 			ajGraphicsSetFgcolour(old);
561 
562 		    ajGraphicsDrawposRect(start+offset,0.0,
563                                           start+offset+bar_width,tot);
564 		    num = 0;
565 		    tot = 0;
566 		    start +=bin_range;
567 		}
568 	    }
569 	}
570     }
571     else if(thys->displaytype == HIST_SEPARATE)
572     {
573 	bar_width = bin_range;
574 
575 	for(i=0; i < thys->numofsets; i++)
576 	{
577 	    if(totals[i] <= 0.01)
578 	    {			       /* apparently the ymin value */
579 		if(totals[i] < 0.0)
580 		    totals[i] = 0.0;
581 		else
582 		    totals[i] = 1.0;
583 	    }
584 
585 	    ajGraphicsPlenv(thys->xmin - percent5, thys->xmax + percent5,
586                             totals2[i]*((float)1.025), totals[i]*((float)1.025),
587                             aj_hist_mark);
588 	    offset = /*bar_width*/0.0;
589 	    start = thys->xmin;
590 	    num = 0;
591 	    tot=0.0;
592 	    data = thys->hists[i]->data;
593 	    ajGraphicsSetLabelsS(thys->hists[i]->xaxis,
594                                  thys->hists[i]->yaxis,
595                                  thys->hists[i]->title,
596                                  thys->hists[i]->subtitle);
597 
598 	    for(j=0; j < thys->numofdatapoints; j++)
599 	    {
600 		tot += data[j];
601 		num++;
602 
603 		if(num >= ptsperbin)
604 		{
605 		    tot = tot / (float)num;
606 
607 		    if(thys->BaW)
608 			old = ajGraphicsSetFillpat(thys->hists[i]->pattern);
609 		    else
610 			old = ajGraphicsSetFgcolour(thys->hists[i]->colour);
611 
612 		    ajGraphicsDrawposRectFill(start+offset,0.0,
613                                               start+offset+bar_width,tot);
614 
615 		    if(thys->BaW)
616 			ajGraphicsSetFillpat(old);
617 		    else
618 			ajGraphicsSetFgcolour(old);
619 
620 		    ajGraphicsDrawposRect(start+offset,0.0,
621                                           start+offset+bar_width,tot);
622 		    num = 0;
623 		    tot = 0;
624 		    start +=bin_range;
625 		}
626 	    }
627 	}
628     }
629     else if(thys->displaytype == HIST_ONTOP)
630     {
631 	for(i=0; i < thys->numofdatapoints; i++)
632 	    totals[i] = 0.0;
633 
634 	for(i=0; i < thys->numofsets; i++)
635 	{
636 	    data = thys->hists[i]->data;
637 	    start = thys->xmin;
638 	    num = 0;
639 	    tot=0.0;
640 
641 	    for(j=0; j < thys->numofdatapoints; j++)
642 	    {
643 		tot += data[j];
644 		num++;
645 
646 		if(num >= ptsperbin)
647 		{
648 		    tot = tot / (float)num;
649 
650 		    if(thys->BaW)
651 			old = ajGraphicsSetFillpat(thys->hists[i]->pattern);
652 		    else
653 			old = ajGraphicsSetFgcolour(thys->hists[i]->colour);
654 
655 		    ajGraphicsDrawposRectFill(start,totals[j],
656                                               start+bin_range,tot+totals[j]);
657 		    if(thys->BaW)
658 			ajGraphicsSetFillpat(old);
659 		    else
660 			ajGraphicsSetFgcolour(old);
661 
662 		    ajGraphicsDrawposRect(start,totals[j],
663                                           start+bin_range,tot+totals[j]);
664 		    totals[j] += tot;
665 		    tot = 0;
666 		    /*	  ajDebug("num = %d",num);*/
667 		    num = 0;
668 		    start +=bin_range;
669 		}
670 	    }
671 	}
672     }
673 
674     AJFREE(totals);
675     AJFREE(totals2);
676 
677     return;
678 }
679 
680 
681 
682 
683 /* @section modifiers **********************************************************
684 **
685 ** Controlling the internals
686 **
687 ** @fdata [AjPHist]
688 ** @fcategory modify
689 **
690 ** @nam3rule Set Set histogram internals
691 ** @nam3rule Setmulti Set multiple graph member
692 ** @nam4rule Title Histogram title
693 ** @nam4rule Rlabel Right axis label
694 ** @nam4rule Xlabel X-axis label
695 ** @nam4rule Ylabel Y-axis label
696 ** @nam4rule Colour Set colour for a block
697 ** @nam4rule Mono Set to plot in black and white with patterns
698 ** @nam4rule Pattern Set pattern for a block in a black and white histogram
699 ** @suffix C Character data
700 ** @suffix S String data
701 **
702 ** @argrule * thys [AjPHist]  Histogram object
703 ** @argrule Setmulti indexnum [ajuint] Index for the set number
704 ** @argrule Colour colour [ajint] Colour for bar set.
705 ** @argrule Mono set [AjBool] Set to use patterns or colour for filling
706 ** @argrule Pattern style [ajint] Line style number for bar set.
707 ** @argrule C txt [const char*]  Text value
708 ** @argrule S str [const AjPStr]  Text value
709 **
710 ** @valrule * [void]
711 **
712 ******************************************************************************/
713 
714 
715 
716 
717 /* @func ajHistSetMono ********************************************************
718 **
719 ** Set patterns instead of colours for printing to B/W printers etc.
720 **
721 ** @param [u] thys [AjPHist] Histogram to have ptr set.
722 ** @param [r] set [AjBool]    Set to use patterns or colour for filling,
723 **                            false to reset to colour.
724 ** @return [void]
725 **
726 ** @release 6.2.0
727 ** @@
728 ******************************************************************************/
729 
ajHistSetMono(AjPHist thys,AjBool set)730 void ajHistSetMono(AjPHist thys, AjBool set)
731 {
732     thys->BaW = set;
733 
734     return;
735 }
736 
737 
738 
739 
740 /* @func ajHistSetRlabelC *****************************************************
741 **
742 ** Store Y Axis Right Label for the histogram
743 **
744 ** @param [u] thys [AjPHist] histogram to set string in.
745 ** @param [r] txt [const char*] text to be copied.
746 ** @return [void]
747 **
748 ** @release 6.2.0
749 ** @@
750 ******************************************************************************/
751 
ajHistSetRlabelC(AjPHist thys,const char * txt)752 void ajHistSetRlabelC(AjPHist thys, const char* txt)
753 {
754     ajStrAssignC(&thys->yaxisright,txt);
755 
756     return;
757 }
758 
759 
760 
761 
762 /* @func ajHistSetTitleC ******************************************************
763 **
764 ** Copy Title for the histogram.
765 **
766 ** @param [u] thys [AjPHist] histogram to set string in.
767 ** @param [r] txt [const char*] text to be copied.
768 ** @return [void]
769 **
770 ** @release 1.0.0
771 ** @@
772 ******************************************************************************/
773 
ajHistSetTitleC(AjPHist thys,const char * txt)774 void ajHistSetTitleC(AjPHist thys, const char* txt)
775 {
776     ajStrAssignC(&thys->title,txt);
777 
778     return;
779 }
780 
781 
782 
783 
784 /* @func ajHistSetXlabelC *****************************************************
785 **
786 ** Store X axis label for the histogram
787 **
788 ** @param [u] thys [AjPHist] histogram to set string in.
789 ** @param [r] txt [const char*] text to be copied.
790 ** @return [void]
791 **
792 ** @release 6.2.0
793 ** @@
794 ******************************************************************************/
795 
ajHistSetXlabelC(AjPHist thys,const char * txt)796 void ajHistSetXlabelC(AjPHist thys, const char* txt)
797 {
798     ajStrAssignC(&thys->xaxis,txt);
799 
800     return;
801 }
802 
803 
804 
805 
806 /* @func ajHistSetYlabelC *****************************************************
807 **
808 ** Store Y Axis Left Label for the histogram
809 **
810 ** @param [u] thys [AjPHist] histogram to set string in.
811 ** @param [r] txt [const char*] text to be copied.
812 ** @return [void]
813 **
814 ** @release 6.2.0
815 ** @@
816 ******************************************************************************/
817 
ajHistSetYlabelC(AjPHist thys,const char * txt)818 void ajHistSetYlabelC(AjPHist thys, const char* txt)
819 {
820     ajStrAssignC(&thys->yaxisleft,txt);
821 
822     return;
823 }
824 
825 
826 
827 
828 /* @func ajHistSetmultiColour *************************************************
829 **
830 ** Set colour for bars in histogram for index'th set.
831 **
832 ** @param [u] thys [AjPHist] Histogram to have ptr set.
833 ** @param [r] indexnum [ajuint]     Index for the set number.
834 ** @param [r] colour [ajint]    Colour for bar set.
835 ** @return [void]
836 **
837 ** @release 6.2.0
838 ** @@
839 ******************************************************************************/
840 
ajHistSetmultiColour(AjPHist thys,ajuint indexnum,ajint colour)841 void ajHistSetmultiColour(AjPHist thys, ajuint indexnum, ajint colour)
842 {
843     if(indexnum >= thys->numofdatapoints)
844     {
845 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
846 	      thys->numofdatapoints-1,indexnum);
847 
848 	return;
849     }
850 
851     thys->hists[indexnum]->colour = colour;
852 
853     return;
854 }
855 
856 
857 
858 
859 /* @func ajHistSetmultiPattern ************************************************
860 **
861 ** Set colour for bars in histogram for one set.
862 **
863 ** @param [u] thys [AjPHist] Histogram to have ptr set.
864 ** @param [r] indexnum [ajuint]     Index for the set number.
865 ** @param [r] style [ajint]    Line style number for bar set.
866 ** @return [void]
867 **
868 ** @release 6.2.0
869 ** @@
870 ******************************************************************************/
871 
ajHistSetmultiPattern(AjPHist thys,ajuint indexnum,ajint style)872 void ajHistSetmultiPattern(AjPHist thys, ajuint indexnum, ajint style)
873 {
874     if(indexnum >= thys->numofdatapoints)
875     {
876 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
877 	      thys->numofdatapoints-1,indexnum);
878 
879 	return;
880     }
881 
882     thys->hists[indexnum]->pattern = style;
883 
884     return;
885 }
886 
887 
888 
889 
890 /* @func ajHistSetmultiTitleC *************************************************
891 **
892 ** Store title for the index'th set.
893 **
894 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
895 ** @param [r]  indexnum [ajuint]      Index for the set number.
896 ** @param [r]  txt  [const char *]  Title.
897 ** @return [void]
898 **
899 ** @release 6.2.0
900 ** @@
901 ******************************************************************************/
902 
ajHistSetmultiTitleC(AjPHist thys,ajuint indexnum,const char * txt)903 void ajHistSetmultiTitleC(AjPHist thys, ajuint indexnum, const char *txt)
904 {
905     if(indexnum >= thys->numofdatapoints)
906     {
907 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
908 	      thys->numofdatapoints-1,indexnum);
909 
910 	return;
911     }
912 
913     ajStrAssignC(&thys->hists[indexnum]->title,txt);
914 
915     return;
916 }
917 
918 
919 
920 
921 /* @func ajHistSetmultiTitleS *************************************************
922 **
923 ** Set ptr for title for index'th set..
924 **
925 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
926 ** @param [r] indexnum [ajuint]       Index for the set number.
927 ** @param [r] str [const AjPStr]    Title.
928 ** @return [void]
929 **
930 ** @release 6.2.0
931 ** @@
932 ******************************************************************************/
933 
ajHistSetmultiTitleS(AjPHist thys,ajuint indexnum,const AjPStr str)934 void ajHistSetmultiTitleS(AjPHist thys, ajuint indexnum, const AjPStr str)
935 {
936     if(indexnum >= thys->numofdatapoints)
937     {
938 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
939 	      thys->numofdatapoints-1,indexnum);
940 	return;
941     }
942 
943     ajStrAssignS(&thys->hists[indexnum]->title, str);
944 
945     return;
946 }
947 
948 
949 
950 
951 /* @func ajHistSetmultiXlabelC ************************************************
952 **
953 ** Store X axis title for the index'th set.
954 **
955 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
956 ** @param [r] indexnum [ajuint]       Index for the set number.
957 ** @param [r] txt [const char *]    x Title.
958 ** @return [void]
959 **
960 ** @release 6.2.0
961 ** @@
962 ******************************************************************************/
963 
ajHistSetmultiXlabelC(AjPHist thys,ajuint indexnum,const char * txt)964 void ajHistSetmultiXlabelC(AjPHist thys, ajuint indexnum, const char *txt)
965 {
966     if(indexnum >= thys->numofdatapoints)
967     {
968 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
969 	      thys->numofdatapoints-1,indexnum);
970 
971 	return;
972     }
973 
974     ajStrAssignC(&thys->hists[indexnum]->xaxis,txt);
975 
976     return;
977 }
978 
979 
980 
981 
982 /* @func ajHistSetmultiXlabelS ************************************************
983 **
984 ** Set ptr for X axis title for index'th set..
985 **
986 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
987 ** @param [r] indexnum [ajuint]       Index for the set number.
988 ** @param [r] str [const AjPStr]    x Title.
989 ** @return [void]
990 **
991 ** @release 6.2.0
992 ** @@
993 ******************************************************************************/
994 
ajHistSetmultiXlabelS(AjPHist thys,ajuint indexnum,const AjPStr str)995 void ajHistSetmultiXlabelS(AjPHist thys, ajuint indexnum, const AjPStr str)
996 {
997     if(indexnum >= thys->numofdatapoints)
998     {
999 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
1000 	      thys->numofdatapoints-1,indexnum);
1001 	return;
1002     }
1003 
1004     ajStrAssignS(&thys->hists[indexnum]->xaxis, str);
1005 
1006     return;
1007 }
1008 
1009 
1010 
1011 
1012 /* @func ajHistSetmultiYlabelC ************************************************
1013 **
1014 ** Store Y axis title for the index'th set.
1015 **
1016 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
1017 ** @param [r] indexnum [ajuint]       Index for the set number.
1018 ** @param [r] txt [const char *]    Y Title.
1019 ** @return [void]
1020 **
1021 ** @release 6.2.0
1022 ** @@
1023 ******************************************************************************/
1024 
ajHistSetmultiYlabelC(AjPHist thys,ajuint indexnum,const char * txt)1025 void ajHistSetmultiYlabelC(AjPHist thys, ajuint indexnum, const char *txt)
1026 {
1027     if(indexnum >= thys->numofdatapoints)
1028     {
1029 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
1030 	      thys->numofdatapoints-1,indexnum);
1031 	return;
1032     }
1033 
1034     ajStrAssignC(&thys->hists[indexnum]->yaxis,txt);
1035 
1036     return;
1037 }
1038 
1039 
1040 
1041 
1042 /* @func ajHistSetmultiYlabelS ************************************************
1043 **
1044 ** Set ptr for Y axis title for index'th set..
1045 **
1046 ** @param [u] thys [AjPHist]   Histogram to have ptr set.
1047 ** @param [r] indexnum [ajuint]       Index for the set number.
1048 ** @param [r] str [const AjPStr]    Y Title.
1049 ** @return [void]
1050 **
1051 ** @release 6.2.0
1052 ** @@
1053 ******************************************************************************/
1054 
ajHistSetmultiYlabelS(AjPHist thys,ajuint indexnum,const AjPStr str)1055 void ajHistSetmultiYlabelS(AjPHist thys, ajuint indexnum, const AjPStr str)
1056 {
1057     if(indexnum >= thys->numofdatapoints)
1058     {
1059 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
1060 	      thys->numofdatapoints-1,indexnum);
1061 	return;
1062     }
1063 
1064     ajStrAssignS(&thys->hists[indexnum]->yaxis, str);
1065 
1066     return;
1067 }
1068 
1069 
1070 
1071 
1072 /* @section Histogram data management *****************************************
1073 **
1074 ** Functions to manage the data values associated with a histogram object
1075 **
1076 ** @fdata [AjPHist]
1077 ** @fcategory modify
1078 **
1079 ** @nam3rule Data
1080 ** @nam4rule Add Add data values to be owned by the histogram object
1081 ** @nam4rule Copy Copy data values to histogram object
1082 ** @nam4rule Set Set internals of one plot
1083 **
1084 ** @argrule * thys [AjPHist] Histogram object
1085 ** @argrule Data indexnum [ajuint] number within multiple graph.
1086 ** @argrule Add data [PLFLT*] graph to be added.
1087 ** @argrule Copy srcdata [PLFLT const*] graph to be added.
1088 **
1089 ** @valrule * [void]
1090 **
1091 ******************************************************************************/
1092 
1093 
1094 
1095 
1096 /* @func ajHistDataAdd ********************************************************
1097 **
1098 ** Set internal pointer to data for a set of data points for one set.
1099 **
1100 ** @param [u] thys [AjPHist] Histogram to have ptr set.
1101 ** @param [r] indexnum [ajuint] Index for the set number.
1102 ** @param [u] data  [PLFLT*]  Data values to be owned by the histogram object
1103 ** @return [void]
1104 **
1105 ** @release 6.2.0
1106 ** @@
1107 ******************************************************************************/
1108 
ajHistDataAdd(AjPHist thys,ajuint indexnum,PLFLT * data)1109 void ajHistDataAdd(AjPHist thys, ajuint indexnum, PLFLT *data)
1110 {
1111     if(indexnum >= thys->numofdatapoints)
1112     {
1113 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
1114 	      thys->numofdatapoints-1,indexnum);
1115 
1116 	return;
1117     }
1118 
1119     if(!thys->hists[indexnum]->data)
1120 	thys->numofsets++;
1121 
1122     thys->hists[indexnum]->data = data;
1123 
1124     return;
1125 }
1126 
1127 
1128 
1129 
1130 /* @func ajHistDataCopy *******************************************************
1131 **
1132 ** Copy data from data array to histogram for one set.
1133 **
1134 ** @param [u] thys [AjPHist] Histogram to have ptr set.
1135 ** @param [r] indexnum [ajuint] Index for the set number.
1136 ** @param [r] srcdata  [PLFLT const*]  Data to be copied
1137 ** @return [void]
1138 **
1139 ** @release 6.2.0
1140 ** @@
1141 ******************************************************************************/
1142 
ajHistDataCopy(AjPHist thys,ajuint indexnum,PLFLT const * srcdata)1143 void ajHistDataCopy(AjPHist thys, ajuint indexnum, PLFLT const *srcdata)
1144 {
1145     ajuint i;
1146 
1147     if(indexnum >= thys->numofdatapoints)
1148     {
1149 	ajErr("Histograms can only be allocated from 0 to %d. NOT %u",
1150 	      thys->numofdatapoints-1,indexnum);
1151 
1152 	return;
1153     }
1154 
1155     thys->hists[indexnum]->data = AJALLOC(thys->numofdatapoints*sizeof(PLFLT));
1156 
1157     for(i=0; i < thys->numofdatapoints; i++)
1158 	thys->hists[indexnum]->data[i] = srcdata[i];
1159 
1160     thys->hists[indexnum]->deletedata = AJTRUE;
1161     thys->numofsets++;
1162 
1163     return;
1164 }
1165 
1166 
1167 
1168 
1169 #ifdef AJ_COMPILE_DEPRECATED_BOOK
1170 #endif
1171 
1172 
1173 
1174 
1175 #ifdef AJ_COMPILE_DEPRECATED
1176 /* @obsolete ajHistClose
1177 ** @rename ajHistogramClose
1178 */
ajHistClose(void)1179 __deprecated void ajHistClose(void)
1180 {
1181     ajHistogramClose();
1182 
1183     return;
1184 }
1185 
1186 
1187 
1188 
1189 /* @obsolete ajHistSetMark
1190 ** @rename ajHistogramSetMark
1191 */
ajHistSetMark(ajint mark)1192 __deprecated void ajHistSetMark(ajint mark)
1193 {
1194     ajHistogramSetMark(mark);
1195     return;
1196 }
1197 
1198 
1199 
1200 
1201 /* @obsolete ajHistDelete
1202 ** @rename ajHistDel
1203 */
ajHistDelete(AjPHist * phist)1204 __deprecated void ajHistDelete(AjPHist* phist)
1205 {
1206     ajHistDel(phist);
1207     return;
1208 }
1209 
1210 
1211 
1212 
1213 /* @obsolete ajHistSetBlackandWhite
1214 ** @rename ajHistSetMono
1215 */
ajHistSetBlackandWhite(AjPHist thys,AjBool set)1216 __deprecated void ajHistSetBlackandWhite(AjPHist thys, AjBool set)
1217 {
1218     ajHistSetMono(thys, set);
1219 }
1220 
1221 
1222 
1223 
1224 /* @obsolete ajHistSetYAxisRightC
1225 ** @rename ajHistSetYlabelC
1226 */
ajHistSetYAxisRightC(AjPHist thys,const char * strng)1227 __deprecated void ajHistSetYAxisRightC(AjPHist thys, const char* strng)
1228 {
1229     ajHistSetRlabelC(thys, strng);
1230     return;
1231 }
1232 
1233 
1234 
1235 
1236 /* @obsolete ajHistSetXAxisC
1237 ** @rename ajHistSetXlabelC
1238 */
ajHistSetXAxisC(AjPHist thys,const char * strng)1239 __deprecated void ajHistSetXAxisC(AjPHist thys, const char* strng)
1240 {
1241     ajHistSetXlabelC(thys, strng);
1242     return;
1243 }
1244 
1245 
1246 
1247 
1248 /* @obsolete ajHistSetYAxisLeftC
1249 ** @rename ajHistSetYlabelC
1250 */
ajHistSetYAxisLeftC(AjPHist thys,const char * strng)1251 __deprecated void ajHistSetYAxisLeftC(AjPHist thys, const char* strng)
1252 {
1253     ajHistSetYlabelC(thys, strng);
1254     return;
1255 }
1256 
1257 
1258 
1259 
1260 /* @obsolete ajHistSetColour
1261 ** @rename ajHistSetmltiColour
1262 */
ajHistSetColour(AjPHist thys,ajuint indexnum,ajint colour)1263 __deprecated void ajHistSetColour(AjPHist thys, ajuint indexnum, ajint colour)
1264 {
1265     ajHistSetmultiColour(thys, indexnum, colour);
1266     return;
1267 }
1268 
1269 
1270 
1271 
1272 /* @obsolete ajHistSetPattern
1273 ** @rename ajHistSetmultiPattern
1274 */
ajHistSetPattern(AjPHist thys,ajuint indexnum,ajint style)1275 __deprecated void ajHistSetPattern(AjPHist thys, ajuint indexnum, ajint style)
1276 {
1277     ajHistSetmultiPattern(thys, indexnum, style);
1278     return;
1279 }
1280 
1281 
1282 
1283 
1284 /* @obsolete ajHistSetMultiTitleC
1285 ** @rename ajHistSetmultiTitleC
1286 */
ajHistSetMultiTitleC(AjPHist hist,ajint indexnum,const char * title)1287 __deprecated void ajHistSetMultiTitleC(AjPHist hist, ajint indexnum,
1288                                       const char* title)
1289 {
1290     ajHistSetmultiTitleC(hist, indexnum, title);
1291     return;
1292 }
1293 
1294 
1295 
1296 
1297 /* @obsolete ajHistSetMultiTitle
1298 ** @rename ajHistSetmultiTitleS
1299 */
ajHistSetMultiTitle(AjPHist hist,ajint indexnum,const AjPStr title)1300 __deprecated void ajHistSetMultiTitle(AjPHist hist, ajint indexnum,
1301                                       const AjPStr title)
1302 {
1303     ajHistSetmultiTitleS(hist, indexnum, title);
1304     return;
1305 }
1306 
1307 
1308 
1309 
1310 /* @obsolete ajHistSetMultiXTitleC
1311 ** @rename ajHistSetmultiXlabelC
1312 */
ajHistSetMultiXTitleC(AjPHist hist,ajint indexnum,const char * title)1313 __deprecated void ajHistSetMultiXTitleC(AjPHist hist, ajint indexnum,
1314                                       const char* title)
1315 {
1316     ajHistSetmultiXlabelC(hist, indexnum, title);
1317     return;
1318 }
1319 
1320 
1321 
1322 
1323 /* @obsolete ajHistSetMultiXTitle
1324 ** @rename ajHistSetmultiXlabelS
1325 */
ajHistSetMultiXTitle(AjPHist hist,ajint indexnum,const AjPStr title)1326 __deprecated void ajHistSetMultiXTitle(AjPHist hist, ajint indexnum,
1327                                       const AjPStr title)
1328 {
1329     ajHistSetmultiXlabelS(hist, indexnum, title);
1330     return;
1331 }
1332 
1333 
1334 
1335 
1336 /* @obsolete ajHistSetMultiYTitleC
1337 ** @rename ajHistSetmultiYlabelC
1338 */
ajHistSetMultiYTitleC(AjPHist hist,ajint indexnum,const char * title)1339 __deprecated void ajHistSetMultiYTitleC(AjPHist hist, ajint indexnum,
1340                                       const char* title)
1341 {
1342     ajHistSetmultiYlabelC(hist, indexnum, title);
1343     return;
1344 }
1345 
1346 
1347 
1348 
1349 /* @obsolete ajHistSetMultiYTitle
1350 ** @rename ajHistSetmultiYlabelS
1351 */
ajHistSetMultiYTitle(AjPHist hist,ajint indexnum,const AjPStr title)1352 __deprecated void ajHistSetMultiYTitle(AjPHist hist, ajint indexnum,
1353                                       const AjPStr title)
1354 {
1355     ajHistSetmultiYlabelS(hist, indexnum, title);
1356     return;
1357 }
1358 
1359 
1360 
1361 
1362 /* @obsolete ajHistSetPtrToData
1363 ** @rename ajHistDataAdd
1364 */
ajHistSetPtrToData(AjPHist thys,ajint indexnum,PLFLT * data)1365 __deprecated void ajHistSetPtrToData(AjPHist thys, ajint indexnum, PLFLT *data)
1366 {
1367     ajHistDataAdd(thys, indexnum, data);
1368     return;
1369 }
1370 
1371 
1372 
1373 
1374 /* @obsolete ajHistCopyData
1375 ** @rename ajHistDataCopy
1376 */
ajHistCopyData(AjPHist thys,ajuint indexnum,const PLFLT * data)1377 __deprecated void ajHistCopyData(AjPHist thys, ajuint indexnum,
1378                                  const PLFLT *data)
1379 {
1380     ajHistDataCopy(thys, indexnum, data);
1381     return;
1382 }
1383 #endif
1384