Anaphe Home Page Reference Documentation

Main Page     Namespaces     Classes     Source Code    

P_Histo_3D.cpp

Go to the documentation of this file.
00001 #if 1
00002         #include "HTL/P_Histo_3D.h"
00003 #else
00004         #include "HTL/T_Histo_3D.h"
00005 #endif
00006 
00007 //
00008 // Let's get lazy and use the preprocessor:
00009 //
00010 #define TEMPLATE___     \
00011         template< class T_Life, class T_Bin             \
00012                 , class T_Point_X, class T_Partition_X  \
00013                 , class T_Point_Y, class T_Partition_Y  \
00014                 , class T_Point_Z, class T_Partition_Z >
00015 
00016 #define CLASS___        \
00017         P_Histo_3D < T_Life, T_Bin , T_Point_X, T_Partition_X, \
00018         T_Point_Y, T_Partition_Y , T_Point_Z, T_Partition_Z>
00019 
00020 //
00021 // *************************************************************************** 
00022 //
00023 
00024 TEMPLATE___
00025 CLASS___::P_Histo_3D ( const char *a_name
00026         , const T_Partition_X &a_partition_X
00027         , const T_Partition_Y &a_partition_Y 
00028         , const T_Partition_Z &a_partition_Z )
00029         : P_I_Histo_3D()
00030         , name_(a_name)
00031         , partition_X_( a_partition_X )
00032         , partition_Y_( a_partition_Y )
00033         , partition_Z_( a_partition_Z )
00034         , bins_((a_partition_X.bin_count()+2)
00035                 *(a_partition_Y.bin_count()+2)
00036                 *(a_partition_Z.bin_count()+2) 
00037                 +  dim()*dim()*(dim()-1))
00038 {
00039 }
00040 
00041 TEMPLATE___
00042 CLASS___::P_Histo_3D( I_Histo &a_histo, int copy_data )
00043         : name_( a_histo.name() )
00044         , partition_X_( a_histo.i_partition(0) )
00045         , partition_Y_( a_histo.i_partition(1) )
00046         , partition_Z_( a_histo.i_partition(2) )
00047         , bins_( a_histo.bin_count() + a_histo.extra_bin_count() +
00048                  a_histo.dim()*a_histo.dim()*(a_histo.dim()-1))
00049 {
00050   if (a_histo.dim() == 3) {
00051     if( copy_data ) {
00052       // Copy the bin contents:
00053       //
00054       for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00055         bins_[i] .make( a_histo.i_bin(i) );
00056     }
00057   } else 
00058     HTL_ERR("1st argument is not a 3D-histo interface");
00059 }
00060 
00061 TEMPLATE___
00062 CLASS___::P_Histo_3D(const I_Histo &a_histo, int copy_data ) 
00063         : name_( a_histo.name() )
00064         , partition_X_( a_histo.i_partition(0) )
00065         , partition_Y_( a_histo.i_partition(1) )
00066         , partition_Z_( a_histo.i_partition(2) )
00067         , bins_( a_histo.bin_count() + a_histo.extra_bin_count() +
00068                  a_histo.dim()*a_histo.dim()*(a_histo.dim()-1))
00069 {
00070   if (a_histo.dim() == 3) {
00071     if( copy_data ) {
00072       // Copy the bin contents:
00073       //
00074       for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00075         bins_[i] .make( a_histo.i_bin(i) );
00076     }
00077   } else 
00078     HTL_ERR("1st argument is not a 3D-histo interface");
00079 }
00080 
00081 TEMPLATE___
00082 I_Bin & CLASS___::i_bin( I_Bin_Location &a_location )
00083 {
00084   if(a_location.size() >= (unsigned long) dim()) {
00085     return (I_Bin &) bin( a_location[0], a_location[1], a_location[2], 0);
00086   } else {
00087     HTL_ERR("Invalid dimension for location in i_bin(..)");
00088     return (I_Bin &)  bin(0, 0 ,0 );
00089   }
00090 }
00091 
00092 TEMPLATE___
00093 I_Bin & CLASS___::i_bin( I_Bin_Location &a_location ) const
00094 {
00095   if(a_location.size() >= (unsigned long) dim()) {
00096     return (I_Bin &) bin( a_location[0], a_location[1], a_location[2] );
00097   } else {
00098     HTL_ERR("Invalid dimension for location in i_bin(..)");
00099     return (I_Bin &)  bin(0, 0 , 0);
00100   }
00101 }
00102 
00103 TEMPLATE___
00104 I_Bin & CLASS___::i_bin( Index i  ) 
00105 {
00106   if (i>=0 && i<Index(bin_count()+extra_bin_count())) {
00107     return (I_Bin &) bins_[i];
00108   } else {
00109     HTL_ERR("Invalid index in i_bin( Index i )");
00110     return (I_Bin &) bins_[0];
00111   }
00112 }
00113 
00114 TEMPLATE___
00115 I_Bin & CLASS___::i_bin( Index i  ) const
00116 {
00117   if (i>=0 && i<Index(bin_count()+extra_bin_count())) {
00118     return (I_Bin &) bins_[i];
00119   } else {
00120     HTL_ERR("Invalid index in i_bin( Index i )");
00121     return (I_Bin &) bins_[0];
00122   }
00123 }
00124 
00125 TEMPLATE___
00126 I_Bin & CLASS___::i_extra_bin( I_Extra_Bin_Location &a_location)
00127 {
00128   if(a_location.size() >= (unsigned long) dim()) {
00129     return (I_Bin &) extra_bin( a_location[0], a_location[1], a_location[2]);
00130   } else {
00131     HTL_ERR("Invalid dimension for location in i_extra_bin(..)");
00132     return (I_Bin &)  bin(0, 0 ,0 );
00133   }
00134 }
00135 
00136 TEMPLATE___
00137 I_Bin & CLASS___::i_extra_bin( I_Extra_Bin_Location &a_location) const
00138 {
00139   if(a_location.size() >= (unsigned long) dim()) {
00140     return (I_Bin &) extra_bin( a_location[0], a_location[1], a_location[2] );
00141   } else {
00142     HTL_ERR("Invalid dimension for location in i_extra_bin(..)");
00143     return (I_Bin &)  bin(0, 0 , 0);
00144   }
00145 }
00146 
00147 TEMPLATE___
00148 I_Partition & CLASS___::i_partition( Index p )
00149 {
00150   if(p>=0 && p<=2) {
00151     switch( p ) {
00152     case 0: return (I_Partition &) partition_X_;
00153     case 1: return (I_Partition &) partition_Y_;
00154     case 2: return (I_Partition &) partition_Z_;
00155       // To avoid warnings?
00156     default:return (I_Partition &) partition_X_;
00157     }
00158   } else {
00159     HTL_ERR("Invalid partition index in i_partition(..)");
00160     return (I_Partition &) partition_X_;
00161   }
00162 }
00163 
00164 TEMPLATE___
00165 I_Partition & CLASS___::i_partition( Index p ) const
00166 {
00167   if(p>=0 && p<=2) {
00168     switch( p ) {
00169     case 0: return (I_Partition &) partition_X_;
00170     case 1: return (I_Partition &) partition_Y_;
00171     case 2: return (I_Partition &) partition_Z_;
00172       // To avoid warnings?
00173     default: return (I_Partition &) partition_X_;
00174     }
00175   } else {
00176     HTL_ERR("Invalid partition index in i_partition(..)");
00177     return (I_Partition &) partition_X_;
00178   }
00179 }
00180 
00181 TEMPLATE___
00182 T_Bin & CLASS___::extra_bin( Extra_Index an_ei,Extra_Index an_ej,
00183                              Extra_Index an_ek, int updateBin)
00184 {
00185   if(EXTRA_VALID(an_ei) && EXTRA_VALID(an_ej) && EXTRA_VALID(an_ek)) {
00186     if (updateBin)  {H_BIN_UPDATE}
00187     // EXTRA_VALID(an_ei) returns {i=0,1,2} <-> {U,I,O}
00188     return (T_Bin &) bins_[summaryOUInfo(an_ei,an_ej,an_ek)];
00189   } else {
00190     HTL_ERR("Invalid index in extra_bin(..)");
00191     return (T_Bin &) bins_[ bin_count()];
00192   }
00193 }
00194 
00195 TEMPLATE___
00196 T_Bin & CLASS___::extra_bin( Extra_Index an_ei,Extra_Index an_ej,
00197                              Extra_Index an_ek ) const
00198 {
00199   if(EXTRA_VALID(an_ei) && EXTRA_VALID(an_ej) && EXTRA_VALID(an_ek)) {
00200     // EXTRA_VALID(an_ei) returns {i=0,1,2} <-> {U,I,O}
00201     HTL_ERR("Can't get the extra_bin information in const method");
00202     return (T_Bin &) bins_[ bin_count()];
00203   } else {
00204     HTL_ERR("Invalid index in extra_bin(..)");
00205     return (T_Bin &) bins_[ bin_count()];
00206   }
00207 }
00208 
00209 TEMPLATE___
00210 void CLASS___::reset()
00211 {
00212   for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00213     bins_[i] .reset();
00214 }
00215 
00216 
00217 TEMPLATE___
00218 T_Bin & CLASS___::mapped_bin( T_Point_X x, T_Point_Y y, T_Point_Z z )
00219 {
00220   // Map x to an index:
00221   Index an_index_x;
00222   Extra_Index an_extra_index_x;
00223   partition_X().map_index( x, an_index_x, an_extra_index_x );
00224 
00225   // Map y to an index:
00226   Index an_index_y;
00227   Extra_Index an_extra_index_y;
00228   partition_Y().map_index( y, an_index_y, an_extra_index_y );
00229 
00230   // Map z to an index:
00231   Index an_index_z;
00232   Extra_Index an_extra_index_z;
00233   partition_Z().map_index( z, an_index_z, an_extra_index_z );
00234 
00235   // Return mapped bin:
00236   if( is_in_range( an_extra_index_x, an_extra_index_y, an_extra_index_z ) )
00237     return bin( an_index_x, an_index_y, an_index_z );
00238   else
00239     return _bin(realOutRange(an_extra_index_x, an_extra_index_y,
00240                 an_extra_index_z, an_index_x , an_index_y, an_index_z ));
00241 }
00242 
00243 TEMPLATE___
00244 void CLASS___::compute_(const I_Histo &other, binHistoOp &oper)
00245 {
00246   H_BIN_UPDATE;
00247   for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00248     oper.eval(i_bin(i), other.i_bin(i) );
00249 }
00250 
00251 TEMPLATE___
00252 void CLASS___::compute_(double value, binScalarOp &oper)
00253 {
00254   H_BIN_UPDATE;
00255   for( Index i=0; i<Index(bin_count()+extra_bin_count()); i++ )
00256     oper.eval(i_bin(i), value );
00257 }
00258 
00259 TEMPLATE___
00260 void CLASS___::add_( const I_Histo &other )
00261 {
00262   if (compatiblePartitions(other,"add_(..)")) {
00263     binHistoAdd operation;
00264     compute_ (other, operation);
00265   }
00266 }
00267 
00268 TEMPLATE___
00269 P_REF_I_Histo CLASS___::add1_( const I_Histo &other )
00270 {
00271   add_( other );
00272   return H_P_THIS;
00273 }
00274 
00275 
00276 TEMPLATE___
00277 void CLASS___::sub_( const I_Histo &other )
00278 {
00279   if (compatiblePartitions(other,"sub_(..)")) {
00280     binHistoSub operation;
00281     compute_ (other, operation);
00282   } 
00283 }
00284 
00285 TEMPLATE___
00286 P_REF_I_Histo CLASS___::sub1_( const I_Histo &other )
00287 {
00288   sub_( other );
00289   return H_P_THIS;
00290 }
00291 
00292 
00293 TEMPLATE___
00294 void CLASS___::mul_( const I_Histo &other )
00295 {
00296   if (compatiblePartitions(other,"mul_(..)")) {
00297     binHistoMul operation;
00298     compute_ (other, operation);
00299   }
00300 }
00301 
00302 TEMPLATE___
00303 P_REF_I_Histo CLASS___::mul1_( const I_Histo &other )
00304 {
00305   mul_( other );
00306   return H_P_THIS;
00307 }
00308 
00309 
00310 TEMPLATE___
00311 void CLASS___::div_( const I_Histo &other )
00312 {
00313   if (compatiblePartitions(other,"div_(..)")) {
00314     binHistoDiv operation;
00315     compute_ (other, operation);
00316   } 
00317 }
00318 
00319 TEMPLATE___
00320 P_REF_I_Histo CLASS___::div1_( const I_Histo &other )
00321 {
00322   div_( other );
00323   return H_P_THIS;
00324 }
00325 
00326 
00327 TEMPLATE___
00328 void CLASS___::binomial_div_( const I_Histo &other )
00329 {
00330   if (compatiblePartitions(other,"div_(..)")) {
00331     binHistoBinDiv operation;
00332     compute_ (other, operation);
00333   }
00334 }
00335 
00336 TEMPLATE___
00337 P_REF_I_Histo CLASS___::binomial_div1_( const I_Histo &other )
00338 {
00339   binomial_div_( other );
00340   return H_P_THIS;
00341 }
00342 
00343 TEMPLATE___
00344 void CLASS___::add_( double x )
00345 {
00346   binScalarAdd operation;
00347   compute_ (x,operation );
00348 }
00349 
00350 TEMPLATE___
00351 void CLASS___::sub_( double x )
00352 {
00353   binScalarSub operation;
00354   compute_ (x, operation);
00355 }
00356 
00357 TEMPLATE___
00358 void CLASS___::mul_( double x )
00359 {
00360   binScalarMul operation;
00361   compute_ (x, operation);
00362 }
00363 
00364 TEMPLATE___
00365 void CLASS___::div_( double x )
00366 {
00367   binScalarDiv operation;
00368   compute_ (x, operation);
00369 }
00370 
00371 TEMPLATE___
00372 bool CLASS___::compatiblePartitions (const I_Histo &other, const char *oper) {
00373   if( (partition_X().is_compatible_with(((I_Histo &) other).i_partition(0))) 
00374     &&(partition_Y().is_compatible_with(((I_Histo &) other).i_partition(1)))
00375     &&(partition_Z().is_compatible_with(((I_Histo &) other).i_partition(2)))){
00376     return true;
00377   } else {
00378     char msg [128];
00379     strcpy (msg, "Incompatible partitions in (..)");
00380     strcat (msg,oper);
00381     HTL_ERR(msg );    
00382     return false;
00383   }
00384 }
00385 
00386 TEMPLATE___
00387 void CLASS___::faceBoundary(Extra_Index an_ei,Extra_Index an_ej,
00388                             Extra_Index an_ek, Index& low, Index& high) {
00389   Index n = partition_X().bin_count();
00390   Index m = partition_Y().bin_count();
00391   Index p = partition_Z().bin_count();
00392   low = m*n*p ;
00393   high = m*n*p ;
00394   if (an_ei == H_UNDERFLOW) {low +=0; high += m*p;}
00395   if (an_ei == H_OVERFLOW)  {low +=m*p; high += m*p*2;}
00396   if (an_ej == H_UNDERFLOW) {low +=m*p*2; high +=  m*p*2+n*p;}
00397   if (an_ej == H_OVERFLOW)  {low +=m*p*2+n*p; high +=  m*p*2+n*p*2;}
00398   if (an_ek == H_UNDERFLOW) {low +=m*p*2+n*p*2; high += m*p*2+n*p*2+n*m ;}
00399   if (an_ek == H_OVERFLOW)  {low +=m*p*2+n*p*2+n*m; high += m*p*2+n*p*2+n*m*2;}
00400 }                           
00401 
00402 TEMPLATE___
00403 void CLASS___::edgeBoundary(Extra_Index an_ei,Extra_Index an_ej,
00404                             Extra_Index an_ek, Index& low, Index& high) {
00405   Index n = partition_X().bin_count();
00406   Index m = partition_Y().bin_count();
00407   Index p = partition_Z().bin_count();
00408   low = m*n*p + m*p*2+n*p*2+n*m*2;
00409   high = m*n*p + m*p*2+n*p*2+n*m*2;
00410 
00411   if ((an_ei == H_UNDERFLOW) && (an_ej == H_UNDERFLOW)) {
00412     low += 0; high += p;
00413   }
00414   if ((an_ei == H_OVERFLOW ) && (an_ej == H_UNDERFLOW)) {
00415     low += p; high += p*2;
00416   }
00417   if ((an_ei == H_UNDERFLOW ) && (an_ej == H_OVERFLOW)) {
00418     low += p*2; high += p*3;
00419   }
00420   if ((an_ei == H_OVERFLOW) && (an_ej == H_OVERFLOW)) {
00421     low += p*3; high += p*4;
00422   }
00423 
00424   if ((an_ej == H_UNDERFLOW) && (an_ek == H_UNDERFLOW)) {
00425     low += p*4; high += p*4 + n;
00426   }
00427   if ((an_ej == H_OVERFLOW ) && (an_ek == H_UNDERFLOW)) {
00428     low += p*4 + n; high += p*4 + n*2;
00429   }
00430   if ((an_ej == H_UNDERFLOW ) && (an_ek == H_OVERFLOW)) {
00431     low += p*4 + n*2; high += p*4 + n*3;
00432   }
00433   if ((an_ej == H_OVERFLOW) && (an_ek == H_OVERFLOW)) {
00434     low += p*4 + n*3; high += p*4 + n*4;
00435   }
00436 
00437   if ((an_ei == H_UNDERFLOW) && (an_ek == H_UNDERFLOW)) {
00438     low += p*4 + n*4; high += p*4 + n*4 + m;
00439   }
00440   if ((an_ei == H_OVERFLOW ) && (an_ek == H_UNDERFLOW)) {
00441     low += p*4 + n*4 + m; high += p*4 + n*4 + m*2;
00442   }
00443   if ((an_ei == H_UNDERFLOW ) && (an_ek == H_OVERFLOW)) {
00444     low += p*4 + n*4 + m*2; high += p*4 + n*4 + m*3;
00445   }
00446   if ((an_ei == H_OVERFLOW) && (an_ek == H_OVERFLOW)) {
00447     low += p*4 + n*4 + m*3; high += p*4 + n*4 + m*4;
00448   }
00449 }
00450 
00451 TEMPLATE___
00452 Index CLASS___::computeSummary( Index which, Index low, Index high) {
00453   Index n = partition_X().bin_count();
00454   Index m = partition_Y().bin_count();
00455   Index p = partition_Z().bin_count();
00456   Index i;
00457   bins_[(n+2)*(m+2)*(p+2)+which].reset();
00458   for (i=low;i<high;i++)
00459     bins_[(n+2)*(m+2)*(p+2)+which].add(bins_[i]);
00460   return which;
00461 }
00462 
00463 TEMPLATE___
00464   Index CLASS___::summaryOUInfo(Extra_Index an_ei,Extra_Index an_ej,
00465                                 Extra_Index an_ek) {
00466   int outRangeIndexes = 0;
00467   Index n = partition_X().bin_count();
00468   Index m = partition_Y().bin_count();
00469   Index p = partition_Z().bin_count();
00470   Index retval = 0; 
00471   Index low;
00472   Index high;
00473   if (an_ei != H_IN_RANGE) outRangeIndexes++;
00474   if (an_ej != H_IN_RANGE) outRangeIndexes++;
00475   if (an_ek != H_IN_RANGE) outRangeIndexes++;
00476   // outRangeIndexes: 1->face, 2->edge, 3->corner
00477   switch (outRangeIndexes) {
00478   case 1: // Faces: compute sums over the faces and put in additional bins
00479     retval = (n+2)*(m+2)*(p+2);
00480     faceBoundary(an_ei,an_ej,an_ek,low,high);
00481     if (an_ei == H_UNDERFLOW) retval += computeSummary(0,low,high);
00482     if (an_ei == H_OVERFLOW)  retval += computeSummary(1,low,high);
00483     if (an_ej == H_UNDERFLOW) retval += computeSummary(2,low,high);
00484     if (an_ej == H_OVERFLOW)  retval += computeSummary(3,low,high);
00485     if (an_ek == H_UNDERFLOW) retval += computeSummary(4,low,high);
00486     if (an_ek == H_OVERFLOW)  retval += computeSummary(5,low,high);
00487     break;
00488   case 2: // Edge: compute sums over the edges and put in additional bins
00489     retval += (n+2)*(m+2)*(p+2);
00490     edgeBoundary(an_ei,an_ej,an_ek,low,high);
00491     if ((an_ei == H_UNDERFLOW) && (an_ej == H_UNDERFLOW)) 
00492       retval += computeSummary(6,low,high);
00493     if ((an_ei == H_OVERFLOW ) && (an_ej == H_UNDERFLOW))
00494       retval += computeSummary(7,low,high);
00495     if ((an_ei == H_UNDERFLOW ) && (an_ej == H_OVERFLOW)) 
00496       retval += computeSummary(8,low,high);
00497     if ((an_ei == H_OVERFLOW) && (an_ej == H_OVERFLOW)) 
00498       retval += computeSummary(9,low,high);
00499 
00500     if ((an_ej == H_UNDERFLOW) && (an_ek == H_UNDERFLOW)) 
00501       retval += computeSummary(10,low,high);
00502     if ((an_ej == H_OVERFLOW ) && (an_ek == H_UNDERFLOW)) 
00503       retval += computeSummary(11,low,high);
00504     if ((an_ej == H_UNDERFLOW ) && (an_ek == H_OVERFLOW)) 
00505       retval += computeSummary(12,low,high);
00506     if ((an_ej == H_OVERFLOW) && (an_ek == H_OVERFLOW)) 
00507       retval += computeSummary(13,low,high);
00508 
00509     if ((an_ei == H_UNDERFLOW) && (an_ek == H_UNDERFLOW)) 
00510       retval += computeSummary(14,low,high);
00511     if ((an_ei == H_OVERFLOW ) && (an_ek == H_UNDERFLOW))
00512       retval += computeSummary(15,low,high);
00513     if ((an_ei == H_UNDERFLOW ) && (an_ek == H_OVERFLOW)) 
00514       retval += computeSummary(16,low,high);
00515     if ((an_ei == H_OVERFLOW ) && (an_ek == H_OVERFLOW)) 
00516       retval += computeSummary(17,low,high);
00517 
00518    break;
00519   case 3: // Corners: return real bins
00520     retval = n*m*p+m*p*2+n*p*2+n*m*2 + p*4 + n*4 + m*4;
00521     if (an_ek ==H_UNDERFLOW) {
00522       if (an_ej == H_UNDERFLOW) {
00523         if (an_ei == H_UNDERFLOW)
00524           retval += 0;
00525         else
00526           retval += 1;
00527       } else {
00528         if (an_ei == H_UNDERFLOW)
00529           retval += 2;
00530         else
00531           retval += 3;
00532       }
00533     } else {
00534       if (an_ej == H_UNDERFLOW) {
00535         if (an_ei == H_UNDERFLOW)
00536           retval += 4;
00537         else
00538           retval += 5;
00539       } else {
00540         if (an_ei == H_UNDERFLOW)
00541           retval += 6;
00542         else
00543           retval += 7;
00544       }
00545     }
00546     break;
00547   default:
00548     HTL_ERR("Bin is in-range");
00549   }
00550   return retval; 
00551 }
00552 
00553 TEMPLATE___
00554 Index CLASS___::realOutRange(Extra_Index an_ei,Extra_Index an_ej,
00555                              Extra_Index an_ek,
00556                              Index an_i,Index an_j,Index an_k) const {
00557   int outRangeIndexes = 0;
00558   Index retval = 0;
00559   Index n = partition_X().bin_count();
00560   Index m = partition_Y().bin_count();
00561   Index p = partition_Z().bin_count();
00562   if (an_ei != H_IN_RANGE) outRangeIndexes++;
00563   if (an_ej != H_IN_RANGE) outRangeIndexes++;
00564   if (an_ek != H_IN_RANGE) outRangeIndexes++;
00565   // outRangeIndexes: 1->face, 2->edge, 3->corner
00566   switch (outRangeIndexes) {
00567   case 1: // Face
00568     retval += n*m*p; // In-range bins offset
00569     if (an_ei == H_UNDERFLOW) retval += an_j+an_k*m;
00570     else {
00571       if (an_ei == H_OVERFLOW)  retval += an_j+an_k*m + m*p;
00572       else {
00573         if (an_ej == H_UNDERFLOW) retval += an_i+an_k*n + m*p*2;
00574         else {
00575           if (an_ej == H_OVERFLOW)  retval += an_i+an_k*n + m*p*2+n*p;
00576           else {
00577             if (an_ek == H_UNDERFLOW) 
00578               retval += an_i+an_j*n + m*p*2+n*p*2;
00579             else
00580               retval += an_i+an_j*n + m*p*2+n*p*2+n*m;/* if (an_ek == H_OVERFLOW) */ 
00581           }
00582         }
00583       }
00584     }
00585     break;
00586   case 2: // Edge
00587     retval += n*m*p + (m*p+n*p+n*m)*2; // In-range bins + faces offset
00588     if (an_ei == H_UNDERFLOW) {
00589       if (an_ej == H_UNDERFLOW) retval += an_k; 
00590       else {
00591         if (an_ej == H_OVERFLOW ) retval += p*2 + an_k;
00592         else {
00593           if (an_ek == H_UNDERFLOW) 
00594             retval += (p+n)*4 + an_j;
00595           else retval += (p+n)*4 + m*2 + an_j;/* if ((an_ek == H_OVERFLOW )) */ 
00596         }
00597       }
00598     } else {
00599       if (an_ei == H_OVERFLOW ) {
00600         if (an_ej == H_OVERFLOW ) retval += p*3 + an_k;
00601         else {
00602           if (an_ej == H_UNDERFLOW) retval += p + an_k;
00603           else {
00604             if (an_ek == H_UNDERFLOW) 
00605               retval += (p+n)*4 + m + an_j;
00606             else retval += (p+n)*4 + m*3 + an_j; /* if ((an_ek == H_OVERFLOW )) */ 
00607           }
00608         }
00609       } else { 
00610         if (an_ej == H_UNDERFLOW) {
00611           if (an_ek == H_UNDERFLOW) 
00612             retval += p*4 + an_i;
00613           else 
00614             retval += p*4 + n*2 + an_i; /* if (an_ek == H_OVERFLOW ) */
00615         } else {
00616           if (an_ek == H_UNDERFLOW) 
00617             retval += p*4 + n + an_i;
00618           else 
00619             retval += p*4 + n*3 + an_i; /* if (an_ek == H_OVERFLOW ) */
00620         }
00621       }
00622     }
00623 
00624    break;
00625   case 3: // Corners
00626     //In-range bins + faces + edges offset
00627     retval += n*m*p + (m*p+n*p+n*m)*2 + (p+n+m)*4 ;
00628     if (an_ek ==H_UNDERFLOW) {
00629       if (an_ej == H_UNDERFLOW) {
00630         if (an_ei == H_UNDERFLOW)
00631           retval += 0;
00632         else
00633           retval += 1;
00634       } else {
00635         if (an_ei == H_UNDERFLOW)
00636           retval += 2;
00637         else
00638           retval += 3;
00639       }
00640     } else {
00641       if (an_ej == H_UNDERFLOW) {
00642         if (an_ei == H_UNDERFLOW)
00643           retval += 4;
00644         else
00645           retval += 5;
00646       } else {
00647         if (an_ei == H_UNDERFLOW)
00648           retval += 6;
00649         else
00650           retval += 7;
00651       }
00652     }
00653     break;
00654   default:
00655     HTL_ERR("Bin is in-range");
00656   }
00657   return retval;
00658 }
00659 
00660 
00661 TEMPLATE___  
00662 I_Bin & CLASS___::i_any_bin ( I_Bin_Location &aLoc ) const {
00663   if (aLoc.size() >=  (unsigned long) dim() ) {
00664     if ((aLoc[0] >= 0 ) && (aLoc[1]  >= 0)&& (aLoc[2]  >= 0))
00665       // In-range bin
00666       return i_bin(aLoc);
00667     else {
00668       Extra_Index an_ei = H_IN_RANGE;
00669       Extra_Index an_ej = H_IN_RANGE;
00670       Extra_Index an_ek = H_IN_RANGE;
00671       if (aLoc[0] == I_Histo::UNDERFLOW_BIN)
00672         an_ei = H_UNDERFLOW;
00673       if (aLoc[0] == I_Histo::OVERFLOW_BIN)
00674         an_ei = H_OVERFLOW;
00675       if (aLoc[1] == I_Histo::UNDERFLOW_BIN)
00676         an_ej = H_UNDERFLOW;
00677       if (aLoc[1] == I_Histo::OVERFLOW_BIN)
00678         an_ej = H_OVERFLOW;
00679       if (aLoc[2] == I_Histo::UNDERFLOW_BIN)
00680         an_ek = H_UNDERFLOW;
00681       if (aLoc[2] == I_Histo::OVERFLOW_BIN)
00682         an_ek = H_OVERFLOW;
00683       return i_bin (realOutRange(an_ei, an_ej,an_ek,aLoc[0],aLoc[1],aLoc[2]));
00684     }
00685   } else {
00686     HTL_ERR("1st argument is not a 3D-histo interface.");
00687     return (I_Bin &) bin(0,0,0);
00688   }     
00689 }
00690 
00691 #undef CLASS___
00692 #undef TEMPLATE___
00693 
00694 


Anaphe documentation generated by Doxygen (www.doxygen.org)