2
* Author: Simon Kelley (srk@sanger.ac.uk)
3
* Copyright (C) J Thierry-Mieg and R Durbin, 1991
4
* -------------------------------------------------------------------
5
* Acedb is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
* or see the on-line version at http://www.gnu.org/copyleft/gpl.txt
19
* -------------------------------------------------------------------
20
* This file is part of the ACEDB genome database package, written by
21
* Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and
22
* Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr
24
* Description: assorted utility functions for extracting data from
42
* Last edited: Mar 28 15:58 2007 (edgrif)
43
*-------------------------------------------------------------------
46
/* $Id: gmapconvert.c,v 1.39 2007/03/29 15:08:17 edgrif Exp $ */
54
static BOOL tagTypesMatch(KEY tag_1, KEY tag_2) ;
58
KEY gMapCacheKey(KEY map, char *suffix)
61
OBJ obj = bsCreate(map);
65
{ noCache = bsFindTag(obj, str2tag("No_cache"));
70
strcpy(buf, name(map));
73
if (lexword2key(buf, &ret, _VgMap))
79
void gMapCacheStore(KEY map, char *suffix, Array a, char *format)
82
strcpy(buf, name(map));
85
lexaddkey(buf, &key, _VgMap);
86
arrayStore(key, a, format);
89
void gMapCacheKill(KEY map)
94
strcpy(buf, "FIND gMap ");
95
strcat(buf, name(map));
98
for (i = 0 ; i < keySetMax(kset); i++)
99
arrayKill(keySet(kset, i));
102
BOOL gMapIsCache(KEY map)
104
KEY poscache = gMapCacheKey(map, "main");
109
if (iskey(poscache) != 2)
116
BOOL gMapNeighbours(MAPCONTROL map, KEYSET *keyset, KEY key)
120
*keyset = keySetReCreate(*keyset);
123
if (!a) return FALSE;
125
for(i=0, j=0 ; i<keySetMax(a) ; i++)
126
if (class(keySet(a,i)))
127
keySet(*keyset,j++) = keySet(a,i) ;
130
return keySetMax(*keyset) != 0;
135
static BOOL gMapContainment(int level, MAPCONTROL map, KEYSET *ks,
136
KEY key, KEY senseTag)
137
/* senseTag is _Positive or _Negative */
138
{ KEY mapk = map->key;
141
int typeOf1, typeOf2, i;
142
Array loci = arrayCreate(50, BSunit);
144
/* get info in object */
145
if ((obj = bsCreate(key)))
146
{ if (bsGetKey(obj, str2tag("More_data"), &k))
149
messerror("Have chased 100 levels of More_data and got to %s, "
150
"is there a loop?", name(k));
152
gMapContainment(level+1, map, ks, k, senseTag);
154
while (bsGetKey(obj, _bsDown, &k));
158
if (bsFindTag(obj, senseTag) && bsFlatten(obj, 2, loci))
159
for (i = 1; i<arrayMax(loci); i+= 2)
160
{ k = arr(loci, i, BSunit).k;
162
keySet(*ks, keySetMax(*ks)) = k;
165
/* get info in Pos_neg_data */
166
if (bsGetKey(obj, str2tag("Pos_neg_data"), &k))
170
if (!bsFindTag(comp, senseTag))
175
if (bsFindTag(comp, str2tag("Item_1")) &&
176
bsGetKeyTags(comp, _bsRight, &mo1) &&
177
bsGetKey(comp, _bsRight, &mo1))
178
typeOf1 = gMapGetMapObject(mo1, mapk, 0, 20, 0, 0, 0, 0);
179
if (bsFindTag(comp, str2tag("Item_2")) &&
180
bsGetKeyTags(comp, _bsRight, &mo2) &&
181
bsGetKey(comp, _bsRight, &mo2))
182
typeOf2 = gMapGetMapObject(mo2, mapk, 0, 20, 0, 0, 0, 0);
185
if (((typeOf1&FLAG_ANY_INTERVAL) && (typeOf2&FLAG_ANY_LOCUS)) ||
186
((typeOf2&FLAG_ANY_INTERVAL) && (typeOf1&FLAG_ANY_LOCUS)))
189
keySet(*ks, keySetMax(*ks)) = mo2;
192
keySet(*ks, keySetMax(*ks)) = mo1;
195
while (bsGetKey(obj, _bsDown, &k));
201
return keySetMax(*ks) != 0;
204
BOOL gMapPositive(MAPCONTROL map, KEYSET *ks, KEY key)
205
{ *ks = keySetReCreate(*ks);
206
return gMapContainment(0, map, ks, key, str2tag("Positive"));
209
BOOL gMapNegative(MAPCONTROL map, KEYSET *ks, KEY key)
210
{ *ks = keySetReCreate(*ks);
211
return gMapContainment(0, map, ks, key, str2tag("Negative"));
214
BOOL gMapMultiPt(MAPCONTROL map, KEYSET *ks, KEY key)
219
*ks = keySetReCreate(*ks) ;
220
if ((obj = bsCreate (key)))
221
{ if (bsGetKey (obj, _Multi_point, &k)) do
222
keySet (*ks, keySetMax(*ks)) = k ;
223
while (bsGetKey (obj, _bsDown, &k)) ;
228
return keySetMax(*ks) != 0;
231
BOOL gMap2Pt(MAPCONTROL map, KEYSET *ks, KEY key)
236
*ks = keySetReCreate(*ks) ;
237
if ((obj = bsCreate (key)))
238
{ if (bsGetKey (obj, _2_point, &k)) do
239
keySet (*ks, keySetMax(*ks)) = k ;
240
while (bsGetKey (obj, _bsDown, &k)) ;
245
return keySetMax(*ks) != 0;
248
static void addMultiData (OBJ obj, Array counts, Array loci)
254
mark = bsMark (obj, mark) ;
258
if (!bsGetKeyTags(obj, _bsRight, &tag) ||
259
!bsGetKey (obj, _bsRight, &locus))
260
{ messerror ("No terminating locus in multi results") ;
263
if (i >= arrayMax(loci))
264
array (loci, i, KEY) = locus ;
265
else if (locus != array(loci,i,KEY))
266
{ messerror ("Mismatching locus %s in multi results",
270
if (!bsGetData (obj, _bsRight, _Int, &count))
272
if (i >= arrayMax(counts))
273
array(counts,i,int) = count ;
275
array(counts,i,int) += count ;
283
BOOL gMapGetMultiPtData(MAPCONTROL map,
287
{ Array counts, loci;
293
if (!(obj = bsCreate (multi)))
296
counts = arrayHandleCreate(20, int, handle);
297
loci = arrayHandleCreate(20, KEY, handle);
299
if (bsFindTag (obj, _Combined))
300
addMultiData (obj, counts, loci) ;
302
{ if (bsFindTag (obj, _A_non_B))
303
addMultiData (obj, counts, loci) ;
304
if (bsFindTag (obj, _B_non_A))
305
addMultiData (obj, counts, loci) ;
310
if (arrayMax(loci) <=2 && iskey(multi) > 1) /* i.e. not just a name */
312
arrayDestroy(counts);
317
min = 1000000 ; max = -1000000 ;
318
for (i = 0 ; i < arrayMax(loci) ; ++i)
319
if (getPos (map, arr(loci,i,KEY), &y))
320
{ if (y < min) min = y ;
321
if (y > max) max = y ;
325
{ arrayDestroy(counts);
330
data = (MULTIPTDATA)handleAlloc(0, handle, sizeof(struct MultiPtData));
331
data->counts = counts;
341
BOOL gMapGet2PtData(MAPCONTROL map, KEY key, STORE_HANDLE handle, TWOPTDATA *ret)
343
BOOL result = FALSE ;
345
KEY type_tag_1, type_tag_2 ;
357
/* Need two matching tags to give the two points. */
358
if (!bsGetKeyTags(obj, str2tag("Point_1"), &type_tag_1) || !bsGetKeyTags(obj, str2tag("Point_2"), &type_tag_2)
359
|| !tagTypesMatch(type_tag_1, type_tag_2))
365
bsGoto(obj, 0) ; /* Pop back up to root for later locations... */
368
data = (TWOPTDATA)handleAlloc(0, handle, sizeof(struct TwoPtData));
370
/* Now get the position data. */
371
if ((!bsGetKey(obj, type_tag_1, &data->loc1) || !bsGetKey(obj, type_tag_1, &data->loc2))
372
|| (!getPos(map, data->loc1, &data->y1) || !getPos(map, data->loc2, &data->y2)))
380
if (!bsGetKeyTags(obj, _Calculation, &type))
383
if (!bsGetData(obj, _Distance, _Float, &data->distance))
385
if (!bsGetData(obj, _Error, _Float, &data->error))
391
for (i=0; bsGetData(obj, _bsRight, _Int, p) && i < 4 ; p++, i++) ;
397
if ((type == _Full || /* WT X Y XY */
398
type == _Backcross || /* WT X Y XY */
399
type == _Sex_full) && /* WT X Y XY */
403
if ((type == _Recs_all || /* X Y ALL */
404
type == _Tetrad) && /* PD NPD TT */
408
if ((type == _One_recombinant || /* WT X */
409
type == _Selected || /* X XY */
410
type == _One_all || /* X ALL */
411
type == _One_let || /* X ALL */
412
type == _Tested || /* H X */
413
type == _Selected_trans || /* X XY */
414
type == _Back_one || /* WT X */
415
type == _Sex_one || /* WT X */
416
type == _Sex_cis || /* X ALL */
417
type == _Dom_one || /* WT nonWT */
418
type == _Dom_selected || /* WT X */
419
type == _Dom_semi || /* XD ALL */
420
type == _Dom_let || /* WT ALL */
421
type == _Direct || /* R T */
422
type == _Complex_mixed || /* X ALL */
423
type == _Lethal_tested || /* N WT */
424
type == _Centromere_segregation) && /* 1st 2nd */
429
{ messerror("Wrong number of data (%d) for 2 point calculation %s",
444
/* This is a utility function which returns the map position of any
445
locus-like object on the map. As side effects, it is responsible
446
for setting the values of map->min, map->max etc and look->orderedLoci,
447
which is a keyset of all the loci which have a Positive_clone entry.
448
It may be called with key zero to get its side-effects */
450
BOOL getPos (MAPCONTROL map, KEY key, float *y)
452
KEY chrom, locus, clone;
453
KEY posCache, orderedCache;
455
float xmin = -1, xmax = 1; /* minimum sensible range */
458
GeneticMap look = (GeneticMap)map->look;
459
Array cacheArray = 0, orderedArray = 0, loci = 0;
468
Associator a = look->posAss;
473
look->posAss = a = assHandleCreate(map->handle);
474
look->orderedLoci = arrayHandleCreate(200, KEY, map->handle);
475
if ((posCache = gMapCacheKey(map->key, "pos")) &&
476
(cacheArray = arrayGet(posCache, struct cacheEntry, "kf")))
479
for (i = 2; i <arrayMax(cacheArray); i++)
481
u.f = arr(cacheArray, i, struct cacheEntry).x;
482
assInsert(a, assVoid(arr(cacheArray, i,struct cacheEntry).key),
485
xmin = arr(cacheArray, 0, struct cacheEntry).x;
486
xmax = arr(cacheArray, 1, struct cacheEntry).x;
488
if ((orderedCache = gMapCacheKey(map->key, "ordered")) &&
489
(orderedArray = arrayGet(orderedCache, KEY, "k")))
490
for (i= 0; i <arrayMax(orderedArray); i++)
491
keySet(look->orderedLoci, i) = arr(orderedArray, i, KEY);
495
loci = gMapMapObjects(map->key);
496
cacheArray = arrayCreate(200, struct cacheEntry);
497
j = 2; /* zero and one for min and max */
498
for (Locus = 0, i = 0; i <arrayMax(loci); bsDestroy (Locus) , i++)
499
{ locus = arr(loci, i, KEYPAIR).obj;
500
chrom = arr(loci, i, KEYPAIR).map;
501
flags = gMapGetMapObject(locus, map->key, chrom,
502
20, &x, &dx, &Locus, 0);
505
if (flags & FLAG_ANY_LOCUS)
506
{ /* put info into cacheArray */
507
array(cacheArray, j, struct cacheEntry).x = x;
508
array(cacheArray, j, struct cacheEntry).key = locus;
510
/* This is very bizarre, we need need polymorphic assocs ASAP */
512
assInsert(a, assVoid(locus), u.vs);
525
if (bsGetKey (Locus,_Positive_clone,&clone))
526
keySetInsert(look->orderedLoci, locus);
529
array(cacheArray, 0, struct cacheEntry).x = xmin;
530
array(cacheArray, 1, struct cacheEntry).x = xmax;
531
orderedArray = arrayCopy(look->orderedLoci);
533
gMapCacheStore(map->key, "pos", cacheArray, "kf");
534
gMapCacheStore(map->key, "ordered", orderedArray, "k");
538
arrayDestroy(cacheArray);
539
arrayDestroy(orderedArray);
540
/* If we can't find display tags in this map,
541
we look in any it inherits from */
545
while ((Chrom = bsCreate(chrom)))
546
{ if (bsGetData(Chrom, _Extent, _Float, &map->min))
547
{ bsGetData(Chrom, _bsRight, _Float, &map->max);
550
if (bsGetKey(Chrom, _From_map, &chrom))
558
map->centre = (map->max + map->min)/2.0; /* default values */
559
width = (map->max - map->min)/3.0;
562
while ((Chrom = bsCreate(chrom)))
563
{ if (bsFindTag(Chrom, _Flipped))
565
if (bsGetData(Chrom, _Centre, _Float, &map->centre))
566
{ bsGetData(Chrom, _bsRight, _Float, &width);
569
if (bsGetKey(Chrom, _From_map, &chrom))
576
map->mag = (map->control->graphHeight-5) / width;
578
map->mag = - map->mag;
582
if (key && assFind(look->posAss, assVoid(key), &u.vs))
592
/* override the position value for a Locus temporarily */
594
void setTestPos (MAPCONTROL map, KEY key, float pos)
596
GeneticMap look = (GeneticMap)map->look;
601
assRemove(look->posAss, assVoid(key));
604
assInsert(look->posAss, assVoid(key), u.vs);
608
/* This is a fundamental routine. It takes the key of
609
some object which has a Map tag followed by ?Map #Map_position
610
and the key of the map on which the postition is required.
611
It returns zero if something's missing,
612
or FLAG_ANY_INTERVAL if it's an interval or FLAG_ANY_LOCUS if it's
614
If the object doesn't have a position on the given map, but the map
615
has a From_map tag, it searches recursively in the inherited from maps.
616
For an interval the centre goes into *xret and half the length
617
into *dxret. For a Locus the position goes into *xret and the
619
dxret and/or xret may be zero without segfaulting.
620
The map key is needed to resolve the positions the objects which
621
appear on more than one map. If objp is non-zero, the bsObject
622
for the object is not closed, but returned (a bsGoto(0) is performed on it).
623
ind is the limit on how far one should recurse to resolve maps_with
625
If count is non-null, multiple positions may be returned. In this
626
case *count on calling gives the maximum number of positions to
627
be returned (must be >=1) and xret and dxret must be suitably sized arrays.
628
On return, *count if the actual number of positions found.
630
Note that the object need not be mapped directly on the map given as a
631
parameter, it may be mapped on another map which the parameter map inherits
632
from, or another map which it includes. See gMapMapObjects for details.
638
(KEY key, KEY map, KEY hint, int ind,
639
float *xret, float *dxret, OBJ *objp, int *count)
647
KEY _Multi_Ends = str2tag("Multi_Ends");
648
float mapOffset, mapFactor;
656
{ messerror("Chased too many mapable objects trying to "
657
"resolve \"maps with\". Is there a cycle involving %s?",
664
if (!key || !(item = bsCreate(key)))
670
/* now find out what's what in the mapping dept. If we have a hint, and it's
671
the same as the map, that's easy. A hint != map, means the locus is on an
672
inhertits-from map, or a sub-map. we find which, and determine the
673
transformation. If there is no hint, we need to first find the actual map
674
that the locus is on, using the same priority rules as gMapMapObjects
675
(IMPORTANT), then proceed as above. */
679
/* find the map which includes the hint, or is the hint */
681
while (hint != map &&
682
(Map = bsCreate(map)) &&
683
!bsFindKey(Map, str2tag("Includes"), hint))
684
/* cannot find mapping for this map, it may inherit from another */
685
{ if (!bsGetKey(Map, str2tag("From_map"), &map))
697
if (!bsFindKey(item, str2tag("Map"), hint))
706
{ if (bsFindKey(item, str2tag("Map"), map))
707
/* it's on the map we want, easy */
710
/* it's not, see if it's on a sub-map */
711
{ OBJ Map = bsCreate(map);
713
if (bsGetKey(Map, str2tag("Includes"), &submap))
715
{ if (bsFindKey(item, str2tag("Map"), submap))
718
while (!hint && bsGetKey(Map, _bsDown, &submap));
722
if (!hint) /* not found it yet, try inherits from maps. */
723
{ OBJ Map = bsCreate(map);
724
if (!Map || !bsGetKey(Map, str2tag("From_map"), &map))
725
/* No more, failed to find it. */
736
/* Ok , we now have a sequence map, hint, item, if hint != map,
737
we can calculate the scaling factor and offset */
744
{ float leftEnd, rightEnd, extentLeft, extentRight;
745
OBJ Submap = bsCreate(hint);
746
if (!bsFindKey(Submap, str2tag("Map"), map) ||
747
!bsPushObj(Submap) ||
748
!bsGetData(Submap, _Left, _Float, &leftEnd) ||
749
!bsGetData(Submap, _Right, _Float, &rightEnd))
750
messerror("Failed to find map position for submap %s in map %s",
751
name(hint), name(map));
752
if (leftEnd == rightEnd)
753
messerror("Submap %s has zero length on map %s - cannot scale.",
754
name(hint), name(map));
756
if (!bsGetData(Submap, str2tag("Extent"), _Float, &extentLeft) ||
757
!bsGetData(Submap, _bsRight, _Float, &extentRight))
758
messerror("Map %s is a submap of map %s, but does not have an extent",
759
name(hint), name(map));
763
if (leftEnd > rightEnd)
764
{ float tmp = rightEnd;
770
mapFactor = (extentRight - extentLeft) / (leftEnd - rightEnd);
775
if (!bsPushObj(item)) /* to #Map_position */
782
if (bsGetData(item, _Multi_Position, _Float, &x1))
785
{ mark = bsMark(item, mark);
786
bsPushObj(item); /* To #Map_Error */
787
if (!bsGetData(item, _Error, _Float, &x2))
788
x2 = 0.0; /* default if no error */
791
*(xret++) = mapOffset + mapFactor*x1;
793
*(dxret++) = mapFactor*x2;
798
while (ourCount<max && bsGetData(item, _bsDown, _Float, &x1));
812
return FLAG_ANY_LOCUS;
815
if (bsGetData(item, _Multi_Ends, _Float, &x1))
818
{ mark = bsMark(item, mark);
819
if (!bsGetData(item, _bsRight, _Float, &x2))
820
continue; /* lines with no right */
822
{ float dx = (x2 - x1)/2.0;
824
*(xret++) = mapOffset + mapFactor * (x1 + dx);
826
*(dxret++) = mapFactor*dx;
829
{ float dx = (x1 - x2)/2.0;
831
*(xret++) = mapOffset + mapFactor * (x2 + dx);
833
*(dxret++) = mapFactor*dx;
839
while (ourCount<max && bsGetData(item, _bsDown, _Float, &x1));
853
return FLAG_ANY_INTERVAL;
856
if (bsGetData(item, _Position, _Float, &x1)) /* Locus-like */
857
{ bsPushObj(item); /* to #Map_Error */
858
if (!bsGetData(item, _Error, _Float, &x2))
859
x2 = 0.0; /* default if no error */
867
*xret = mapOffset + mapFactor*x1;
869
*dxret = mapFactor*x2;
872
return FLAG_ANY_LOCUS;
875
if (bsGetData(item , _Left, _Float, &x1) && /* Interval-like */
876
bsGetData(item, _Right, _Float, &x2))
885
{ float dx = (x2 - x1)/2.0;
887
*xret = mapOffset + mapFactor*(x1 + dx);
889
*dxret = mapFactor*dx;
892
{ float dx = (x1 - x2)/2.0;
894
*xret = mapOffset + mapFactor * (x2 + dx);
896
*dxret = mapFactor * dx;
901
return FLAG_ANY_INTERVAL;
905
if (bsFindTag(item, str2tag("With")) &&
906
bsGetKeyTags(item, _bsRight, &key) &&
907
bsGetKey(item, _bsRight, &key))
909
flags = gMapGetMapObject(key, map, 0, ind-1, xret, dxret, 0, count);
911
bsPushObj(item) && bsFindTag(item, str2tag("Relative")) &&
913
{ if (bsGetData(item, _Position, _Float, &offset))
915
for (i= 0; i < (count ? *count : 1); i++)
917
flags = FLAG_ANY_LOCUS ;
919
else if (bsGetData(item, _Left, _Float, &x1) &&
920
bsGetData(item, _Right, _Float, &x2))
923
{ int tmp = x1 ; x1 = x2 ; x2 = tmp ; }
924
dx = (x1 + x2) / 2.0 ;
926
for (i= 0; i < (count ? *count : 1); i++)
928
dx = (x2 - x1) / 2.0 ;
930
for (i= 0; i < (count ? *count : 1); i++)
932
flags = FLAG_ANY_INTERVAL ;
935
flags = 0 ; /* require Position or Ends */
949
bsDestroy(item); /* mieg */
953
/**********************************/
956
/* This generates an array of all the objects on a map. It handles included
957
maps (one level only) and inherits_from maps. The output is a set of
958
(mapped object, map) pairs. The map is the map which directly contains the
959
object, to be given as a hint to gMapGetMapObject.
960
Note that the same object may not be mapped in more than one map, extra
961
mappings get ignored. The priority for this ensures that inheritance
962
works OK, and that objects mapped on a map and it's sub-map get the sub-map
967
Array gMapMapObjects(KEY chrom)
968
{ Array loci, results;
971
KEY key, locus, submap ;
974
results = arrayCreate(300, KEYPAIR);
975
loci = arrayCreate(200, BSunit);
978
while (i--) /* this is used to prevent infinite recursion in inheritance */
979
lexClearClassStatus(i, CALCULSTATUS);
981
while ((Chrom = bsCreate(chrom)))
983
lexSetStatus(chrom, CALCULSTATUS) ; /* prevent recursions */
985
if (bsFindTag (Chrom,_Contains) && bsFlatten(Chrom, 2, loci))
986
{ for (i = 1; i<arrayMax(loci); i+=2)
987
{ locus = arr(loci, i, BSunit).k;
988
if (locus && !(CALCULSTATUS & lexGetStatus(locus)))
989
{ lexSetStatus(locus, CALCULSTATUS);
990
p = arrayp(results, arrayMax(results), KEYPAIR);
991
p->obj = arr(loci, i, BSunit).k;
996
/* now deal with included maps */
997
/* note that these cannot inherit, and that only on level of
998
inclusion is allowed */
1000
if (bsGetKey(Chrom, str2tag("includes"), &submap))
1002
{ OBJ Subchrom = bsCreate(submap);
1004
bsFindTag (Subchrom,_Contains) && bsFlatten(Subchrom, 2, loci))
1005
{ for (i = 1; i<arrayMax(loci); i+=2)
1006
{ locus = arr(loci, i, BSunit).k;
1007
if (locus && !(CALCULSTATUS & lexGetStatus(locus)))
1008
{ lexSetStatus(locus, CALCULSTATUS);
1009
p = arrayp(results, arrayMax(results), KEYPAIR);
1010
p->obj = arr(loci, i, BSunit).k;
1015
bsDestroy(Subchrom);
1017
while (bsGetKey(Chrom, _bsDown, &submap));
1020
/* now do the same in any inherited maps. */
1022
if (!bsGetKey(Chrom, _From_map, &key) ||
1023
(CALCULSTATUS & lexGetStatus(key)))
1036
KEY gMapKeyOnTag(KEY key, KEY tag)
1044
if (!(obj = bsCreate(key)))
1047
ok = bsGetKey(obj, tag, &ret);
1056
/****************** giface hook *****************/
1058
void gMapDrawGIF (ACEIN command_in, ACEOUT result_out)
1062
BOOL haveBounds = FALSE ;
1063
BOOL isWhole = FALSE ;
1064
BOOL isHideHeader = FALSE ;
1065
float x1, x2, hdiff ;
1069
lexaddkey ("View", &key, _VMainClasses) ;
1070
_VView = KEYKEY(key) ;
1072
if (!aceInCheck(command_in, "w"))
1075
word = aceInWord(command_in);
1076
if (!lexword2key(word, &key, _VMap))
1078
aceOutPrint (result_out, "// gif map error: map %s not known\n", word) ;
1083
while (aceInStep (command_in, '-')) /* options */
1084
if ((word = aceInWord(command_in)))
1086
if (strcmp (word, "view") == 0
1087
&& aceInCheck(command_in, "w"))
1089
word = aceInWord(command_in);
1090
if (!lexword2key (word, &view, _VView))
1092
aceOutPrint (result_out, "// gif map error: view %s not known\n", word);
1096
else if (strcmp (word, "coords") == 0
1097
&& aceInCheck(command_in, "ff"))
1099
aceInFloat (command_in, &x1);
1100
aceInFloat (command_in, &x2) ;
1101
haveBounds = (x2 != x1) ;
1104
aceOutPrint (result_out, "// gif map error: coords given are the same (%g)\n", x1) ;
1108
else if (strcmp (word, "whole") == 0)
1110
else if (strcmp (word, "hideheader") == 0)
1111
isHideHeader = TRUE ;
1118
if (aceInCheck (command_in, "w"))
1119
/* no more options allowed on command-line */
1122
{ extern BOOL displayReportGif ;
1123
displayReportGif = FALSE ;
1124
display (key, view, "GMAP") ; /* the primary display */
1125
displayReportGif = TRUE ;
1128
map = currentMapControl () ;
1131
{ map->control->hideHeader = TRUE ;
1132
map->control->topMargin = 1 ;
1135
{ map->centre = (x1 + x2) / 2.0 ;
1136
map->mag = (map->control->graphHeight -
1137
map->control->topMargin - 2.0) / (x2 - x1) ;
1140
{ BOOL isNeg = (map->mag < 0) ;
1141
map->centre = (map->max + map->min) / 2.0 ;
1142
map->mag = (map->control->graphHeight -
1143
map->control->topMargin - 2.0) /
1144
(map->max - map->min) ;
1145
if (isNeg) map->mag = -map->mag ;
1148
if (haveBounds || isHideHeader || isWhole)
1151
hdiff = (map->control->graphHeight - 5) / (2.0 * map->mag) ;
1152
x1 = map->centre - hdiff ;
1153
x2 = map->centre + hdiff ;
1154
aceOutPrint (result_out, "// MAP %s %g %g", freeprotect(name(key)), x1, x2) ;
1155
if (view) aceOutPrint (result_out, " view=%s", freeprotect(name(view))) ;
1156
aceOutPrint (result_out, "\n") ;
1161
aceOutPrint (result_out, "// gif map error: usage: MAP map [-view view] [-coords x1 x2]\n") ;
1167
/* Checks to see that two tags match where the relationship between the tags is:
1169
* name(tag_1) = "XXXX_1"
1170
* name(tag_2) = "XXXX_2"
1173
static BOOL tagTypesMatch(KEY tag_1, KEY tag_2)
1175
BOOL result = FALSE ;
1179
prefix = strtok(g_strdup(name(tag_1)), "_") ;
1181
tag = g_strdup_printf("%s_1", prefix) ;
1183
if (strcmp(tag, name(tag_1)) == 0)
1186
tag = g_strdup_printf("%s_2", prefix) ;
1188
if (strcmp(tag, name(tag_2)) == 0)
1199
/*******************************************************************/
1200
/********************** end of file ********************************/