00001 #include "qsenormalizer.h"
00002 #include "qsedataset.h"
00003 #include "qsescan.h"
00004
00005 QseNormalizer::QseNormalizer
00006 (QseDataSet* inData, QseDataSet* outData, const QString& name, QObject* parent)
00007 : QseEXAFSOperator(inData, outData, name, parent),
00008 m_ScanPattern(this, "scanpattern",NULL),
00009 m_MinScanRowCount(this, "minscanrowcount", NULL),
00010 m_MaxScanRowCount(this, "maxscanrowcount", NULL),
00011 m_InputEnergyUnits(this, QStringList()<<"eV"<<"keV",
00012 "inputenergyunits", NULL),
00013 m_OutputEnergyUnits(this, QStringList()<<"eV"<<"keV",
00014 "outputenergyunits", NULL)
00015 {
00016 m_InputEnergyUnits.setValue(1);
00017 m_OutputEnergyUnits.setValue(1);
00018 }
00019
00020 void QseNormalizer::exec()
00021 {
00022 m_OutputData -> clear();
00023
00024 int ns = m_InputData -> scanCount();
00025
00026 for (int s = 0; s < ns; s++) {
00027 if (matchesScan(s)) {
00028 QseScan *osc = m_OutputData -> appendScan();
00029
00030 normalizeScan(s, osc);
00031 }
00032 }
00033
00034 m_OutputData -> emitLoadCompleted();
00035 }
00036
00037 bool QseNormalizer::matchesScan(int n)
00038 {
00039 QseScan* s = m_InputData->scan(n);
00040
00041 if (s) {
00042 QseScanRole r = UnspecifiedScanRole;
00043
00044 if (m_ScanExceptions.contains(s)) {
00045 r = m_ScanExceptions[s];
00046 }
00047
00048 bool ok1, ok2;
00049
00050 double minVal = m_MinScanRowCount.toDouble(&ok1);
00051 double maxVal = m_MaxScanRowCount.toDouble(&ok2);
00052
00053 if (ok1 || ok2) {
00054 int nrows = s->maxRowCount();
00055
00056 if (ok1 && (nrows < minVal)) {
00057 return FALSE;
00058 }
00059
00060 if (ok2 && (nrows > maxVal)) {
00061 return FALSE;
00062 }
00063 }
00064
00065 if (r == UnspecifiedScanRole) {
00066 return m_ScanPattern.toRegExp().exactMatch(s->scanCommand());
00067 } else {
00068 return r == ScanUsedRole;
00069 }
00070 } else {
00071 return false;
00072 }
00073 }
00074
00075 void QseNormalizer::normalizeScan(int n, QseScan* osc)
00076 {
00077 QseScan *sc = m_InputData->scan(n);
00078
00079 if (sc) {
00080 int nc = sc -> columnCount();
00081 int energycol = -1;
00082
00083 for (int c = 0; c < nc; c++) {
00084 QseColumn *col = sc -> column(c);
00085
00086 if (matchesEnergyColumn(col)) {
00087 energycol = c;
00088 }
00089 }
00090
00091 if (energycol < 0) {
00092 emit message(QString("No energy column found for scan %1").arg(n));
00093 } else {
00094 osc -> mergeHeaders(sc->header());
00095 osc -> setScanNumber(sc->scanNumber());
00096
00097 QseColumn *energy = osc -> appendColumn("Energy", sc -> column(energycol));
00098 QseColumn *normal = osc -> appendColumn("Norm");
00099 QseColumn *detect = osc -> appendColumn("Detector");
00100 QseColumn *seconds = osc -> appendColumn("Seconds");
00101
00102 energy -> multiplication(energyScalingRatio());
00103
00104 int nnorm = 0, ndet = 0, nsecs = 0;
00105
00106 for (int c = 0; c < nc; c++) {
00107 QseColumn *col = sc -> column(c);
00108
00109 if (matchesNormalizationColumn(col)) {
00110 nnorm += 1;
00111 normal -> addition(col);
00112 } else if (matchesDetectorColumn(col)) {
00113 ndet += 1;
00114 detect -> addition(col);
00115 } else if (matchesSecondsColumn(col)) {
00116 nsecs += 1;
00117 seconds -> addition(col);
00118 }
00119 }
00120
00121 if (nnorm > 0) {
00122 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00123
00124 ratio -> division(normal);
00125
00126 emit message(QString("Scan %1 had %2 detector columns, was normalized by %3 ion chambers").arg(n).arg(ndet).arg(nnorm));
00127 } else if (nsecs > 0) {
00128 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00129
00130 ratio -> division(seconds);
00131 emit message(QString("Scan %1 had %2 detector columns, was normalized by counting time").arg(n).arg(ndet));
00132 } else {
00133 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00134
00135 emit message(QString("Scan %1 had %2 detector columns, no normalization performed").arg(n).arg(ndet));
00136 }
00137 }
00138 }
00139 }
00140
00141 double QseNormalizer::energyScalingRatio()
00142 {
00143 int inp = m_InputEnergyUnits.toInt();
00144 int otp = m_OutputEnergyUnits.toInt();
00145
00146 if (inp == otp) {
00147 return 1.0;
00148 } else if (inp == 0 && otp == 1) {
00149 return 0.001;
00150 } else if (inp == 1 && otp == 0) {
00151 return 1000.0;
00152 } else {
00153 return 1;
00154 }
00155 }
00156