/// Class to find information in the ODB /// By now, look at DCCs (active) and FEMs (enabled) /// to set the corresponding DQ flag when masked /// Added also a check to flag if TPC is out of global DAQ /// Class following the structure of ITPCGas by Blair Jamieson /// Lorena Escudero (loressa@ific.uv.es) #include "ITPCODBInfo.hxx" #include "ISlowControlMySQLInterface.hxx" #include "IOARuntimeParameters.hxx" #include #include #include #include #include "ISlowControlDatabase.hxx" #include "gscUtils.hxx" #include "ISlowControlMySQLInterface.hxx" #include "IOARuntimeParameters.hxx" #include #include #include #include #include #include #include "ISlowControlDatabase.hxx" #include "gscUtils.hxx" ///-------------------------------------------------------------------- /// build new reading within a especific time interval ITPCODBInfo::ITPCODBInfo( long timemin, long timemax ){ fTime = timemin; fStartTime = timemin; fEndTime = timemax; fDebug = false; fTimeStamp = 0x0; Init(); } void ITPCODBInfo::Init(){ // set up the field names SetupFieldNames(); // read the information Read(); } ///-------------------------------------------------------------------- /// Setup vectors of strings for field names /// that will be querried in the database void ITPCODBInfo::SetupFieldNames(){ fOUT_names0.clear(); fOUT_names1.clear(); fDCC_names.clear(); fFEM_names.clear(); fOUT_names0.push_back("TripTBEBActive"); fOUT_names1.push_back("GRequested_transitions"); fDCC_names.push_back("DCCActive"); fFEM_names.push_back("FEMEnable_1"); fFEM_names.push_back("FEMEnable_2"); fFEM_names.push_back("FEMEnable_3"); fFEM_names.push_back("FEMEnable_4"); fFEM_names.push_back("ExpertDCC"); fFEM_names.push_back("DCCId"); return; } ///------------------------------------------------------------------------ /// Compute the DCC Status: find the DCC not active and set the flag for corresponding TPC long ITPCODBInfo::ComputeDCCStatus(int fDCCActive){ //method to compute the real flag (in new flags schema) //adding the ODB flag (8th flag) for each TPC with any DCC not active long status=0; int diff; diff = 262143-fDCCActive; for (int x=17; x>=0; x--){ //it is possible than more than one DCC is not active, in different TPCs int aux; aux = diff - pow(2,x); if (aux>0 || aux==0){//the value is included in diff if(x>11){ //This is TPC1 status += 32768 ;//ODB flag (8th flag) for TPC1 }else{ if(x>5){//This is TPC3 status += 2147483648; } else{//This is TPC2 status += 8388608; } } diff = diff - pow(2,x); if(diff==0) return status; } } return status; } long ITPCODBInfo::ComputeFEMStatus(){ //method to compute the real flag (in new flags schema) //adding the ODB flag (8th flag) for each TPC with any FEM disabled //use bool variables to avoid adding same flag twice bool idTPC1=false; bool idTPC2=false; bool idTPC3=false; //we need to loop over the vector of DCC Id with a FEM disabled for (std::vector< int >::iterator it = fDCCIdFEM.begin(); it != fDCCIdFEM.end() ; ++it){ if (*it<6) idTPC2 = true; //DCC0-5 for TPC2 if(*it>5 && *it<12) idTPC3 = true; //DCC6-11 for TPC3 if(*it>11 && *it<18) idTPC1 = true; //DCC12-17 for TPC1 } long status=0; if(idTPC1) status+=32768; //ODB flag for TPC1 if(idTPC2) status+=8388608; //ODB flag for TPC2 if(idTPC3) status+=2147483648; //ODB flag for TPC3 if (status ==0 ) std::cout << "Problem with DCC id vector" << std::endl; return status; } long ITPCODBInfo::ComputeTotalStatus(){ //method to compute the real flag (in new flags schema) //taking into account both DCC and FEM flags long totalstatus=0; //use bool variables to avoid adding same flag twice bool idTPC1=false; bool idTPC2=false; bool idTPC3=false; long auxDCC = fDCCStatus; long auxFEM = fFEMStatus; if (fDCCStatus==fFEMStatus ) totalstatus = fDCCStatus; //if we have the same flag then we do not need to do anything else else { if (fDCCStatus==0 ) totalstatus = fFEMStatus; else { if (fFEMStatus==0 ) totalstatus = fDCCStatus; else {//separate in TPCs if(auxDCC>=2147483648){ idTPC3 = true; auxDCC -=2147483648 ; } if(auxDCC>=8388608){ idTPC2 = true; auxDCC -= 8388608; } if(auxDCC==32768) idTPC1=true; if(auxFEM>=2147483648){ idTPC3 = true; auxFEM -=2147483648 ; } if(auxFEM>=8388608){ idTPC2 = true; auxFEM -= 8388608; } if(auxFEM==32768) idTPC1=true; //sum contributions from both DCC and FEM if(idTPC1) totalstatus+=32768; //ODB flag for TPC1 if(idTPC2) totalstatus+=8388608; //ODB flag for TPC2 if(idTPC3) totalstatus+=2147483648; //ODB flag for TPC3 } } } return totalstatus; } std::vector > > ITPCODBInfo::QueryGetField(int time, const char *table_name, std::vector table_fields){ //ISlowControlDatabase::Get().QueryGetFieldNoCache was giving problems for DCCActive... std::vector > > result; std::stringstream command; int nrows = 250; //250 rows starting from time command <<"SELECT _i_time, "; // add the requested fields for(unsigned int i = 0; i < table_fields.size(); i++){ command << table_fields[i] << ","; } command <<" ABS(_i_time-"<< time <<") as distance " << " FROM " << table_name << " WHERE _i_time - "<< time <<" > 0 " << " ORDER BY distance limit " << nrows << ";"; //initialize server // Get environment variables to define which database to query GSC information. TString url = getenv("ENV_GSC_TSQL_URL"); TString user = getenv("ENV_GSC_TSQL_USER"); TString pswd = getenv("ENV_GSC_TSQL_PSWD"); // Use handy ROOT class to interpret URL. TUrl url_obj(url.Data()); std::string User = std::string(user.Data()); std::string Pswd = std::string(pswd.Data()); int port = url_obj.GetPort(); if(port == 0) // Probably no port set; use default 3306. port = 3306; ISlowControlMySQLInterface *fGSCInterface = new ISlowControlMySQLInterface(user.Data(), pswd.Data(), url_obj); // Open up the ODB database connection. // Catch the exception if this fails, since this might not be important to some people. url_obj.SetFile("t2kodb"); COMETVerbose("Initializing MySQL ODB Database."); ISlowControlMySQLInterface *fODBInterface; try{ fODBInterface = new ISlowControlMySQLInterface(user.Data(), pswd.Data(), url_obj); }catch (COMET::ELostGSCDatabaseConnection e) { COMETLog("ODB Database not available. " << "Attempting to access ODB information will cause exception. "); fODBInterface = 0; } TSQLServer *fServer; fServer = TSQLServer::Connect(url_obj.GetUrl(),User.c_str(),Pswd.c_str()); //handle result TSQLResult* sqlresult = fServer->Query(command.str().c_str()); if(!sqlresult) return result; TSQLRow* row = sqlresult->Next(); while(row){ unsigned int colnum = (unsigned int)sqlresult->GetFieldCount(); if(colnum != table_fields.size()+2){ COMETError("QueryGetField: input fields doesn't match database result."); continue; } std::vector current_fields; std::pair > current_data; current_data.first = atof(row->GetField(0)); for(unsigned int counter=1; counter < colnum; counter++){ int value = atoi(row->GetField(counter)); current_fields.push_back(value); } current_data.second = current_fields; result.push_back(current_data); delete row; row = sqlresult->Next(); } fServer->Close(); delete sqlresult; return result; } std::vector > > ITPCODBInfo::QueryGetField(int time, const char *table_name, std::vector table_fields, int nrows){ //instead of calling ISlowControlDatabase::Get().QueryGetFieldNoCache, which returns a vector of double values //create own function to query the database, because we need to get a char or string value for FEMEnable = 'y' or 'n' //maybe move to ISlowControlMySQLInterface.cxx at some point... std::vector > > result; std::stringstream command; command <<"SELECT _i_time, "; // add the requested fields for(unsigned int i = 0; i < table_fields.size(); i++){ command << table_fields[i] << ","; } command <<" ABS(_i_time-"<< time <<") as distance " << " FROM " << table_name << " WHERE _i_time - "<< time <<" > 0 " << " ORDER BY distance limit " << nrows << ";"; //initialize server // Get environment variables to define which database to query GSC information. TString url = getenv("ENV_GSC_TSQL_URL"); TString user = getenv("ENV_GSC_TSQL_USER"); TString pswd = getenv("ENV_GSC_TSQL_PSWD"); // Use handy ROOT class to interpret URL. TUrl url_obj(url.Data()); std::string User = std::string(user.Data()); std::string Pswd = std::string(pswd.Data()); int port = url_obj.GetPort(); if(port == 0) // Probably no port set; use default 3306. port = 3306; ISlowControlMySQLInterface *fGSCInterface = new ISlowControlMySQLInterface(user.Data(), pswd.Data(), url_obj); // Open up the ODB database connection. // Catch the exception if this fails, since this might not be important to some people. url_obj.SetFile("t2kodb"); COMETVerbose("Initializing MySQL ODB Database."); ISlowControlMySQLInterface *fODBInterface; try{ fODBInterface = new ISlowControlMySQLInterface(user.Data(), pswd.Data(), url_obj); }catch (COMET::ELostGSCDatabaseConnection e) { COMETLog("ODB Database not available. " << "Attempting to access ODB information will cause exception. "); fODBInterface = 0; } TSQLServer *fServer; fServer = TSQLServer::Connect(url_obj.GetUrl(),User.c_str(),Pswd.c_str()); //handle result TSQLResult* sqlresult = fServer->Query(command.str().c_str()); if(!sqlresult) return result; TSQLRow* row = sqlresult->Next(); while(row){ unsigned int colnum = (unsigned int)sqlresult->GetFieldCount(); if(colnum != table_fields.size()+2){ COMETError("QueryGetField: input fields doesn't match database result."); continue; } std::vector current_fields; std::pair > current_data; current_data.first = atof(row->GetField(0)); for(unsigned int counter=1; counter < colnum; counter++){ std::string value = std::string(row->GetField(counter)); current_fields.push_back(value); } current_data.second = current_fields; result.push_back(current_data); delete row; row = sqlresult->Next(); } fServer->Close(); delete sqlresult; return result; } bool ITPCODBInfo::CheckFEMs(){ //method to check if any FEM is disabled (value = 'n') bool status = false; fDCCIdFEM.clear(); for(int j=0; j<4; j++){ std::string value = std::string(fFEM_vec0[ fFEM_idx ].second[j]); size_t found=0; found=value.find("n"); size_t endpos =std::string::npos; if(found != endpos) { status = true; int id=atoi((fFEM_vec0[ fFEM_idx ].second[5]).c_str()); //std::cout << "value DCC: " << id << "FEM: " << j+1 <<" not enabled " << "for time=" << long(fFEM_vec0[ fFEM_idx ].first) << std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec1[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec1[ fFEM_idx ].second[5]).c_str()); //std::cout << "value DCC: " << id << "FEM: " << j+1 <<" = " << value << "for time=" << long(fFEM_vec1[ fFEM_idx ].first) << std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec2[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec2[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec2[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec3[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec3[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec3[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec4[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec4[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec4[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec5[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec5[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec5[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec6[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec6[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec6[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec7[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec7[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec7[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec8[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec8[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec8[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec9[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec9[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec9[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec10[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec10[ fFEM_idx ].second[5]).c_str()); //std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec10[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec11[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec11[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec11[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec12[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec12[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec12[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec13[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec13[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec13[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec14[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec14[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec14[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec15[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec15[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec15[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec16[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec16[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec16[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } value = std::string (fFEM_vec17[ fFEM_idx ].second[j]); found=0; found=value.find("n"); if(found != endpos) { status = true; int id=atoi((fFEM_vec17[ fFEM_idx ].second[5]).c_str()); // std::cout << "value DCC: " << id << "FEM: " << j <<" = " << value << "for time=" << long(fFEM_vec17[ fFEM_idx ].first)<< std::endl; fDCCIdFEM.push_back(id); } } return status ; } void ITPCODBInfo::Read(){ SetupTimeStamp(); fDCCActive = 0; fBEBActive = 0; fTPClocal = 0; fDCCStatus = 0; fFEMStatus =0; fStatus = true; fTotalStatus = 0; // Check if we need to read more data // from slow control database CheckReadDB(); // Get index into each of the vectors of database query // results for the current time UpdateVectorTimeIdx(); if((fOUT_isok0 == true) && (fOUT_isok1 == true) ){ fBEBActive = fOUT_vec0[ fOUT_idx0 ].second[0];//The value for TripTBEBActive //std::cout << "fBEBActive=" << fBEBActive << std::endl; fTPClocal = fOUT_vec1[ fOUT_idx1 ].second[0];//The value for GRequested_transitions //std::cout << "fTPClocal = " << fTPClocal << std::endl; //Check if TPC is out of global DAQ. if((int(fBEBActive&128) !=0) && (fTPClocal != 2) ){//TPC in global. Then check the DCCs and FEMs //std::cout << " TPC in global " << std::endl; if ( fDCC_isok == true ){ // Read Flows for DCC Active values fDCCActive = fDCC_vec[ fDCC_idx ].second[0]; //If DCCActive value = 262143, then good status if (fDCCActive==262143 ) { fDCCStatus = 0; //otherwise find the DCC not active and set the flag for the corresponding TPC } else { fDCCStatus = ComputeDCCStatus(fDCCActive); } } bool femstatus= false; if ( fFEM_isok == true ){ // Read Flows for FEM values femstatus = CheckFEMs(); if (femstatus){ fFEMStatus = ComputeFEMStatus(); } else fFEMStatus = 0; } if(fDCCStatus==0 && fFEMStatus ==0) fStatus = true; else fStatus = false; if(fStatus) fTotalStatus = 0; else fTotalStatus = ComputeTotalStatus(); } else {//TPC out of global. Then set the status with ODB flag for all TPCs std::cout << " TPC out of global DAQ " << std::endl; fStatus = false; fTotalStatus = long( pow(2,15) + pow(2,23) + pow(2,31) ); } } if (fDebug){ // Time check: long db_time = (long)ISlowControlDatabase::Get().QueryShowField(fTime,"tpcgasplc_plca","_i_time"); std::cout << ""< long( fOUT_vec0[ fOUT_vec0.size()-2 ].first ) || fTime > long( fOUT_vec1[ fOUT_vec1.size()-2 ].first ) ){ // std::cout<<" About to Read_OUT"< long( fDCC_vec[ fDCC_vec.size()-2 ].first ) ){ // std::cout<<" About to Read_DCC"< long( fFEM_vec0[ fFEM_vec0.size()-2 ].first )|| fFEM_vec1.size() <= 2 || fTime > long( fFEM_vec1[ fFEM_vec1.size()-2 ].first )|| fFEM_vec2.size() <= 2 || fTime > long( fFEM_vec2[ fFEM_vec2.size()-2 ].first )|| fFEM_vec3.size() <= 2 || fTime > long( fFEM_vec3[ fFEM_vec3.size()-2 ].first )|| fFEM_vec4.size() <= 2 || fTime > long( fFEM_vec4[ fFEM_vec4.size()-2 ].first )|| fFEM_vec5.size() <= 2 || fTime > long( fFEM_vec5[ fFEM_vec5.size()-2 ].first )|| fFEM_vec6.size() <= 2 || fTime > long( fFEM_vec6[ fFEM_vec6.size()-2 ].first )|| fFEM_vec7.size() <= 2 || fTime > long( fFEM_vec7[ fFEM_vec7.size()-2 ].first )|| fFEM_vec8.size() <= 2 || fTime > long( fFEM_vec8[ fFEM_vec8.size()-2 ].first )|| fFEM_vec9.size() <= 2 || fTime > long( fFEM_vec9[ fFEM_vec9.size()-2 ].first )|| fFEM_vec10.size() <= 2 || fTime > long( fFEM_vec10[ fFEM_vec10.size()-2 ].first )|| fFEM_vec11.size() <= 2 || fTime > long( fFEM_vec11[ fFEM_vec11.size()-2 ].first )|| fFEM_vec12.size() <= 2 || fTime > long( fFEM_vec12[ fFEM_vec12.size()-2 ].first )|| fFEM_vec13.size() <= 2 || fTime > long( fFEM_vec13[ fFEM_vec13.size()-2 ].first )|| fFEM_vec14.size() <= 2 || fTime > long( fFEM_vec14[ fFEM_vec14.size()-2 ].first )|| fFEM_vec15.size() <= 2 || fTime > long( fFEM_vec15[ fFEM_vec15.size()-2 ].first )|| fFEM_vec16.size() <= 2 || fTime > long( fFEM_vec16[ fFEM_vec16.size()-2 ].first )|| fFEM_vec17.size() <= 2 || fTime > long( fFEM_vec17[ fFEM_vec17.size()-2 ].first ) ){ // std::cout<<" About to Read_FEM"<= long( (fOUT_vec0[0].first) )) { if(fDebug) std::cout << "Time = " << fTime << "and entry time = " << long( (fOUT_vec0[0].first) ) << std::endl; fOUT_idx0 = 0; fOUT_isok0 = true; } } else { for (int i=0; i= long( (fOUT_vec0[i].first) ) && fTime < long( (fOUT_vec0[i+1].first) ) ) { if(fDebug) std::cout << "Time = " << fTime << "and entry time = " << long( (fOUT_vec0[i].first) ) << std::endl; fOUT_idx0 = i; fOUT_isok0 = true; break; } } } // Find index for current time for TPC out of global DAQ (second check) fOUT_isok1 = false; if ( fOUT_vec1.size()==1 ){ if ( fTime >= long( (fOUT_vec1[0].first) )) { fOUT_idx1 = 0; fOUT_isok1 = true; } } else { for (int i=0; i= long( (fOUT_vec1[i].first) ) && fTime < long( (fOUT_vec1[i+1].first) ) ) { fOUT_idx1 = i; fOUT_isok1 = true; break; } } } // Find index for current time for DCC fDCC_isok = false; if ( fDCC_vec.size()==1 ){ fDCC_idx = 0; fDCC_isok = true; } else { for (int i=0; i= long( (fDCC_vec[i].first) ) && fTime < long( (fDCC_vec[i+1].first) ) ) { fDCC_idx = i; fDCC_isok = true; break; } } } // Find index for current time for FEM fFEM_isok = false; if ( fFEM_vec0.size()==1 ){ fFEM_idx = 0; fFEM_isok = true; } else { for (int i=0; i= long( (fFEM_vec0[i].first) ) && fTime < long( (fFEM_vec0[i+1].first) ) ) { fFEM_idx = i; fFEM_isok = true; break; } } } return; }