Skip to content
Snippets Groups Projects
Commit fd22dbcf authored by Jan Reher's avatar Jan Reher
Browse files

Several optimizations, includes are now linking to ProtoSoft directory (should...

Several optimizations, includes are now linking to ProtoSoft directory (should soon start doing this properly).
parent a4ebb62b
No related branches found
No related tags found
No related merge requests found
......@@ -6,11 +6,12 @@ find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../proddb-clientlib/)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/includes/)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/proddb/)
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/libs)
add_library(toolbox "toolbox.cpp" "serialListReader.h" "serialListReader.cxx")
add_library(proddbaccess "proddb/ProdDbAccess.cxx" "proddb/ProdDbAccess.h" "proddb/ProductionDatabase.cxx" "proddb/ProductionDatabase.h")
add_library(proddbaccess "proddb/ProdDbAccess.cxx" "proddb/ProdDbAccess.h" "proddb/ProductionDatabase.cxx" "proddb/ProductionDatabase.h" "proddb/ProductionDatabaseApdStorage.cxx" "proddb/ProductionDatabaseApdStorage.h")
add_executable(apdBatchSetter "apdbatchsetter.cpp")
add_executable(apdLocationSetter "apdlocationsetter.cpp")
......@@ -18,6 +19,8 @@ add_executable(apdBoxSetter "apdboxsetter.cpp")
add_executable(getLocations "getlocations.cpp")
add_executable(getU100 "getu100.cxx")
add_executable(makeSerialList "makeseriallist.cxx")
add_executable(getIrradiationDose "getirradiationstatus.cxx")
add_executable(testXmlStructure "testxmlstructure.cxx")
target_link_libraries(toolbox Qt5::Network Qt5::Core Qt5::Xml proddbaccess)
target_link_libraries(proddbaccess Qt5::Network Qt5::Core Qt5::Xml)
......@@ -25,7 +28,9 @@ target_link_libraries(proddbaccess Qt5::Network Qt5::Core Qt5::Xml)
target_link_libraries(apdBatchSetter proddbclient boost_program_options)
target_link_libraries(apdBoxSetter proddbclient boost_program_options)
target_link_libraries(getLocations proddbaccess boost_program_options)
target_link_libraries(getIrradiationDose proddbaccess boost_program_options)
target_link_libraries(getU100 proddbaccess boost_program_options)
target_link_libraries(makeSerialList toolbox)
target_link_libraries(testXmlStructure Qt5::Core Qt5::Xml)
target_link_libraries(apdLocationSetter proddbclient proddbaccess boost_program_options Qt5::Gui Qt5::Widgets)
// Basic
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
// Boost
#include <boost/program_options.hpp>
// Custom
#include "ProdDbAccess.h"
#include "toolbox.cpp"
using namespace std;
namespace po = boost::program_options;
static string fileName = "serials.dat";
int main(int argc, char* argv[]) {
if ( argc < 2 ) {
cerr << "ERROR: Missing parameters! Please provide the name of a text file containing the serials." << endl;
exit(1);
}
if ( argc > 2 ) {
cerr << "ERROR: Too many parameters! Please only provide the name of a text file containing the serials." << endl;
exit(1);
}
ProdDbAccess* _dba = new ProdDbAccess();
fileName = string(argv[1]);
vector<string> apdSerials = loadSerialsFromFileName(fileName);
for (size_t i = 0 ; i < apdSerials.size() ; i++ ) {
if (apdSerials[i].size() == 9) apdSerials[i] = "0" + apdSerials[i];
cout << "S/N: " << apdSerials[i] << " '" << _dba->getIrradiationDose(uint( stoul( apdSerials[i] ) ) ) << "'" << endl;
}
return 0;
}
/home/tau/jreher/ProtoSoft/DAQ/ApdCurves/ProductionDatabaseApdStorage.h
\ No newline at end of file
#include "ProdDbAccess.h"
#include "ProductionDatabase.h"
#include <string>
ProdDbAccess::ProdDbAccess() {
if (QCoreApplication::instance() == nullptr) {
char *argv[] = {nullptr};
int argc = sizeof(argv) / sizeof(char*) - 1;
_app = new QCoreApplication(argc,argv);
} else {
_app = QCoreApplication::instance();
}
_db = new proddb::ProductionDatabase();
}
ProdDbAccess::~ProdDbAccess() {
delete _app;
delete _db;
}
ProdDbAccess::ProdDbAccess(ProdDbAccess& other) {
_app = other._app;
_db = other._db;
}
double ProdDbAccess::vendorU100(unsigned int m_serial) {
return getDataForApd(m_serial).Gain100Voltage;
}
double ProdDbAccess::vendorUbreakthrough(unsigned int m_serial) {
return getDataForApd(m_serial).BreakthroughVoltage;
}
double ProdDbAccess::vendorDarkCurrent(unsigned int m_serial) {
return getDataForApd(m_serial).DarkCurrent;
}
unsigned int ProdDbAccess::lotNumber(unsigned int m_serial) {
return m_serial / 100000000;
}
unsigned int ProdDbAccess::waferNumber(unsigned int m_serial) {
return m_serial / 1000000 - m_serial / 100000000 * 100;
}
std::string ProdDbAccess::location(unsigned int m_serial) {
return getDataForApd(m_serial).location;
}
std::string ProdDbAccess::waferPosition(unsigned int m_serial) {
return getDataForApd(m_serial).wafer_position;
}
proddb::DbApdData ProdDbAccess::getDataForApd(unsigned int m_serial) {
if (_cachedSN != m_serial) {
std::string serial = std::to_string(m_serial);
if (m_serial < 1000000000) serial = "0" + serial;
proddb::DbApdData newItem = _db->queryManufacturerApdData(serial);
_cache = newItem;
_cachedSN = m_serial;
}
return _cache;
}
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProdDbAccess.cxx
\ No newline at end of file
#pragma once
#include "AbsDbAccess.h"
#include "ProductionDatabase.h"
#include <string>
#include "QtCore/QCoreApplication"
class ProdDbAccess : public AbsDbAccess {
public:
ProdDbAccess();
~ProdDbAccess();
ProdDbAccess(ProdDbAccess& other);
double vendorU100(unsigned int serial);
double vendorUbreakthrough(unsigned int serial);
double vendorDarkCurrent(unsigned int serial);
unsigned int lotNumber(unsigned int serial);
unsigned int waferNumber(unsigned int serial);
std::string waferPosition(unsigned int serial);
std::string location(unsigned int serial);
private:
proddb::ProductionDatabase *_db;
proddb::DbApdData _cache;
QCoreApplication *_app;
unsigned int _cachedSN = 0;
proddb::DbApdData getDataForApd(unsigned int serial);
};
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProdDbAccess.h
\ No newline at end of file
#include "ProductionDatabase.h"
#include <iostream>
#include <limits>
#include <stdexcept>
#include <unistd.h>
#include <QtXml/QDomDocument>
#include <QtXml/QDomNode>
#include <QtXml/QDomNodeList>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkAccessManager>
using namespace proddb;
ProductionDatabase::ProductionDatabase ()
: _netman ( new QNetworkAccessManager ( this ) )
, _apdDetailsApiUrl ( QString::fromUtf8 ( "https://ep1.ruhr-uni-bochum.de/endcapProductionDB/api/apd_details.php?serial=%1" ) )
, _debug ( false ) {
checkDebugMode();
}
ProductionDatabase::~ProductionDatabase() {
delete _netman;
}
void ProductionDatabase::checkDebugMode() {
const char*const envvar = getenv ( "PRODUCTIONDATABASE" );
if ( envvar != nullptr ) {
if ( std::string ( envvar ) == std::string ( "DEBUG" ) )
_debug = true;
}
}
DbApdData ProductionDatabase::queryManufacturerApdData ( const std::string& serial ) {
if ( serial.size() == 0 ) {
const DbApdData data = {
false,
std::numeric_limits< double >::quiet_NaN(),
std::numeric_limits< double >::quiet_NaN(),
std::numeric_limits< double >::quiet_NaN(),
"",
""
};
return data;
}
try {
if ( _debug )
std::cout << "Initiating network request to " << _apdDetailsApiUrl.arg ( serial.c_str() ).toUtf8().constData() << std::endl;
QNetworkReply* apddetails = _netman->get ( QNetworkRequest ( QUrl ( _apdDetailsApiUrl.arg ( serial.c_str() ) ) ) );
connect ( apddetails, SIGNAL ( finished() ), &_waitForNetwork, SLOT ( quit() ) );
_waitForNetwork.exec();
if ( _debug )
std::cout << "Done, received reply." << std::endl;
if ( apddetails->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() != 200 ) {
const QString exceptionMsg = QString::fromUtf8 ( "HTTP error while invoking Production DB Web API: The server returned HTTP status code %1." ).arg ( apddetails->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() );
throw std::runtime_error ( exceptionMsg.toUtf8().constData() );
}
QDomDocument dom;
QString errorMsg;
int errorLine;
int errorColumn;
if ( _debug )
std::cout << "Setting content of network reply to QDomDocument, verifying response..." << std::endl;
if ( !dom.setContent ( apddetails, &errorMsg, &errorLine, &errorColumn ) ) {
const QString exceptionMsg = QString::fromUtf8 ( "Error in parsing data for APD %4: %1 (line %2, column %3)" ).arg ( errorMsg ).arg ( errorLine ).arg ( errorColumn ).arg ( serial.c_str() );
throw std::runtime_error ( exceptionMsg.toUtf8().constData() );
}
if ( dom.documentElement().nodeName() != QString::fromUtf8 ( "productiondb" )
|| dom.documentElement().firstChild().nodeName() != QString::fromUtf8 ( "request" ) )
throw std::runtime_error ( "APD data has invalid format." );
QDomNode requestResult = dom.documentElement().firstChild();
if ( !requestResult.attributes().contains ( QString::fromUtf8 ( "successful" ) )
|| !requestResult.attributes().contains ( QString::fromUtf8 ( "error_number" ) ) )
throw std::runtime_error ( "APD data has invalid format." );
if ( requestResult.attributes().namedItem ( QString::fromUtf8 ( "successful" ) ).nodeValue() !=
QString::fromUtf8 ( "true" ) ) {
const QString exceptionMsg = QString::fromUtf8 ( "Server reports error %1 when querying data of APD %2:\n%3" ).arg ( requestResult.attributes().namedItem ( QString::fromUtf8 ( "error_number" ) ).nodeValue() ).arg ( serial.c_str() ).arg ( requestResult.nextSibling().firstChild().nodeValue() );
throw std::runtime_error ( exceptionMsg.toUtf8().constData() );
}
if ( _debug )
std::cout << "Response OK, extracting data..." << std::endl;
const QDomNodeList nodeListBreakthrough = dom.documentElement().elementsByTagName ( QString::fromUtf8 ( "breakthrough_voltage" ) );
if ( nodeListBreakthrough.length() != 1 )
throw std::runtime_error ( "Tag <breakthrough_voltage> missing or occuring more than once." );
const QDomNode breakthroughNode = nodeListBreakthrough.item ( 0 );
bool ok = false;
const double breakthroughVoltage = breakthroughNode.firstChild().nodeValue().toDouble ( &ok );
if ( !ok )
throw std::runtime_error ( "Error parsing break-through voltage value into double." );
const QDomNodeList nodeListGain100 = dom.documentElement().elementsByTagName ( QString::fromUtf8 ( "gain100_voltage" ) );
if ( nodeListGain100.length() != 1 )
throw std::runtime_error ( "Tag <gain100_voltage> missing or occuring more than once." );
const QDomNode gain100Node = nodeListGain100.item ( 0 );
ok = false;
const double gain100Voltage = gain100Node.firstChild().nodeValue().toDouble ( &ok );
if ( !ok )
throw std::runtime_error ( "Error parsing gain 100 voltage value into double." );
const QDomNodeList nodeListDarkCurrent = dom.documentElement().elementsByTagName ( QString::fromUtf8 ( "darkcurrent" ) );
if ( nodeListDarkCurrent.length() != 1 )
throw std::runtime_error ( "Tag <darkcurrent> missing or occuring more than once." );
const QDomNode darkCurrentNode = nodeListDarkCurrent.item ( 0 );
ok = false;
const double darkCurrent = darkCurrentNode.firstChild().nodeValue().toDouble ( &ok ) / 1e9; // Dark current stored as Nanoampere in the database
if ( !ok )
throw std::runtime_error ( "Error parsing dark current value into double." );
const QDomNodeList nodeListWaferPos = dom.documentElement().elementsByTagName ( QString::fromUtf8 ( "wafer_position" ) );
if ( nodeListWaferPos.length() != 1 )
throw std::runtime_error ( "Tag <wafer_position> missing or occuring more than once." );
const QDomNode waferPosNode = nodeListWaferPos.item ( 0 );
ok = false;
const std::string waferPos = waferPosNode.firstChild().nodeValue().toStdString();
if (waferPos.size() == 3) ok = true;
if ( !ok )
throw std::runtime_error ( "Error reading wafer position" );
const QDomNodeList nodeListLocation = dom.documentElement().elementsByTagName ( QString::fromUtf8 ( "location" ) );
if ( nodeListLocation.length() != 1 )
throw std::runtime_error ( "Tag <location> missing or occuring more than once." );
const QDomNode locationNode = nodeListLocation.item ( 0 );
ok = false;
const std::string location = locationNode.firstChild().nodeValue().toStdString();
if (location.size() > 0) ok = true;
if ( !ok )
throw std::runtime_error ( "Error reading location" );
if ( _debug )
std::cout << "Data extraction complete, got "
<< "Break-through voltage " << breakthroughVoltage << " V, "
<< "Gain 100 voltage " << gain100Voltage << " V (at room temperature), "
<< "Dark current " << darkCurrent << " A"
<< "Position in wafer " << waferPos
<< "Location " << location
<< std::endl;
const DbApdData data = {true, breakthroughVoltage, gain100Voltage, darkCurrent, waferPos, location };
return data;
}
catch ( std::exception& e ) {
std::cerr << e.what() << std::endl;
const DbApdData data = {
false,
std::numeric_limits< double >::quiet_NaN(),
std::numeric_limits< double >::quiet_NaN(),
std::numeric_limits< double >::quiet_NaN(),
"",
""
};
return data;
}
}
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProductionDatabase.cxx
\ No newline at end of file
#pragma once
#include <QtCore/QObject>
#include <QtCore/QEventLoop>
#include <string>
class QNetworkAccessManager;
namespace proddb {
struct DbApdData {
bool foundApd;
double BreakthroughVoltage;
double Gain100Voltage;
double DarkCurrent;
std::string wafer_position;
std::string location;
};
class ProductionDatabase : public QObject {
private:
QNetworkAccessManager* _netman;
QEventLoop _waitForNetwork;
const QString _apdDetailsApiUrl;
bool _debug;
void checkDebugMode();
public:
ProductionDatabase ();
~ProductionDatabase();
ProductionDatabase ( const ProductionDatabase& other ) = delete;
ProductionDatabase ( ProductionDatabase&& other ) = delete;
ProductionDatabase& operator= ( const ProductionDatabase& other ) = delete;
ProductionDatabase& operator= ( ProductionDatabase&& other ) = delete;
DbApdData queryManufacturerApdData(const std::string& serial);
};
}
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProductionDatabase.h
\ No newline at end of file
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProductionDatabaseApdStorage.cxx
\ No newline at end of file
/home/tau/jreher/git/ProtoSoft/DAQ/ApdCurves/ProductionDatabaseApdStorage.h
\ No newline at end of file
#include <vector>
#include <iostream>
#include <QtCore/QString>
#include <QtXml/QXmlStreamWriter>
int main() {
std::vector<QString> apds;
apds.push_back(QString::fromUtf8("1234567890"));
apds.push_back(QString::fromUtf8("4567890123"));
apds.push_back(QString::fromUtf8("7890123456"));
int batch = 1;
QString buffer;
QXmlStreamWriter xml ( &buffer );
xml.setAutoFormatting ( true );
xml.writeStartDocument ( QString::fromUtf8 ( "1.0" ) );
xml.writeStartElement ( QString::fromUtf8 ( "productiondb" ) );
xml.writeTextElement ( QString::fromUtf8 ( "batch_type" ), QString::fromUtf8 ( "after irradiation" ) );
xml.writeStartElement ( QString::fromUtf8 ( "elements" ) );
int j = 1;
for ( auto i = apds.begin(); i != apds.end(); i++, j++ ) {
xml.writeStartElement ( QString::fromUtf8 ( "apd" ) );
xml.writeTextElement ( QString::fromUtf8 ( "serial" ), *i );
xml.writeTextElement ( QString::fromUtf8 ( "batch_number" ), QString::number ( batch, 10 ) );
xml.writeTextElement ( QString::fromUtf8 ( "position" ), QString::number( j, 10 ) );
xml.writeEndElement();
}
xml.writeEndDocument(); // This closes all open tags automatically.
std::cerr << buffer.toStdString() << std::endl;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment