00001 #include "qseaverager.h"
00002 #include "qseaveragerrole.h"
00003 #include "qsedataset.h"
00004
00005 #include "qsescan.h"
00006 #include "qsecolumn.h"
00007
00008 QseAverager::QseAverager(QObject *parent)
00009 : QObject(parent)
00010 {}
00011
00012 QseAverager::~QseAverager()
00013 {}
00014
00015 void QseAverager::exec(QseDataSet *inFile,
00016 QseAveragerRole *role,
00017 QseDataSet *outFile)
00018 {
00019 outFile -> clear();
00020
00021 int ns = inFile -> scanCount();
00022
00023 for (int s = 0; s < ns; s++) {
00024 QseScan *sc = inFile -> scan(s);
00025
00026 if (role -> matchesScan(sc)) {
00027 QseScan *osc = outFile -> appendScan();
00028
00029 normalizeScan(inFile, role, osc, s);
00030 }
00031 }
00032
00033 outFile -> emitLoadCompleted();
00034 }
00035
00036
00040 void QseAverager::normalizeScan(QseDataSet *inFile,
00041 QseAveragerRole *role,
00042 QseScan *osc,
00043 int n)
00044 {
00045 QseScan *sc = inFile->scan(n);
00046
00047 if (sc) {
00048 int nc = sc -> columnCount();
00049 int energycol = -1;
00050
00051 for (int c = 0; c < nc; c++) {
00052 QseColumn *col = sc -> column(c);
00053
00054 if (role -> matchesEnergyColumn(col)) {
00055 energycol = c;
00056 }
00057 }
00058
00059 if (energycol < 0) {
00060 emit message(QString("No energy column found for scan %1").arg(n));
00061 } else {
00062 mergeHeaders(osc, sc);
00063
00064 osc -> setScanNumber(sc->scanNumber());
00065
00066 QseColumn *energy = osc -> appendColumn("Energy", sc -> column(energycol));
00067 QseColumn *normal = osc -> appendColumn("Norm");
00068 QseColumn *detect = osc -> appendColumn("Detector");
00069 QseColumn *seconds = osc -> appendColumn("Seconds");
00070
00071 energy -> multiplication(role->energyScalingRatio());
00072
00073 int nnorm = 0, ndet = 0, nsecs = 0;
00074
00075 for (int c = 0; c < nc; c++) {
00076 QseColumn *col = sc -> column(c);
00077
00078 if (role -> matchesNormalizationColumn(col)) {
00079 nnorm += 1;
00080 normal -> addition(col);
00081 } else if (role -> matchesDetectorColumn(col)) {
00082 ndet += 1;
00083 detect -> addition(col);
00084 } else if (role -> matchesSecondsColumn(col)) {
00085 nsecs += 1;
00086 seconds -> addition(col);
00087 }
00088 }
00089
00090 if (nnorm > 0) {
00091 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00092
00093 ratio -> division(normal);
00094
00095 emit message(QString("Scan %1 had %2 detector columns, was normalized by %3 ion chambers").arg(n).arg(ndet).arg(nnorm));
00096 } else if (nsecs > 0) {
00097 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00098
00099 ratio -> division(seconds);
00100 emit message(QString("Scan %1 had %2 detector columns, was normalized by counting time").arg(n).arg(ndet));
00101 } else {
00102 QseColumn *ratio = osc -> appendColumn("Ratio", detect);
00103
00104 emit message(QString("Scan %1 had %2 detector columns, no normalization performed").arg(n).arg(ndet));
00105 }
00106 }
00107 }
00108 }
00109
00110 bool QseAverager::addScans(QseScan* s1, const QseScan* s2)
00111 {
00112 if (s1 && s2) {
00113 int nc1 = s1->columnCount();
00114 int nc2 = s2->columnCount();
00115
00116 if (nc1 == 0) {
00117 for (int c = 0; c < nc2; c++) {
00118 QseColumn *c2 = s2->column(c);
00119 QseColumn *c1 = s1->appendColumn(c2->name(), c2);
00120 }
00121
00122 mergeHeaders(s1, s2);
00123
00124 emit message(QString("Started new average with scan %1").arg(s1->scanCommand()));
00125
00126 return true;
00127 } else {
00128 if (nc1 != nc2) {
00129 emit message(QString("Scans have different numbers of columns (%1,%2)").arg(nc1).arg(nc2));
00130 return false;
00131 }
00132
00133 for (int c = 0; c < nc1; c++) {
00134 QseColumn *c1 = s1->column(c);
00135 QseColumn *c2 = s2->column(c);
00136
00137 if (c1 && c2) {
00138 int nr1 = c1->rowCount();
00139 int nr2 = c2->rowCount();
00140
00141 if (nr1 != nr2) {
00142 emit message(QString("Scan columns have differing numbers of points"));
00143 return false;
00144 }
00145 } else {
00146 emit message(QString("Scan column missing in one or other scan"));
00147 return false;
00148 }
00149 }
00150
00151 for (int c = 0; c < nc1; c++) {
00152 QseColumn *c1 = s1->column(c);
00153 QseColumn *c2 = s2->column(c);
00154
00155 if (c1 && c2) {
00156 c1 -> addition(c2);
00157 }
00158 }
00159
00160 mergeHeaders(s1, s2);
00161
00162 emit message(QString("Scan %1 added to scan %2").arg(s2->scanCommand()).arg(s1->scanCommand()));
00163
00164 return true;
00165 }
00166 } else {
00167 emit message(QString("Scan was missing"));
00168 return false;
00169 }
00170 }
00171
00172 bool QseAverager::divideScan(QseScan* s, double v)
00173 {
00174 if (s) {
00175 int nc = s->columnCount();
00176
00177 for (int c = 0; c < nc; c++) {
00178 QseColumn *col = s->column(c);
00179
00180 if (col) {
00181 col->division(v);
00182 }
00183 }
00184
00185 return true;
00186 } else {
00187 return false;
00188 }
00189 }
00190
00191 void QseAverager::mergeHeaders(QseScan *s1, const QseScan *s2)
00192 {
00193 if (s1 && s2) {
00194
00195 s1->setName(s2->name());
00196 s1->mergeHeaders(s2->header());
00197 s1->setScanDateTime(QDateTime::currentDateTime());
00198 }
00199 }