//---------------------------------------------------------------------------
LogFile::LogFile() : 
  bufferPos_(0),
  bufferSize_(0),
  bufferDataTTA_(60 * 1000000u), // 60 seconds
  lastFlushTime_(gettimeofday()),
  rotationThreshold_(1024 * 1024),
  rotatedFileCount_(10),
  codePage_(CP_OEMCP)
{
//  enabledLevels_(1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512),
  memset(enabledLevels_,0,sizeof(enabledLevels_));
  debugLevel(0,1);
  debugLevel(1,1);
  debugLevel(2,1);
  debugLevel(3,1);
  debugLevel(4,1);
  debugLevel(5,1);
  debugLevel(6,1);
  debugLevel(7,1);
  debugLevel(8,1);
  debugLevel(9,1);
//#ifndef NDEBUG
//  debugLevel(128,1);
//#endif
}
//=============================================================================
//  Match vertices by distance
//=============================================================================
void  VertexCompare::matchByDistance(std::vector<LHCb::RecVertex>& vertfull, 
                                     std::vector<LHCb::RecVertex>& verthalf, std::vector<int>& link) {

  if (verthalf.size()>vertfull.size() && debugLevel()) debug() << "half.size > full.size" << endmsg;
  for(int imc=0; imc<(int)vertfull.size(); imc++) {
//     if ( mcpvvec[imc].indexRecPVInfo  > -1) continue;
    double mindist = 999999.;
    int indexrec = -1;
    for(int irec=0; irec<(int)verthalf.size(); irec++){
      if (std::count(link.begin(), link.end(), irec)!=0) continue;
      double dist = fabs(verthalf.at(irec).position().z()-vertfull.at(imc).position().z());
      if(dist < mindist) {
        mindist = dist;
        indexrec = irec;
      }
    }
    if(debugLevel()) debug() << "original vertex " << imc << " linked to " << indexrec << " half vertex." << endmsg;
    link.push_back(indexrec);
  }

  for(int imc=0; imc<(int)vertfull.size(); imc++) {
    int count = std::count(link.begin(), link.end(), imc);
    if (count >1 && debugLevel()) debug() << "linked twice to vertex " << imc << endmsg;
  }
}
//---------------------------------------------------------------------------
LogFile & LogFile::setDebugLevels(const utf8::String & levels)
{
  utf8::String minus("-");
  for( intptr_t i = enumStringParts(levels) - 1; i >= 0; i-- ){
    utf8::String s(stringPartByNo(levels,i));
    Mutant level(s);
    try {
      level.changeType(mtInt);
    }
    catch( ExceptionSP & e ){
      if( dynamic_cast<utf8::EStr2Scalar *>(e.ptr()) == NULL ) throw;
    }
    if( s.strstr(minus).eos() ){
      debugLevel(level,1);
    }
    else {
      debugLevel(-(intptr_t) level,0);
    }
  }
  return *this;
}
    void cleanup_s()
    {
      // If we're supposed to print out statistics, do so now.
      
      if (printStats())
        statistics_s.print(pinfo, reductionFilter_s);

      // Close the log file, if necessary.

      logMessages(0);

      // Turn off all POOMA streams.

      infoMessages(false);
      warnMessages(false);
      errorMessages(false);
      debugLevel(Inform::off);
    }
//---------------------------------------------------------------------------
LogFile & LogFile::setAllDebugLevels(intptr_t value)
{
  for( intptr_t i = sizeof(enabledLevels_) * 8 - 1; i >= 0; i-- )
    debugLevel(i,value);
  return *this;
}
//---------------------------------------------------------------------------
LogFile & LogFile::internalLog(uintptr_t level,const utf8::String::Stream & stream)
{
  if( debugLevel(level) ){
    uint64_t ct = getlocaltimeofday();
    struct timeval tv = time2Timeval(ct);
    struct tm t = time2tm(timeval2Time(tv));
    bool post = false;
    try {
      char buf[128], buf2[128 * sizeof(wchar_t)];
      intptr_t a, l;
#if HAVE_SNPRINTF
#define SNPRINTF snprintf
#elif HAVE__SNPRINTF
#define SNPRINTF _snprintf
#endif
      if( currentFiber() != NULL )
        a = SNPRINTF(
          buf,
          sizeof(buf),
          "%02u.%02u.%04u %02u:%02u:%02u.%06ld (%u.%"PRIxPTR",%u): ",
          t.tm_mday,
          t.tm_mon + 1,
          t.tm_year + 1900,
          t.tm_hour,
          t.tm_min,
          t.tm_sec,
          tv.tv_usec,
          getpid(),
          uintptr_t(currentFiber()),
          (unsigned int) level
        );
      else
        a = SNPRINTF(
          buf,
          sizeof(buf),
          "%02u.%02u.%04u %02u:%02u:%02u.%06ld (%u,%u): ",
          t.tm_mday,
          t.tm_mon + 1,
          t.tm_year + 1900,
          t.tm_hour,
          t.tm_min,
          t.tm_sec,
          tv.tv_usec,
          getpid(),
          (unsigned int) level
        );
#undef SNPRINTF
      if( a == -1 ){
        int32_t err = errno;
        newObjectV1C2<Exception>(err,__PRETTY_FUNCTION__)->throwSP();
      }
      utf8::utf8s2mbcs(codePage_,buf2,sizeof(buf2),buf,sizeof(buf));
      l = utf8::utf8s2mbcs(codePage_,NULL,0,stream.plane(),stream.count());
      if( a < 0 || l < 0 ){
        int32_t err = errno;
        newObjectV1C2<Exception>(err,__PRETTY_FUNCTION__)->throwSP();
      }
      if( codePage_ == CP_UNICODE ) a *= sizeof(wchar_t);
      AutoLock<FiberWriteLock> lock(mutex_);
      resume();
      AutoLock<LiteWriteLock> lock2(threadReadWriteLock_);
      uintptr_t bufferSize = bufferSize_;
      while( bufferSize < bufferPos_ + a + l ) bufferSize = (bufferSize << 1) + (bufferSize == 0);
      buffer_.realloc(bufferSize);
      bufferSize_ = bufferSize;
      memcpy(buffer_.ptr() + bufferPos_,buf2,a);
      utf8::utf8s2mbcs(codePage_,buffer_.ptr() + bufferPos_ + a,l,stream.plane(),stream.count());
      bufferPos_ += a + l;
      post = bufferPos_ - a - l == 0 || bufferPos_ >= getpagesize() * 16u || gettimeofday() - lastFlushTime_ >= bufferDataTTA_;
    }
    catch( ExceptionSP & e ){
      exceptionStdErrorToSyslog(e);
//      fprintf(stderr,"%s %d\n",__FILE__,__LINE__); fflush(stderr);
    }
    if( post ) bufferSemaphore_.post();
  }
  return *this;
}
Beispiel #7
0
SQLRETURN SQL_API SQLTables(SQLHSTMT StatementHandle,
			    SQLCHAR * CatalogName,
			    SQLSMALLINT NameLength1,
			    SQLCHAR * SchemaName,
			    SQLSMALLINT NameLength2,
			    SQLCHAR * TableName,
			    SQLSMALLINT NameLength3,
			    SQLCHAR * TableType, SQLSMALLINT NameLength4)
{
	hStmt_T *stmt = (hStmt_T *) StatementHandle;
	char *schema = NULL, *table = NULL, *type = NULL, *sql_end = NULL;
	char sql[1024] = "";
	SQLRETURN status;
	ir_T *ir;
	ar_T *ar;

	if (ENABLE_TRACE) {
		ood_log_message(stmt->dbc, __FILE__, __LINE__,
				TRACE_FUNCTION_ENTRY, (SQLHANDLE) stmt, 0, "");
	}
	ood_clear_diag((hgeneric *) stmt);

	if (SchemaName && !*SchemaName
	    && TableName && !*TableName
	    && CatalogName
	    && !strcmp((const char *)CatalogName, SQL_ALL_CATALOGS)) {
		/*
		 * This can never return any inormation, but there needs to
		 * be a query, so use one which will never return anything
		 */
		strcpy(sql,
		       "SELECT NULL,NULL,NULL,NULL,NULL FROM DUAL WHERE ROWNUM<0");
	} else if (TableName && !*TableName && SchemaName
		   && !strcmp((const char *)SchemaName, SQL_ALL_SCHEMAS)) {
		/*
		 * All schemas
		 */
		strcpy(sql,
		       "SELECT DISTINCT NULL,OWNER,NULL,NULL,NULL FROM ALL_CATALOG");
	} else if (SchemaName && !*SchemaName
		   && TableName && !*TableName
		   && TableType
		   && !strcmp((const char *)TableType, SQL_ALL_TABLE_TYPES)) {
		/*
		 * All table types 
		 */
		strcpy(sql,
		       "SELECT DISTINCT NULL,NULL,NULL,TABLE_TYPE,NULL FROM ALL_CATALOG");
	} else {
		schema = ood_xtoSQLNTS(SchemaName, NameLength2);
		table = ood_xtoSQLNTS(TableName, NameLength3);
		type = ood_xtoSQLNTS(TableType, NameLength4);

		ood_sqltables_construct_sql(stmt, sql, schema, table, type,
					    sql_end, 0);

		if (debugLevel() > 2) {
			fprintf(stderr,
				"SQLTables schema [%s][%d], table [%s][%d], type [%s][%d] SQL [%s]\n",
				schema, NameLength2, table, NameLength3, type,
				NameLength4, sql);
			fprintf(stderr,
				"schema [0x%.8lx] SchemaName [0x%.8lx] NameLength2 [%d]\n",
				(long)schema, (long)SchemaName, NameLength2);
		}
		if (schema && (schema != (char *)SchemaName))	/*malloc'd */
			ORAFREE(schema);
		if (table && (table != (char *)TableName))	/*malloc'd */
			ORAFREE(table);
		if (type && (type != (char *)TableType))	/*malloc'd */
			ORAFREE(type);
	}

	ood_mutex_lock_stmt(stmt);
	status = ood_driver_prepare(stmt, (unsigned char *)sql);
	status |= ood_driver_execute(stmt);

	/* Clear old data out of stmt->current_ir so it can be rebound.
	   The data in stmt->current_ar must not be touched, since it
	   may contain already bound ODBC columns. */

	ood_ir_array_reset(stmt->current_ir->recs.ir,
			   stmt->current_ir->num_recs, stmt->current_ir);

	/*
	 * Now we have to set up the columns for retrieval
	 */
	if (SQL_SUCCESS != ood_alloc_col_desc(stmt, 5, stmt->current_ir,
					      stmt->current_ar)) {
		ood_mutex_unlock_stmt(stmt);
		if (ENABLE_TRACE) {
			ood_log_message(stmt->dbc, __FILE__, __LINE__,
					TRACE_FUNCTION_EXIT, (SQLHANDLE) NULL,
					SQL_ERROR, "");
		}
		return SQL_ERROR;
	}

	ir = stmt->current_ir->recs.ir;
	ar = stmt->current_ar->recs.ar;

	/* stmt->current_ir->num_recs is equal to the allocated size of the
	   ir and ar arrays. Shouldn't expect it to record the number of
	   bound parameters.  
	   stmt->current_ir->num_recs=5; */

	/*
	 * Col 0 is bookmark, not implemented yet at all
	 */
	ir++, ar++;

	/*
	 * Col 1 is TABLE_CAT, varchar, always NULL
	 */
	status |= ood_assign_ir(ir, SQLT_STR, 2, 0,
				ocistr_sqlnts, ocistr_sqlnts);
	ar->data_type = ar->concise_type = SQL_C_CHAR;
	ar->display_size = 1;
	ar->octet_length = ar->length = 30;
	ar->nullable = SQL_NULLABLE;
	strcpy((char *)ar->column_name, "TABLE_CAT");
	status |= ood_driver_define_col(ir);
	ir++, ar++;

	/* 
	 * Col 2 is TABLE_SHEM, varchar
	 */
	status |= ood_assign_ir(ir, SQLT_STR, ORACLE_MAX_SCHEMA_LEN + 1, 0,
				ocistr_sqlnts, ocistr_sqlnts);
	ar->data_type = ar->concise_type = SQL_C_CHAR;
	ar->display_size = ORACLE_MAX_SCHEMA_LEN;
	ar->octet_length = ar->length = ORACLE_MAX_SCHEMA_LEN + 1;
	ar->nullable = SQL_NO_NULLS;
	strcpy((char *)ar->column_name, "TABLE_SCHEM");
	status |= ood_driver_define_col(ir);

	ir++, ar++;

	/* 
	 * Col 3 is TABLE_NAME, varchar
	 */
	status |= ood_assign_ir(ir, SQLT_STR, ORACLE_MAX_TABLE_LEN + 1, 0,
				ocistr_sqlnts, ocistr_sqlnts);
	ar->data_type = ar->concise_type = SQL_C_CHAR;
	ar->display_size = ORACLE_MAX_TABLE_LEN;
	ar->octet_length = ar->length = ORACLE_MAX_TABLE_LEN + 1;
	ar->nullable = SQL_NO_NULLS;
	strcpy((char *)ar->column_name, "TABLE_NAME");
	status |= ood_driver_define_col(ir);

	ir++, ar++;

	/*
	 * Col 4 is TABLE_TYPE
	 */
	status |= ood_assign_ir(ir, SQLT_STR, 64, 0,
				ocistr_sqlnts, ocistr_sqlnts);
	ar->data_type = ar->concise_type = SQL_C_CHAR;
	ar->display_size = 63;
	ar->octet_length = ar->length = 64;
	ar->nullable = SQL_NO_NULLS;
	strcpy((char *)ar->column_name, "TABLE_TYPE");
	status |= ood_driver_define_col(ir);

	ir++, ar++;

	/* 
	 * Col 5 is REMARKS.
	 * This is expensive to bring back and not often used so we don't
	 * bother.
	 */
	status |= ood_assign_ir(ir, SQLT_STR, 32, 0,
				ocistr_sqlnts, ocistr_sqlnts);
	ar->data_type = ar->concise_type = SQL_C_CHAR;
	ar->display_size = 32;
	ar->octet_length = ar->length = 33;
	ar->nullable = SQL_NULLABLE;
	strcpy((char *)ar->column_name, "REMARKS");
	status |= ood_driver_define_col(ir);

	stmt->fetch_status = ood_driver_prefetch(stmt);

	ood_mutex_unlock_stmt(stmt);
	if (ENABLE_TRACE) {
		ood_log_message(stmt->dbc, __FILE__, __LINE__,
				TRACE_FUNCTION_EXIT, (SQLHANDLE) NULL, status,
				"");
	}
	return status;
}
//=============================================================================
// Main execution
//=============================================================================
StatusCode VertexCompare::execute() {
  if(msgLevel(MSG::DEBUG)) debug() << "==> Execute" << endmsg;

  std::vector<LHCb::RecVertex*> vecOfVertices1;
  std::vector<LHCb::RecVertex*> vecOfVertices2;

  bool vertices_ok = getInputVertices(vecOfVertices1, vecOfVertices2);

  std::vector<LHCb::RecVertex> fullVrt1, fullVrt2;

  if (!vertices_ok) {
    return StatusCode::SUCCESS; // return SUCCESS anyway
  }
  if (debugLevel()) debug() << 
     "  Vtx Properities       x       y       z      chi2/ndof     ntracks" 
                            << endmsg;
  // Fill reconstructed PV info
  std::vector<LHCb::RecVertex*>::iterator itRecV1;
  for(itRecV1 = vecOfVertices1.begin(); vecOfVertices1.end() != itRecV1;
               itRecV1++) {
    LHCb::RecVertex* pv;
    pv = *itRecV1;
    fullVrt1.push_back(*pv);
//     int nTracks      = pv->tracks().size();
    if (debugLevel()) debug() << m_inputVerticesName1 << endmsg;
    if (debugLevel()) debug() << "              " << pv->position().x() << "   " 
                              << pv->position().y() << "   " << pv->position().z()  
                              << "   " << pv->chi2PerDoF()  << "   " << pv->tracks().size() << endmsg;
  } // end of loop over vertices1

  std::vector<LHCb::RecVertex*>::iterator itRecV2;
  for(itRecV2 = vecOfVertices2.begin(); vecOfVertices2.end() != itRecV2;
               itRecV2++) {
    LHCb::RecVertex* pv;
    pv = *itRecV2;
    fullVrt2.push_back(*pv);
//     int nTracks      = pv->tracks().size();
    if (debugLevel()) debug() << m_inputVerticesName2 << endmsg;
    if (debugLevel()) debug() << "              " 
                              << pv->position().x() << "   " 
                              << pv->position().y() << "   " 
                              << pv->position().z()  << "   " 
                              << pv->chi2PerDoF()  << "   " 
                              << pv->tracks().size() << endmsg;
  } // end of loop over vertices2
  if (debugLevel()) debug() << "fullVrt1 size   " << fullVrt1.size() << endmsg;
  if (debugLevel()) debug() << "fullVrt2 size   " << fullVrt2.size() << endmsg;
  int size_diff = fullVrt1.size() - fullVrt2.size();
  if(m_produceHistogram) {
    plot(double(size_diff), 1001, "size_diff", -5.5, 5.5, 11);
  }
  if(m_produceNtuple) {
    Tuple myTuple_evt = nTuple(101, "PV_nTuple_evt", CLID_ColumnWiseTuple);
    myTuple_evt->column("size_diff",  double(size_diff));
    myTuple_evt->column("size_1",  double(fullVrt1.size()));
    myTuple_evt->column("size_2",  double(fullVrt2.size()));
    myTuple_evt->write();
  }
  double dx          = -99999.;
  double dy          = -99999.;
  double dz          = -99999.;
  double errx        = -99999.;
  double erry        = -99999.;
  double errz        = -99999.;
  double covxx1      = -99999.;
  double covyy1      = -99999.;
  double covzz1      = -99999.;
  double covxy1      = -99999.;
  double covxz1      = -99999.;  
  double covyz1      = -99999.;

  double covxx2      = -99999.;
  double covyy2      = -99999.;
  double covzz2      = -99999.;
  double covxy2      = -99999.;
  double covxz2      = -99999.;  
  double covyz2      = -99999.;

  int ntracks_part  = 0;
  int ntracks_part2 = 0;
  int dtracks = 0;

  std::vector<LHCb::RecVertex>::iterator fullIter;
  int oIt=0;
  std::vector<int> link;
  if (fullVrt1.size()!=0 && fullVrt2.size()!=0) matchByDistance(fullVrt1, fullVrt2, link);
  else return StatusCode::SUCCESS;
  for (fullIter=fullVrt1.begin(); fullIter!=fullVrt1.end(); fullIter++){
    LHCb::RecVertex vrtf = *fullIter;
    m_nVtx++;
    if (link.at(oIt)==-1) continue;
    Gaudi::SymMatrix3x3 covPV_part1 = vrtf.covMatrix();
    double sigx_part1 = (covPV_part1(0,0));
    double sigy_part1 = (covPV_part1(1,1));
    double sigz_part1 = (covPV_part1(2,2));
    covxx1 = sigx_part1;
    covyy1 = sigy_part1;
    covzz1 = sigz_part1;
    covxy1 = (covPV_part1(0,1));
    covxz1 = (covPV_part1(0,2));
    covyz1 = (covPV_part1(1,2));
    

    Gaudi::SymMatrix3x3 covPV_part2 = fullVrt2.at(link.at(oIt)).covMatrix();
    double sigx_part2 = (covPV_part2(0,0));
    double sigy_part2 = (covPV_part2(1,1));
    double sigz_part2 = (covPV_part2(2,2));

    covxx2 = sigx_part2;
    covyy2 = sigy_part2;
    covzz2 = sigz_part2;
    covxy2 = (covPV_part2(0,1));
    covxz2 = (covPV_part2(0,2));
    covyz2 = (covPV_part2(1,2));
    
    double x1 = vrtf.position().x();
    double y1 = vrtf.position().y();
    double z1 = vrtf.position().z();
    
    double x2 = fullVrt2.at(link.at(oIt)).position().x();
    double y2 = fullVrt2.at(link.at(oIt)).position().y();
    double z2 = fullVrt2.at(link.at(oIt)).position().z();
                
    dx = vrtf.position().x()-fullVrt2.at(link.at(oIt)).position().x();
    dy = vrtf.position().y()-fullVrt2.at(link.at(oIt)).position().y();
    dz = vrtf.position().z()-fullVrt2.at(link.at(oIt)).position().z();

    errx = sqrt(sigx_part1 + sigx_part2);
    erry = sqrt(sigy_part1 + sigy_part2);
    errz = sqrt(sigz_part1 + sigz_part2);
    ntracks_part  = vrtf.tracks().size();
    ntracks_part2 = fullVrt2.at(link.at(oIt)).tracks().size();
    dtracks = ntracks_part - ntracks_part2;

    if(m_produceHistogram) {
      plot(dx, 1021, "dx", -0.25, 0.25, 50);
      plot(dy, 1022, "dy", -0.25, 0.25, 50);
      plot(dz, 1023, "dz", -1.5, 1.5, 60);
      plot(x1, 2021, "x1", -0.25, 0.25, 50);
      plot(y1, 2022, "y1", -0.25, 0.25, 50);
      plot(z1, 2023, "z1", -100., 100., 50);
      plot(x2, 3021, "x2", -0.25, 0.25, 50);
      plot(y2, 3022, "y2", -0.25, 0.25, 50);
      plot(z2, 3023, "z2", -100., 100., 50);
      plot(std::sqrt(sigx_part1), 4011, "x err 1",0., .1, 50);
      plot(std::sqrt(sigy_part1), 4012, "y err 1",0., .1, 50);
      plot(std::sqrt(sigz_part1), 4013, "z err 1",0., .5, 50);
      plot(std::sqrt(sigx_part2), 4021, "x err 2",0., .1, 50);
      plot(std::sqrt(sigy_part2), 4022, "y err 2",0., .1, 50);
      plot(std::sqrt(sigz_part2), 4023, "z err 2",0., .5, 50);
      plot(dx/errx, 1031, "pullx", -5., 5., 50);
      plot(dy/erry, 1032, "pully", -5., 5., 50);
      plot(dz/errz, 1033, "pullz", -5., 5., 50);
      plot(double(ntracks_part) , 1041, "ntracks_part1", 0., 150., 50);
      plot(double(ntracks_part2), 1042, "ntracks_part2", 0., 150., 50);
      plot(double(dtracks), 1043, "dtracks", 0., 150., 50);
      // dz to get false vertex rate from data
      if ( vecOfVertices1.size() > 1 ) {
        for ( unsigned int i1 = 0; i1 < vecOfVertices1.size(); i1++ ) {
          for ( unsigned int i2 = 0; i2 < vecOfVertices1.size(); i2++ ) {
            if (i2 != i1) {  
              double vdz = vecOfVertices1[i1]->position().z() - vecOfVertices1[i2]->position().z();
                plot(vdz,1201,"dz vertices 1", -150.,150.,100);
            }
          }
        }        
      }
      if ( vecOfVertices2.size() > 1 ) {
        for ( unsigned int i1 = 0; i1 < vecOfVertices2.size(); i1++ ) {
          for ( unsigned int i2 = 0; i2 < vecOfVertices2.size(); i2++ ) {
            if (i2 != i1) {  
              double vdz = vecOfVertices2[i1]->position().z() - vecOfVertices2[i2]->position().z();
              plot(vdz, 1202, "dz vertices 2", -150.,150.,100);
            }
          }
        }        
      }

    }
    if(m_produceNtuple) {
      Tuple myTuple = nTuple(102, "PV_nTuple", CLID_ColumnWiseTuple);
      myTuple->column("ntracks_part",  double(ntracks_part));
      myTuple->column("ntracks_part2",  double(ntracks_part2));
      myTuple->column("dtracks", double(dtracks));
      myTuple->column("dx",       dx);
      myTuple->column("dy",       dy);
      myTuple->column("dz",       dz);
      myTuple->column("x1",       x1);
      myTuple->column("y1",       y1);
      myTuple->column("z1",       z1);
      myTuple->column("x2",       x2);
      myTuple->column("y2",       y2);
      myTuple->column("z2",       z2);
      myTuple->column("errx",     errx);
      myTuple->column("erry",     erry);
      myTuple->column("errz",     errz);
      myTuple->column("covxx1",   covxx1);
      myTuple->column("covyy1",   covyy1);
      myTuple->column("covzz1",   covzz1);
      myTuple->column("covxy1",   covxy1);
      myTuple->column("covxz1",   covxz1);
      myTuple->column("covyz1",   covyz1);
      myTuple->column("covxx2",   covxx2);
      myTuple->column("covyy2",   covyy2);
      myTuple->column("covzz2",   covzz2);
      myTuple->column("covxy2",   covxy2);
      myTuple->column("covxz2",   covxz2);
      myTuple->column("covyz2",   covyz2);

      myTuple->write();
    }
    oIt++;
  }

  return StatusCode::SUCCESS;
}