void MemSpectrum::flatten(Spectrum * spec, const Rotation & rot) { assert( spec ); assert( spec->getDimCount() == rot.size() ); assert( rot.size() > 2 ); const int cx = spec->getScale( rot[ DimX ] ).getSampleCount(); const int cy = spec->getScale( rot[ DimY ] ).getSampleCount(); int x,y; Rotation cut( rot.size() - 2 ); Dimension d; for( d = 0; d < cut.size(); d++ ) cut[ d ] = rot[ d + 2 ]; Root::Cube cube( rot.size() ); int c; for( d = DimZ; d < rot.size(); d++ ) { c = spec->getScale( rot[ d ] ).getSampleCount(); cube[ rot[ d ] ].first = 0; cube[ rot[ d ] ].second = c - 1; } Buffer buf; for( x = 0; x < cx; x++ ) { cube[ rot[ DimX ] ].first = cube[ rot[ DimX ] ].second = x; for( y = 0; y < cy; y++ ) { cube[ rot[ DimY ] ].first = cube[ rot[ DimY ] ].second = y; spec->fillBuffer( buf, cut, cube ); d_buf.setAt( x, y, buf.calcMean() ); } } }
inline void peakToView2( const T& peak, T& view, const Rotation& r, int dim, const PeakPos& o ) { for( int i = 0; i < r.size(); i++ ) if( r[ i ] < dim ) view[ i ] = peak[ r[ i ] ]; else view[ i ] = o[ r[ i ] ]; }
Rotation Spectrum::getTypeMapping(bool inverted) const { if( inverted ) { Rotation rot; rot.assign( getType()->getDimCount(), DimUndefined ); for( int d = 0; d < rot.size(); d++ ) rot[mapToType( d )] = d; return rot; }else { Rotation rot( getDimCount() ); for( int d = 0; d < rot.size(); d++ ) rot[d] = mapToType( d ); return rot; } }
bool RotateDlg::rotate(Rotation & map) { Dimension dim = map.size(); assert( dim == int(d_labels.size()) ); d_buttons.resize( Extension( dim, dim ) ); const int ncol = 2; const int nrow = (d_editAtomType)?3:2; d_cbs.assign( dim, 0 ); QVBoxLayout* top = new QVBoxLayout(this); top->setMargin( 10 ); QGridLayout* contents = new QGridLayout(); QHBoxLayout* buttons = new QHBoxLayout(); QLabel* l = new QLabel( d_colLabel.data(), this ); l->setAlignment( Qt::AlignCenter | Qt::AlignVCenter ); l->setFrameStyle( QFrame::Panel ); l->setFrameShadow( QFrame::Sunken ); contents->addWidget( l, 0, 2, 1, dim + 1 - 2 + 1 ); l = new QLabel( d_rowLabel.data(), this ); l->setAlignment( Qt::AlignCenter | Qt::AlignVCenter ); l->setFrameStyle( QFrame::Panel ); l->setFrameShadow( QFrame::Sunken ); contents->addWidget( l, nrow, 0, dim, 1 ); Dimension row; for( row = 0; row < dim; row++ ) { QString str; // Set row headers if( !d_labels[ row ].first.isEmpty() ) str.sprintf( "Dim. %s: %s", (d_dimLetter)?getDimLetter(row):getDimSymbol(row), d_labels[ row ].first.data() ); else str.sprintf( "Dim. %s", (d_dimLetter)?getDimLetter(row):getDimSymbol(row) ); l = new QLabel( str, this ); l->setAlignment( Qt::AlignCenter | Qt::AlignVCenter ); l->setFrameStyle( QFrame::Panel ); l->setFrameShadow( QFrame::Sunken ); contents->addWidget( l, 1, row + ncol ); // Set column headers if( !d_labels[ row ].second.isEmpty() ) str.sprintf( "Dim. %s: %s", (d_dimLetter)?getDimLetter(row):getDimSymbol(row), d_labels[ row ].second.data() ); else str.sprintf( "Dim. %s", (d_dimLetter)?getDimLetter(row):getDimSymbol(row) ); l = new QLabel( str, this ); l->setAlignment( Qt::AlignLeft | Qt::AlignVCenter ); l->setFrameStyle( QFrame::Panel ); l->setFrameShadow( QFrame::Sunken ); contents->addWidget( l, row + nrow, 1 ); if( d_editAtomType ) { d_cbs[ row ] = new QComboBox( this ); for( int i = AtomType::None; i <= AtomType::Lr; i++ ) d_cbs[ row ]->addItem( AtomType::s_labels[ i ] ); d_cbs[ row ]->setCurrentIndex( d_clr[ row ].getIsoType() ); contents->addWidget( d_cbs[ row ], nrow - 1, row + ncol ); } for( Dimension col = 0; col < dim; col++ ) { QRadioButton* b = new QRadioButton( this ); b->setAutoExclusive( false ); //b->setToggleButton( true ); contents->addWidget( b, row + nrow, col + ncol, Qt::AlignHCenter ); d_buttons.setAt( row, col, b ); connect( b, SIGNAL( toggled(bool) ), this, SLOT( toggled(bool) ) ); } } // Toggle erst zuletzt, da vorher noch nicht alle Buttons existieren. for( row = 0; row < dim; row++ ) for( Dimension col = 0; col < dim; col++ ) { if( map[ row ] == col ) d_buttons.getAt( row, col )->setChecked( true ); } QPushButton* ok = new QPushButton( "&OK", this ); connect( ok, SIGNAL( clicked() ), SLOT( accept() ) ); buttons->addWidget( ok ); ok->setDefault( true ); QPushButton* cancel = new QPushButton( "&Cancel", this ); connect( cancel, SIGNAL( clicked() ), SLOT( reject() ) ); buttons->addWidget( cancel ); top->addLayout( contents ); top->addLayout( buttons ); while( true ) { if( exec() == QDialog::Accepted ) { Rotation map2 = map; bool clrOk = true; for( int row = 0; row < dim; row++ ) { for( int col = 0; col < dim; col++ ) { if( d_buttons.getAt( row, col )->isChecked() ) { map2[ row ] = col; } } if( d_editAtomType ) { d_clr[ row ] = AtomType::Isotope( d_cbs[ row ]->currentIndex() ); if( d_clr[ row ].isNone() ) clrOk = false; } } if( !map2.isValid() ) { QMessageBox::critical( this, "Rotate dimensions", "Dimension assignments have to be unique!" ); }else if( !clrOk ) { QMessageBox::critical( this, "Rotate dimensions", "Atom types must not be empty!" ); }else { map = map2; return true; } }else return false; } }
void MemSpectrum::fillBuffer(Buffer & buffer, const Rotation & dims, const Root::Cube & cube, const Root::Point& ns) const { Dimension d; const Dimension dimCount = cube.size(); const Dimension tdimCount = dims.size(); if( tdimCount > dimCount ) throw Root::Exception( "target dimension out of range" ); //* Bringe den Buffer auf die nötige Grösse, um Cube darin zu speichern. Setze Skalenausschnitt. { ScaleVector sv( tdimCount ); for( d = 0; d < tdimCount; d++ ) sv[ d ] = Scale( d_buf.getScale( dims[ d ] ).getFreq( cube[ dims[ d ] ].first ), d_buf.getScale( dims[ d ] ).getFreq( cube[ dims[ d ] ].second ), // TODO: +1? d_buf.getScale( dims[ d ] ).getColor(), d_buf.getScale( dims[ d ] ).getFolding(), cube.getCellCount( dims[ d ] ) ); buffer.resize( sv ); } //- //* Überführe Cube in normalisierte roi Cube roi( dimCount ); // Bereinigt mit first < second for( d = 0; d < dimCount; d++ ) { roi[ d ].first = Math::min( cube[ d ].first, cube[ d ].second ); roi[ d ].second = Math::max( cube[ d ].first, cube[ d ].second ); if( roi[ d ].first < 0 || roi[ d ].second >= d_buf.getScale( d ).getSampleCount() ) throw Root::Exception( "region of interest out of spectrum" ); } //- /* const */ Point flip; // Target-Achse verläuft parallel oder antiparallel /* const */ Point flipOff; // Arithmetischer Trick um Achse zu drehen for( d = 0; d < tdimCount; d++ ) { if( cube[ dims[ d ] ].first > cube[ dims[ d ] ].second ) { flip.push_back( -1 ); flipOff.push_back( buffer.getExtension()[ d ] - 1 ); }else { flip.push_back( 1 ); flipOff.push_back( 0 ); } } // Ab hier flip und flipOff const const Point roiFirst = roi.getFirst(); const Point roiSecond = roi.getSecond(); Point currentSamp; Index pointIndex; Index targetIndex; Point off; off.assign( tdimCount, 0 ); Point f1; // Faktor für Indexberechnung: // f1[ 0 ] * f1[ 1 ] * at( 2 ) + at( 1 ) * f1[ 0 ] + at( 0 ) f1.assign( dimCount, 1 ); for( d = 1; d < dimCount; d++ ) f1[ d ] = d_buf.getExtension()[ d - 1 ] * f1[ d - 1 ]; Point f2; f2.assign( tdimCount, 1 ); for( d = 1; d < tdimCount; d++ ) f2[ d ] = buffer.getExtension()[ d - 1 ] * f2[ d - 1 ]; for( d = 0; d < tdimCount; d++ ) off[ d ] = -roi[ dims[ d ] ].first; currentSamp = roiFirst; do { //* Berechne den seriellen Index von currentSamp relativ zu currentTile. pointIndex = 0; // Optimierung für currentSamp.getIndex( d_tileSize ): for( d = 0; d < dimCount; d++ ) pointIndex += currentSamp[ d ] * f1[ d ]; //- targetIndex = 0; for( d = 0; d < tdimCount; d++ ) targetIndex += f2[ d ] * ( flip[ d ] * ( off[ d ] + currentSamp[ dims[ d ] ] ) + flipOff[ d ] ); // flip und flipOff drehen die Achse falls verlangt buffer.setAt( targetIndex, d_buf.getAt( pointIndex ) ); // Increment Counter }while( increment( currentSamp, roiFirst, roiSecond ) ); }
inline void viewToPeak( const T& view, T& peak, const Rotation& r ) { for( int i = 0; i < r.size(); i++ ) peak[ r[ i ] ] = view[ i ]; }
inline void peakToView( const T& peak, T& view, const Rotation& r ) { for( int i = 0; i < r.size(); i++ ) view[ i ] = peak[ r[ i ] ]; }