Privacy and Security Notice

tree.cc Source File

tree.cc

Go to the documentation of this file.
00001 
00085 #include <iostream>
00086 #include <math.h>
00087 
00088 
00089 using namespace std;
00090 #include "tree.h"
00091 extern treeregion *rcTreeRegion[2][3][4][4];
00092 extern Det *rcDETRegion[2][3][4];
00093 extern Options opt;
00094 
00095 EUppLow operator++(enum EUppLow &rs, int ) {
00096    return rs = (EUppLow)(rs + 1);
00097 }
00098 ERegion operator++(enum ERegion &rs, int ) {
00099    return rs = (ERegion)(rs + 1);
00100 }
00101 Etype operator++(enum Etype &rs, int ) {
00102    return rs = (Etype)(rs + 1);
00103 }
00104 Edir operator++(enum Edir &rs, int ) {
00105    return rs = (Edir)(rs + 1);
00106 }
00107 /*
00108 Eorientation operator++(enum Eorientation &rs, int ) {
00109    return rs = (Eorientation)(rs + 1);
00110 
00111 }*/
00112 
00113 treenode::treenode(){
00114 
00115 
00116 }
00117 
00118 
00119 treenode::~treenode(){
00120 
00121 }
00122 void treenode::print(){
00123 cout << "("<< minlevel << "," << maxlevel << ")" << endl;
00124 cout << "bits = " << bits << endl;
00125 int i=0;
00126 while(i<TLAYERS){
00127         cout << bit[i] << "," ;
00128         i++;
00129 }
00130 cout << endl;
00131 cout << "xref = " << xref << endl;
00132 }
00133 
00134 shorttree::shorttree(){
00135 
00136 }
00137 
00138 shorttree::~shorttree(){
00139 
00140 }
00141 void shorttree::print(){
00142         //cout << "("<< minlevel << "," << maxlevel << ")" << endl;
00143         cout << "bits = " << bits << endl;
00144         int i=0;
00145         while(i<TLAYERS){
00146                 cout << bit[i] << "," ;
00147                 i++;
00148         }
00149         cout << endl;
00150         //cout << "xref = " << xref << endl;
00151 }
00152 
00153 nodenode::nodenode(){
00154 
00155 }
00156 
00157 nodenode::~nodenode(){
00158 
00159 }
00160 
00161 shortnode::shortnode(){
00162 
00163 }
00164 
00165 shortnode::~shortnode(){
00166 
00167 }
00168 
00169 treeregion::treeregion(){
00170 
00171 }
00172 
00173 treeregion::~treeregion(){
00174 
00175 }
00176 
00177 //____________________________________________________________
00178 tree::tree(){
00179         tlayers = 8;//set tlayers == maxhits for now (for region 3)
00180         hshsiz = 511;
00181         father.genlink = 0;
00182         for(int i=0;i<4;i++){father.son[i]=0;}
00183         father.maxlevel = -1;
00184         father.minlevel = -1;
00185         father.bits = 1;
00186         for(int i=0;i<TLAYERS;i++){father.bit[i]=0;}
00187         father.xref = -1;
00188         npat=0;
00189 
00190         #define OFFS1   2 /* Next Sons have to be linked to offset 1 nodelist */
00191         #define SONEND  3 /* End of son-description */
00192         #define REALSON 4 /* Son and grandson description follows */
00193         #define REFSON  5 /* Son reference follows */
00194   
00195 }
00196 //____________________________________________________________
00197 tree::~tree(){
00198 
00199 }
00200 //____________________________________________________________
00201 void tree::rcInitTree(){
00202         /* This function should be set up to generate a treeregion
00203         for each detector region.  The original code is set up to
00204         do this - DONE*/
00205         /* This function now generates a treeregion for each 
00206         detector for each orientation and plane direction. It needs
00207         checks for the GEM according to plane directions. */
00208         enum EUppLow up_low;
00209         enum ERegion region;
00210         enum Etype type;
00211         enum Edir direction;
00212         char filename[256];
00213         for(up_low = w_upper; up_low <= w_lower;up_low++){
00214                 if(up_low == w_lower) continue; //skip lower for now
00215                 for(region = r1; region<=r3;region++){
00216                         if(region < r3) continue;//skip r1 and r2 for now
00217                         for(type = d_drift; type <=d_cerenkov;type++){
00218                                 if(type!=d_drift&&region==r3)continue;//only VDC in r3
00219                                 for(direction = null_dir; direction<= y_dir;direction++){
00220                                         if(direction!=u_dir && direction!=v_dir)continue;
00221                                                 
00222                                         sprintf( filename,"trees/tree%d-%d-%c-%c-%c-%c.tre",
00223                                                 tlayers,opt.levels[up_low][region-1][type],
00224                                                 "ul"[up_low],
00225                                                 "123"[region-1],
00226                                                 "dgtc"[type],
00227                                                 "nuvxy"[direction]);
00228                                         rcTreeRegion[up_low][region-1][type][direction] =
00229                                                         inittree(filename,opt.levels[up_low][region-1][type],
00230                                                         tlayers,rcDETRegion[up_low][region-1][direction]->width[2],type,region);
00231                                                 
00232 //cout << "(" << up_low << "," << region << "," << type << "," << direction << "," << orient << ")\n" ;
00233                                         //}
00234                                 }
00235                         }
00236                 }
00237         }
00238 }
00239 //____________________________________________________________
00240 
00241 int tree::consistent(treenode *tst, int level,enum Etype type,enum ERegion region){
00242   if(type == d_drift && region == r3){
00243   
00244   int templayers = 8;
00245   int i;
00246   int *b = tst->bit;            /* For faster access to pattern in tst->bit */
00247 
00248 
00249 
00250   double x0;                    /* Bitnumber in the first tree-detector,
00251                                    i.e. treelayer 0                         */ 
00252   double x3e, x3a;              /* Bitnumber in last / last checked layer   */
00253   double adda, adde;            
00254   double dze, dza;
00255 
00256   double xf=0,zf;
00257 
00258   double z[templayers];
00259   double cellwidth = 1.11125;//distance between wires
00260 
00261   int cutback=0;
00262   int firstnonzero=0;
00263 
00264   for(i=0;i<templayers;i++){
00265      if(b[i])firstnonzero++;
00266      if(firstnonzero && !b[i])templayers=i+1;
00267   }
00268 
00269   /* ----- find the z position of each tree-detector relative to  
00270            the first tree-detector                                   ----- */
00271   //for one HDC layer, the tree-detectors are all in a row.  This
00272   //will have to be altered when the 2nd layer is added
00273   z[0]=0;
00274   for( i = 1; i < templayers; i++) {
00275         z[i]=z[i-1]+cellwidth;
00276   }
00277 
00278   /* Get the layer with the largest bit value (dependent on rules in marklin)*/
00279   for( i = 0; i < templayers; i++){
00280         if(b[i]>=xf){
00281                 zf=i;
00282                 xf=b[i];
00283         }
00284   }
00285   /* ----- initial setting for the line check using the first and
00286            the last tree-detectors                                   ----- */
00287   dze = dza = zf;
00288   x0 = b[0];                      /* Fetch the pattern for 1st tree-det.    */
00289   x3a = x3e = xf;          /* Fetch the pattern for last tree-det.   */
00290   x3e++;
00291 
00292 
00293   
00294   
00295 
00296  
00297   /* ----- first check if a straight track through the bins in the 
00298            first and the last tree-detectors fulfill the max angle 
00299            condition                                               ----- */  
00300   double m_min = -((double)tlayers-1)/((double)(1<<level)-1);
00301   double m_max = -(4.0-1.0)/((double)(1<<level)-1);
00302   double m = -((double)zf)/((double)(xf-x0));
00303 
00304   //cout << m_min << " " << m << " " << m_max << endl;
00305   if(m < m_min || m > m_max)return 0;
00306 
00307   /* ----- check if all the bits are along a straight line by 
00308            looping through each pair of outer tree-detectors and 
00309            seeing if the bins on the enclosed tree-detectors are 
00310            along a straight line                                     ----- */
00311 
00312   for( i = zf - 1; i > 0; i--) {     /* loop from the back 
00313                                              tree-detectors forward */  
00314     adda = (x0-b[i])*dza+(x3a-x0)*z[i];   
00315     if( adda <= -dza || dza <= adda)
00316       return 0;
00317     adde = (x0-b[i])*dze+(x3e-x0-1)*z[i];
00318     if( adde <= -dze || dze <= adde)
00319       return 0;
00320     if( i > 1) {
00321       if( adda > 0) {
00322         x3e = b[i]+1;
00323         dze = z[i];
00324       } 
00325       if( adde < 0) {
00326         x3a = b[i];
00327         dza = z[i];
00328       }
00329     }
00330   }
00331   return 1;
00332   }
00333   else{
00334         cerr << "This function is only a stub" << endl;
00335         return 0;
00336   }
00337 
00338 }
00339 /*
00340 int tree::consistent(treenode *tst, int level,enum Etype type,enum ERegion region){
00341         cerr << type << "," << region << "," << level << endl;
00342 
00343 
00344 
00345 
00346         cerr << "This function is only a stub" << endl;
00347 //stub function for consistent until the rest of tree is implemented
00348         return 1;
00349 }
00350 */
00351 //____________________________________________________________
00352 treenode * tree::existent(treenode *tst, int hash){
00353         treenode *walk = generic[hash];   
00354         while( walk) { 
00355                 if(!memcmp( tst->bit,walk->bit,tlayers*sizeof(tst->bit[0]))){
00356                         return walk;                  /* found it! */
00357                 }
00358                 walk = walk->genlink;           /* nope, so look at the next pattern */
00359         }
00360         return 0;
00361 }
00362 //____________________________________________________________
00363 treenode * tree::nodeexists(nodenode *nd, treenode *tr){
00364         while( nd) {
00365                 if( !memcmp(nd->tree->bit,tr->bit, tlayers * sizeof(tr->bit[0])))
00366                         return nd->tree;  /* found it! */
00367                 nd = nd->next;      /* nope, so look at the next son of this father */
00368         }
00369         return 0;
00370 }
00371 //____________________________________________________________
00372 treenode * tree::treedup(treenode *todup){
00373         treenode *ret;
00374 
00375         ret = (treenode*)malloc(sizeof(treenode)); /* allocate the memory for 
00376                                                 the copy treenode          */
00377         assert(ret);                               /* cry if there was an error  */
00378         *ret = *todup;                             /* copy the treenode todup to 
00379                                                 the new treenode           */
00380         ret->xref = -1L;                           /* set the external reference
00381                                                 link                       */
00382         return ret;
00383 
00384 }
00385 //____________________________________________________________
00386 void tree::marklin(treenode *Father,int level,enum Etype type,enum ERegion region){
00387         treenode son;
00388         treenode *sonptr;
00389         nodenode *nodptr;
00390         int i,j;
00391         int offs;
00392         int flip;
00393         int maxs;
00394         int insert_hitpattern;
00395         int hsh;
00396         if(level == maxlevel){
00397                 return;
00398         }
00399         son = *Father;
00400         
00401         i= (1<<tlayers);        // (1<<x) is equal to 2^x 
00402                                 /* Number of possible son patterns for this 
00403                               this Father*/
00404         
00405         if(region==r3 && type == d_drift){
00406                 offs=1;
00407                 maxs=0;
00408                 flip=0;
00409                 int shift;//cell # of first cell
00410                 int maxhits = 8;//max # of cells that can be hit in wanted tracks
00411                 i = (1<<maxhits);
00412                 
00413                 while(i--){//loop through all possibilities
00414         
00415                         for(j=0;j<maxhits;j++){//this loop creates each possible pattern        
00416         
00417                                 if(i & (1<<j)){ 
00418                                         son.bit[j] = (Father->bit[j]<<1)+1;
00419                                 }
00420                                 else{   
00421                                         son.bit[j] = Father->bit[j]<<1;
00422                                 }
00423                         
00424                                 offs = (int)min(offs,son.bit[j]);
00425                         
00426                                 maxs = (int)max(maxs,son.bit[j]);
00427                         }
00428 
00429                         
00430                         //Cut patterns in which there are hits that lie outside the road                                between the first and last hits, i.e. :
00431                         //  X 0      0 X  
00432                         //  0 X  or  X 0
00433                         //  0 X      0 X
00434                         //  X 0      0 X
00435                         son.bits = son.bit[maxhits-1] - son.bit[0];
00436                         //cout << "-------------------------" << endl;
00437                         int cutback =0;
00438                         int cutflag =0;
00439                         for(j=1;j<maxhits;j++){
00440                                 if(son.bit[j]<son.bit[j-1]){//if the bin decreases
00441                                         if(son.bit[j])//and it's nonzero cut it
00442                                                 cutflag++;
00443                                         if(!son.bit[j]){//but if it's zero, make sure it stays zero
00444                                                 cutback++;
00445                                                 if(cutback==1)son.bits = son.bit[j-1] - son.bit[0];
00446                                         }
00447                                 }
00448                                 if(son.bit[j] && cutback)
00449                                         cutflag++;
00450 
00451                         }
00452                         if(cutflag){
00453                                 /*
00454                                 cout << "Cut :" ;
00455                                 for(j=0;j<maxhits;j++)
00456                                         cout << son.bit[j] << " " ;
00457                                 cout << endl;*/
00458                                 continue;
00459                         }
00460 
00461                         if( offs){/* If there is an offset, so         */
00462                                 /*cout << "Offset :" ;
00463                                 for(j=0;j<maxhits;j++)
00464                                         cout << son.bit[j] << " " ;
00465                                 cout << endl;
00466                                 */
00467                                 for( j = 0; j< maxhits; j++) /* shift all hits over this                                                                        offset   */
00468                                         son.bit[j] --;
00469                         }
00470                         if(son.bits < 0){
00471                                 /*cout << "Flip :" ;
00472                                 for(j=0;j<maxhits;j++)
00473                                         cout << son.bit[j] << " " ;
00474                                 cout << endl;
00475                 */
00476                                 flip =2 ;
00477                                 son.bits = -son.bits;
00478                                 for(j=0;j<maxhits;j++)
00479                                         son.bit[j] = son.bits-son.bit[j];
00480                         }
00481                         son.bits++;
00482                         sonptr = nodeexists( Father->son[offs+flip], &son);
00483                         hsh = (son.bit[tlayers-1]+son.bit[1])%HSHSIZ;
00484 
00485 
00486                         /*if(sonptr){for(j=0;j<maxhits;j++)cout << son.bit[j] << " " ;cout <<  "exists" << endl;}
00487                         else{ for(j=0;j<maxhits;j++)cout << son.bit[j] << " " ;cout << endl;}
00488                         cout << "hsh = " << son.bit[tlayers-1] << "," << son.bit[1] << "," << hshsiz << "," << hsh << endl;
00489                         cout << "level : " << level << endl;
00490                         cout << "bits : " << son.bits << endl;*/
00491                         insert_hitpattern = 1;
00492                         if( !sonptr&& 0 == (sonptr= existent( &son, hsh))){
00493                                 if( consistent( &son, level+1,type,region)) {
00494                                         //cout << "Adding treenode..." << endl;
00495                                         
00496                                         sonptr = treedup( &son);
00497                                         sonptr->son[0] = sonptr->son[1] = 
00498                                         sonptr->son[2] = sonptr->son[3] = 0; 
00499                                         sonptr->maxlevel = 
00500                                         sonptr->minlevel = level;
00501                                         sonptr->genlink = generic[hsh];      
00502                                         generic[hsh] = sonptr;
00503                                         npat++;
00504                                         /*cout << "good" <<endl;
00505                                         for(int k=0;k<tlayers;k++){
00506                                                 for(int l=0;l< 2<<(level);l++){
00507                                                         if(son.bit[k]==l)cout << "x ";
00508                                                         else cout << "0 ";
00509                                                 }
00510                                                 cout << endl;
00511                                         }
00512                                         */
00513                                         marklin( sonptr, level+1,type,region);
00514                                 }
00515                                 else{
00516                                         /*cout << "inconsistent" << endl;
00517                                         for(int k=0;k<tlayers;k++){
00518                                                 for(int l=0;l< 2<<(level);l++){
00519                                                         if(son.bit[k]==l)cout << "x ";
00520                                                         else cout << "0 ";
00521                                                 }
00522                                                 cout << endl;
00523                                         }
00524                                         */
00525                                         insert_hitpattern = 0;
00526                                 }
00527                         }
00528                         else if( (sonptr->minlevel > level  && consistent( &son, level+1,type,region) )||sonptr->maxlevel < level) {
00529                                 sonptr->minlevel = (int)min(level,sonptr->minlevel);
00530                                 sonptr->maxlevel = (int)max(level,sonptr->maxlevel);
00531                                 /*for(int k=0;k<tlayers;k++){
00532                                         for(int l=0;l< 2<<(level);l++){
00533                                                 if(son.bit[k]==l)cout << "x ";
00534                                                 else cout << "0 ";
00535                                         }
00536                                         cout << endl;
00537                                 }
00538                                 */
00539 
00540                                 marklin( sonptr, level+1,type,region);
00541                         }
00542                         
00543                         if( insert_hitpattern  &&                          /* "insert pattern"
00544                                                           flag is set and    */
00545                                 !nodeexists( Father->son[offs+flip], &son)) {
00546                                 nodptr = (nodenode*)malloc( sizeof( nodenode));    /* create a nodenode  */
00547                                 assert(nodptr);                                    /* cry if error       */
00548                                 nodptr->next             = Father->son[offs+flip]; /* append it onto     
00549                                                           the son list       */
00550                                 nodptr->tree             = sonptr;
00551                                 Father->son[offs+flip] = nodptr;
00552                                 //cout << "Father's son " << offs+flip << " set" << endl;
00553                         }
00554 
00555                 }
00556 
00557                 
00558 
00559 
00560 
00561 
00562 
00563 
00564         }
00565         else{
00566         while( i--){
00567                 offs =1;
00568                 maxs =0;
00569                 flip =0;
00570 
00571                 for(j=0;j<tlayers;j++){
00572                         //cout << "for("<< j << "," << tlayers << "," <<
00573                         //Father->bit[j] << "," << (1<<j) << "," << i << ")" << endl;
00574         
00575 
00576                         if(i & (1<<j)){
00577                                 son.bit[j] = (Father->bit[j]<<1)+1;
00578                                 }
00579                         else{
00580                                 son.bit[j] = Father->bit[j]<<1;
00581                         }
00582                         offs = (int)min(offs,son.bit[j]);
00583                         maxs = (int)max(maxs,son.bit[j]);
00584                 }
00585                 son.bits = son.bit[tlayers-1] - son.bit[0];
00586                 //cout << "(" << maxs << "," << offs << "," << son.bits << ")" << endl;
00587                 if(maxs-offs > abs(son.bits)){
00588                         //cout << "yes" << endl;
00589                         continue;
00590                 }
00591                 
00592                 if(offs)
00593                         for(j=0;j<tlayers;j++)
00594                                 son.bit[j]--;
00595                 
00596                 if(son.bits < 0){
00597                         flip =2 ;
00598                         son.bits = -son.bits;
00599                         for(j=0;j<tlayers;j++)
00600                                 son.bit[j] = son.bits-son.bit[j];
00601                 }
00602                 son.bits++;
00603                 sonptr= nodeexists(Father->son[offs+flip],&son);
00604                 hsh = (son.bit[tlayers-1]+son.bit[1])%hshsiz;
00605                 cerr << "hsh = " << hsh << endl;
00606                 insert_hitpattern = 1;
00607                 
00608                 if( !sonptr&& 0 == (sonptr= existent( &son, hsh))) {
00609                         //cout << "Pattern is unknown" << endl;
00610                         //cout << "-----------" << endl;
00611                         //son.print();
00612                         //cout << "-----------" << endl;
00613                         if( consistent( &son, level+1,type,region)) {
00614                                 //cout << "Adding treenode..." << endl;
00615                                 sonptr = treedup( &son);
00616                                 sonptr->son[0] = sonptr->son[1] = 
00617                                 sonptr->son[2] = sonptr->son[3] = 0; 
00618                                 sonptr->maxlevel = 
00619                                 sonptr->minlevel = level;
00620                                 sonptr->genlink = generic[hsh];      
00621                                 generic[hsh] = sonptr;
00622                                 marklin( sonptr, level+1,type,region);
00623                         }
00624                         else
00625                                 insert_hitpattern = 0;
00626                 }       
00627                 else if( (sonptr->minlevel > level  && consistent( &son, level+1,type,region) )
00628               ||        sonptr->maxlevel < level) {
00629                         sonptr->minlevel = (int)min(level,sonptr->minlevel);
00630                         sonptr->maxlevel = (int)max(level,sonptr->maxlevel);
00631                         marklin( sonptr, level+1,type,region);
00632                 }
00633                 //cout << "insert_hitpattern = " << insert_hitpattern << endl;
00634 
00635                 if( insert_hitpattern  &&                          /* "insert pattern"
00636                                                           flag is set and    */
00637         !nodeexists( Father->son[offs+flip], &son)) {
00638                         nodptr = (nodenode*)malloc( sizeof( nodenode));    /* create a nodenode  */
00639                         assert(nodptr);                                    /* cry if error       */
00640                         nodptr->next             = Father->son[offs+flip]; /* append it onto     
00641                                                           the son list       */
00642                         nodptr->tree             = sonptr;
00643                         Father->son[offs+flip] = nodptr;
00644                         //cout << "Father's son " << offs+flip << " set" << endl;
00645                 }
00646         }
00647         }
00648 }
00649 //____________________________________________________________
00650 
00651 
00652 
00653 
00654 void tree::treeout(treenode *tn, int level, int off){
00655         nodenode *nd;
00656         int i,v;
00657 
00658         if( level == maxlevel)         /* the level of the treenode is deeper     */
00659                 return;                      /* than the depth of the database.         */
00660 
00661         for(i = 0; i < tlayers; i++) { /* loop over tree-detectors in hit pattern */ 
00662                 v = tn->bit[i];              /* the "on" bin for a tree-detector        */
00663                 if( off & 2)                 /* is it reversed?                         */
00664                         v = tn->bits-1-v;          /* yes, then flip it                       */
00665                 if( off & 1)                 /* is it offset?                           */
00666                         v++;                       /* yes, then apply the offset              */
00667                 printf("%d%*s|%*s*%*s|\n",level,level,"", /* print the bin for this     */
00668                         v, "", tn->bits-1-v,"");           /* tree-detector              */
00669                 puts("");
00670 
00671                 for(i = 0; i < 4; i++) {     /* now loop over the four types (normal, 
00672                                     offset, flipped, flipped offset) of 
00673                                     the sons below this treenode            */
00674                         nd = tn->son[i];           /* nodenode for the son type               */
00675                         while( nd) {               /* loop over nodenodes of this type        */
00676                                 treeout( nd->tree, level+1, i); /* display this nodenode's treenode */
00677                                 nd = nd->next;           /* next son of this type bitte */
00678                         } 
00679                 } 
00680         } /* of loop over tree-detectors */
00681 }
00682 //____________________________________________________________
00683 void tree::freetree(){
00684         treenode *tn,*ltn; 
00685         nodenode *nd,*lnd;
00686         int i,j;
00687 
00688         for( i = 0; i < HSHSIZ; i++) { /* loop over the entries in the genlink 
00689                                     hash table                            */
00690 
00691                 tn = generic[i];                 /* fetch the first treenode for this 
00692                                     hash entry                            */
00693                 while(tn) {                  /* loop over the treenodes for this hash
00694                                     table entry                           */
00695 
00696                         for( j = 0; j < 4; j++) {  /* loop over the four types of sons
00697                                     connected to this treenode            */
00698 
00699                                 nd = tn->son[j];         /* fetch the first nodenode of this type */
00700                                 while(nd) {              /* loop over all nodenodes of this type  */
00701                                         nd = (lnd = nd)->next; /* lnd = pointer to treenode attached  
00702                                           to this nodenode                */
00703                                  /*  nd = next nodenode attached to this 
00704                                           nodenode                        */
00705                                         free(lnd);             /* free the memory for the treenode      */
00706                                 } /* end loop over nodenodes */
00707 
00708                         }
00709                         tn = (ltn = tn)->genlink;  /* ltn = this treenode                   */
00710                                  /*  tn = genlink treenode attached to
00711                                           this treenode                   */
00712                         free(ltn);                 /* free the memory for this treenode     */
00713 
00714                 } /* end loop over genlink treenodes for a hash table entry */
00715         } /* end loop over the genlink hash table entries */
00716 
00717         return;
00718 }
00719 //____________________________________________________________
00720 treeregion * tree::readtree(char *filename, int levels, int tlayers, double rwidth, int dontread){
00721         FILE *f = 0;
00722         shorttree *stb;
00723         treeregion *trr;
00724         double width;
00725         long num;
00726 
00727         xref = 0;
00728         if( !dontread) {
00729                 f = fopen( filename, "rb");
00730                 if( !f)
00731                         return 0;
00732 
00733                 if( fread(&num, sizeof(long), 1L, f) < 1 ||
00734                 fread(&width, sizeof( width), 1L, f) < 1 ) {
00735                         fclose(f) ;
00736                         return 0;
00737                 }
00738                 //cerr << "Num = " << num << endl << "width = " << width << endl;
00739                 stb = (shorttree *)malloc( num * sizeof(shorttree));
00740                 assert(stb);
00741         } else {
00742                 width = rwidth;
00743                 stb = 0;
00744         }
00745         trr = (treeregion *)malloc( sizeof( treeregion));
00746         maxref = num;
00747         if( !dontread && _readtree( f, stb, 0, tlayers)) {
00748                 
00749                 free(stb);
00750                 free(trr);
00751                 fclose(f);
00752                 stb = 0;
00753                 return 0;
00754         }
00755         if( !dontread )
00756                 fclose(f);
00757         trr->searchable = stb ? true : false;
00758         //cerr << "searchable = " << trr->searchable << endl;
00759         trr->node.tree  = stb;
00760         trr->node.next  = 0;
00761         trr->rWidth     = width;
00762         
00763         return trr;
00764 }
00765 //____________________________________________________________
00766 treeregion * tree::inittree(char *filename, int levels, int tlayer, double width,enum Etype type,enum ERegion region){
00767         treeregion *trr;
00768         treenode  *back;
00769         tlayers  = tlayer;
00770         maxlevel = levels+1;
00771         detwidth = width;
00772 
00773         if( tlayer == 0 )
00774                 return 0;
00775         
00776         /* ---------------- first: try to read it in ... */
00777         if(0 == (trr = readtree(filename,levels,tlayer, width,0))|| trr->rWidth != width/*||1*/){ //FORCING PATTERN GENERATION) {
00778                 //cerr << "pattern generation forced" << endl;
00779                 /* ------- if this doesnt work, generate own database -------*/
00780                 if( trr ) {
00781                         if( trr->node.tree )
00782                                 free(trr->node.tree);
00783                         free(trr);
00784                 }
00785                 fflush(stdout);
00786                 back = _inittree( tlayer,type,region);
00787 
00788                 if( !back) {
00789                         fprintf(stderr,"hrc: Tree couldn't be built.\n");
00790                         exit(1);
00791                 }
00792                 printf(" Generated.\n");
00793                 fflush(stdout);
00794                 /* ------- and write it to disk for later fast access ----- */
00795       
00796                 if( !writetree(filename, back, levels, tlayer, width)) {
00797                         fprintf(stderr,"hrc: Tree couldn't be written.\n");
00798                         perror(filename);
00799                         exit(1);
00800                 }
00801                 printf(" Cached.\n");
00802                 fflush(stdout);
00803                 freetree(); /* Free the tree structuere -*/
00804                 /*- and read it in again to get the short search format -*/
00805                 if( 0 == (trr = readtree(filename,levels,tlayer, width, 0))) {
00806                         fprintf(stderr,"hrc: New-Tree couldn't be read.\n");
00807                         perror(filename);
00808                         exit(1);
00809                 }
00810                 printf(" Done.\n");
00811         }
00812         return trr;
00813 
00814 
00815         
00816 }
00817 //____________________________________________________________
00818 treenode * tree::_inittree(int tlayer,enum Etype type,enum ERegion region){
00819         treenode *ret = treedup(&father); /* generate a copy of the father to
00820                                         start off this treesearch database */
00821         
00822         memset(generic,0,sizeof(generic)); /* clear genlink hash table           */
00823         marklin(ret, 0,type,region);                 /* call the recursive tree generator  */
00824         ret->genlink = generic[0];           /* finally, add the father to the 
00825                                                  genlink hash table        */
00826         generic[0] = ret;
00827         cerr << "npat : " << npat<< endl;
00828         return ret; /* return the generated treesearch database to caller */
00829 }
00830 //____________________________________________________________
00831 int tree::_writetree(treenode *tn, FILE *fp, int tlayers){
00832         int i;
00833         nodenode *nd;
00834         //tn->print();
00835         if(tn->maxlevel<tn->minlevel)cerr << "("<<tn->minlevel<<","<<tn->maxlevel<<")"<<endl;
00836         if( tn->xref == -1) {         /* pattern has never been written */
00837                 tn->xref = xref++;              /* set its reference */
00838                 
00839                 if( fputc( REALSON, fp) == EOF || /* and write all pattern data */
00840                 fwrite(&tn->minlevel, sizeof( int), 1L, fp) != 1 ||
00841                 fwrite(&tn->bits, sizeof( int), 1L, fp) != 1 ||
00842                 fwrite(tn->bit,sizeof( int), (size_t)tlayers, fp) != (unsigned int)tlayers )
00843                         return -1;
00844         for( i = 0; i < 4; i++) {
00845                 nd = tn->son[i];
00846                 while( nd) {
00847                         if( _writetree(nd->tree,fp,tlayers))
00848                                 return -1;
00849                         nd = nd->next;
00850                 }
00851                 if( fputc( SONEND, fp) == EOF) /* set the marker for end of sonlist */
00852                         return -1;
00853                 }
00854         } else {                        /* else - only write a reference to */
00855                 if( fputc( REFSON, fp) == EOF  || /* a former written pattern */
00856                 fwrite( &tn->xref, sizeof(tn->xref), 1L, fp) != 1)
00857                         return -1;
00858         }
00859         return 0;
00860 }
00861 //____________________________________________________________
00862 long tree::writetree(char *fn, treenode *tn, int levels, int tlayers, double width){
00863         
00864         //cout << "write tree called" << endl;
00865         FILE *fp = 0;
00866         //extern bool bWriteGlobal;
00867   
00868         //if( bWriteGlobal ) <- ALLOWS FOR COMMAND LINE OPTION OF MAIN.C TO CHOOSE
00869         // WHETHER TO WRITE OR NOT
00870         fp = fopen(fn, "wb");   /* open an output stream */
00871         
00872         xref = 0;
00873         if( !fp){               /* error checking */
00874                 //cout << "debug4c" << endl;
00875                 char *fwsn = strrchr(fn,'/'); /* try to write local file */
00876                 if( fwsn++ ) {
00877                         //cout << "debug4d" << endl;
00878                         fp = fopen( fwsn, "wb+");
00879                         if( fp )
00880                         strcpy( fn, fwsn);
00881                 }
00882         }
00883         if( !fp){
00884                 //cout << "debug4b" << endl;
00885                 return 0;
00886         }
00887         /* --------------------- write 4 bytes to fill later */
00888         if( fwrite( &xref, sizeof(long), 1L, fp) != 1 ||
00889         fwrite( &width, sizeof( double), 1L, fp) != 1 ||
00890         _writetree( tn, fp, tlayers) ) { /* ... and write whole tree*/
00891                 fclose(fp);
00892                 return 0;
00893         }
00894         if( fputc( SONEND, fp) == EOF) /* append marker for end of son list */
00895                 return -1;
00896   
00897         rewind(fp);                     /* now write the total numer of different */
00898         if( fwrite( &xref, sizeof(long), 1L, fp) != 1) { /* patternes */
00899                 fclose(fp);
00900                 //cout << "debug4" << endl;
00901                 return 0;
00902         }
00903         fclose(fp);                     /* everything worked fine */
00904         //cout << "write finished" << endl;
00905         return xref;
00906 }
00907 //____________________________________________________________
00908 
00909 int tree::_readtree(FILE *f, shorttree *stb, shortnode **fath, int tlayers){
00910 int c, sonny;
00911 int Minlevel,Bits,Bit[TLAYERS];
00912 long ref;
00913 
00914 shortnode *node;
00915 for(;;) {
00916         c = fgetc( f);
00917         if( c == REALSON) {             /* in case of a real pattern read it                                            in */
00918                 if( xref >= maxref ) {
00919                         fputs("hrc: readtree failed. error #5. rebuilding treefiles.",stderr);
00920                         return -1;
00921                 }
00922                 if(fread(&Minlevel,sizeof(int),1L,f)!=1||
00923                 fread(&Bits,sizeof(int),1L,f)!=1||
00924                 fread(&Bit,sizeof(int)*tlayers,1L,f)!=1){
00925                         fputs("hrc: readtree failed. error #1. rebuilding treefiles.",stderr);
00926                         return -1;
00927                 }
00928                 
00929                 ref = xref;
00930                 xref++;
00931                 (stb+ref)->minlevel = Minlevel;
00932                 (stb+ref)->bits = Bits;
00933                 for(int i=0;i<tlayers;i++){
00934                         (stb+ref)->bit[i] = Bit[i];
00935                 }
00936                 /*
00937                 if( fread( stb+(ref = xref++), sizeof(int)*(2+tlayers), 1L, f) != 1) {
00938                         fputs("hrc: readtree failed. error #1. rebuilding treefiles.",stderr);
00939                         return -1;
00940                 }
00941                 */
00942                 //(stb+ref)->print();
00943                 if( fath) {     /* and append this patterns to the fathers                                      sons */
00944                         node = (shortnode *)malloc( sizeof( shortnode));
00945                         assert(node);
00946                         node -> tree = stb+ref;
00947                         node -> next = *fath;
00948                         (*fath)      = node;
00949                         //node->tree->print();
00950                 }
00951    
00952                 memset( stb[ref].son, 0, sizeof(stb[ref].son)); /* has no sons yet */
00953                 /* if( level < maxlevel -1) {  but try to read them in */
00954                 
00955                 for(sonny = 0; sonny < 4; sonny++) {
00956                         if( _readtree( f, stb, 
00957                         stb[ref].son+sonny, tlayers)){
00958                                 cerr << "c";
00959                                 return -1;
00960                         }
00961                 }
00962       /* } */
00963         } else if( c == REFSON) {       /* in case of a reference - read in the ref */
00964                 if( fread( &ref, sizeof(ref), 1L, f) != 1) {
00965                         fputs("hrc: readtree failed. error #1. rebuilding treefiles.",stderr);
00966                         return -1;
00967                 }
00968                 if( ref >= xref || ref < 0) { /* some error checking */
00969                         fputs("hrc: readtree failed. error #3. rebuilding treefiles.",stderr);
00970                         return -1;
00971                 }
00972                 if( !fath) {            /* still some error checking */
00973                         fputs("hrc: readtree failed. error #4. rebuilding treefiles.",stderr);
00974                         return -1;
00975                 }
00976                 node = (shortnode *)malloc( sizeof( shortnode)); /* create a new node */
00977                 assert(node);
00978                 node -> tree = stb+ref; /* and append the alread read-in tree */
00979                 node -> next = *fath;   /* 'ref' to this node. */
00980                 (*fath)      = node;
00981         } else if( c == SONEND) /* sonend means end reading */
00982                 break;
00983         else {                  /* this function constists of 50% err check */
00984                 fputs("hrc: readtree failed. error #2. rebuilding treefiles.",stderr);
00985                 return -1;
00986         }
00987 }
00988 return 0;
00989 }
00990 //____________________________________________________________
00991 void tree::printtree(treenode *tn){
00992         tn->print();
00993 
00994 }
00995 //____________________________________________________________
00996 TreeLine::TreeLine(){}
00997 TreeLine::~TreeLine(){}
00998 

Generated on Fri Jan 11 22:33:59 2008 by  doxygen 1.4.6